首页 > 解决方案 > 在 API 24+ 上使用 Uri 通过 Intent 打开文件

问题描述

我有一个应该在设备上打开图像文件的按钮。它在 API 24 下运行良好,但在 API 24 及更高版本上崩溃。我按照 API 24+ 的教程进行操作,但它仍然崩溃,我不知道为什么。

Intent intent = new Intent(Intent.ACTION_VIEW);
if(android.os.Build.VERSION.SDK_INT >=24) {
    fileURI = FileProvider.getUriForFile(context,
        "com.example.android.provider",
        localFile);
    intent.setDataAndType(fileURI, "image/jpeg");
} else {
    intent.setDataAndType(Uri.fromFile(localFile), "image/jpeg");
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);

清单文件:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.android.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths2"/>
</provider>

文件路径2.xml:

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

我没有任何线索。

日志:

11-10 19:59:08.052 21800-21800/com.yannick.mychatapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.yannick.mychatapp, PID: 21800
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
    at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:605)
    at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:579)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:417)
    at com.yannick.mychatapp.ChatRoom$17$1.onClick(ChatRoom.java:936)
    at android.support.design.widget.Snackbar$1.onClick(Snackbar.java:317)
    at android.view.View.performClick(View.java:6597)
    at android.view.View.performClickInternal(View.java:6574)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25885)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

标签: androidfileandroid-intenturi

解决方案


fileURI = FileProvider.getUriForFile(context,
    "com.example.android.provider",
    localFile);

在这里,您使用com.example.android.provider.

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.android.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths2"/>
</provider>

在这里,您使用com.example.android.fileprovider.

这些不一样。它们必须相同。而且,它们需要特定于您的应用程序。使用基于您自己应用程序包名称的内容,并在两个地方使用相同的值。


推荐阅读