Android 7 Nougat:用于sdcard文件的getUriForFile上的FileProvider IllegalArgumentException

时间:2018-03-13 15:13:26

标签: android android-intent android-sdcard android-7.0-nougat android-fileprovider

我的应用程序提供了在用户之间共享文件的功能。对于图像文件,有一个自定义图库,通过长按,它可以通过ACTION_VIEW意图在本地图像查看器中打开图像。这是代码:

public static boolean openFile(Context context, File file)
{
    MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
    String extension = FilenameUtils.getExtension(file.getPath());
    String mimeType = mimeTypeMap.getMimeTypeFromExtension(extension.toLowerCase());

    Intent openFile = new Intent(Intent.ACTION_VIEW);
    openFile.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    |Intent.FLAG_ACTIVITY_NO_HISTORY
                    |Intent.FLAG_GRANT_READ_URI_PERMISSION);

    Uri fileUri;
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
    {
        String authority = context.getApplicationContext().getPackageName() + ".provider";
        try {
            fileUri =  FileProvider.getUriForFile(context, authority, file);
        } catch (IllegalArgumentException e) {
            if (Fabric.isInitialized()) Crashlytics.logException(e);
            else e.printStackTrace();
            return false;
        }
    }
    else fileUri = Uri.fromFile(file);

    openFile.setDataAndType(fileUri, mimeType != null ? mimeType : "*/*");

    if (openFile.resolveActivity(context.getPackageManager()) != null)
    {
        context.startActivity(openFile);
        return true;
    }
    return false;
}

一切都适用于API< 24,但在24+我遇到了试图在SD卡上打开图像的问题。例外是:

java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/89F3-1B06/Pictures/DSC_0004.JPG
W/System.err:     at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:719)
W/System.err:     at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:404)

显然,这是因为<external-path name="other" path="."/>不提供文件树中sdcard级别的访问权限。所以我添加了这条路径: <external-path name="external_files" path="../../"/>。这有帮助,但有些事情告诉我,这不是最好的解决方案。

我找到了另一个解决方案,它也有效:

StrictMode.VmPolicy.Builder builder = new   StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
fileUri = Uri.fromFile(file);

但禁用StrictMode限制看起来更糟。所以它不是选项。

关于如何以正确的方式解决这个问题的任何建议?

1 个答案:

答案 0 :(得分:1)

FileProvider无法从可移动SD卡提供文件。

仅限getFilesDir()getExternalFilesDir()getExternalStorageDirectory()

如果你想从SD卡提供文件,你应该建立自己的文件提供者。