Android文件提供者:找不到包含已配置根目录的文件。

6

我创建了一个应用程序,用于创建gpx文件。除了共享功能外,一切都正常运行。 因此,我创建了一个文件提供程序。您可以查看其配置信息如下。该提供程序在我的运行Android 8.0.0的安卓设备上运行良好,但在朋友的华为(6.0)上不起作用。

Fatal Exception: java.lang.IllegalArgumentException
Failed to find configured root that contains /storage/8737-15E4/Android/data/XXX/cache/20171009_171900.gpx

Manifest中的提供者:

<provider
        android:name=".GenericFileProvider"
        android:authorities="com.package.test.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

file_paths.xml:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="external-files" path="/" />
<external-cache-path name="cache-files" path="/" />
</paths>

代码中的使用方法:

File gpxFile = new File(context.getExternalCacheDir(), "20171009_171900.gpx");    
Uri gpxContentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", gpxFile);

        Intent gpxIntent = new Intent(Intent.ACTION_SEND);
        gpxIntent.setType("text/gpx");

        gpxIntent.putExtra(Intent.EXTRA_STREAM, gpxContentUri);

        Intent programChooser = Intent.createChooser(gpxIntent, context.getString(R.string.select_app_to_share));
        programChooser.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

        activityForDialog.startActivity(programChooser);

我希望有人能够帮助我找出导致应用在某些设备上崩溃的错误...

FileProvider 不支持可移动存储作为 <external-cache-dir> 等代替物。我无法解释为什么 FileProvider 显然可以获得 getExternalCacheDir() 的一个值,而你的代码会得到另一个值。在你的代码中 context 到底是什么?这个 Context 是从哪里来的? - CommonsWare
上下文是通过调用Activity activity = Activity.this; Context context = activity.getApplicationContext(); 生成的。我认为这应该可以工作... - Mojo
1
是的 - 实际上,如果您正在使用其他东西,我会建议这样做。我无法解释这些症状。一种解决方法是捕获异常并在Android 6.0及更早版本的设备上改用Uri.forFile() - CommonsWare
正确。这在Android 7.0+上不会起作用,需要更多的工作,但希望您不会在Android 7.0+设备上遇到这个问题。因此,您可以在可能的情况下使用FileProvider,在FileProvider不喜欢设备(无论出于什么原因)的情况下回退到Uri.forFile() - CommonsWare
非常感谢您的快速帮助。我会尝试一下 ;) - Mojo
显示剩余9条评论
1个回答

4

修改您的“代码中的用法:”并替换第二行

Uri gpxContentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", gpxFile);

用以下代码:
Uri gpxContentUri;
try {
    gpxContentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", gpxFile);
} catch (IllegalArgumentException e) {
    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());
    gpxContentUri = Uri.fromFile(gpxFile);
}

注意:这个错误似乎只在我使用的搭载Android 7.0的“华为P8 Lite(PRA-LX1)”上出现,而 Mojo 说它只发生在他朋友的华为手机上(6.0)。我开始认为这只是这些手机的问题,但有一个解决方法也是好的。


什么是 uriList - EpicPandaForce
1
@EpicPandaForce 首先,很棒的名字,其次,感谢你发现了这个问题!uriList 不应该在那里,但是,如果有人感兴趣,我个人使用以下代码: ArrayList<Uri> uriList = new ArrayList<Uri>(); 然后将其发送到一个发送意图 (ACTION_SEND_MULTIPLE)。 我已经纠正了答案,再次感谢! - Jared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接