首页 > 解决方案 > grantUriPermissions() 上的 SecurityException

问题描述

我有一个应用程序,可以从文件管理器打开 txt 文件,编辑它们并将更改保存到该文件。

事情是,当uri 方案一切file://正常时。但是,如果uri 方案content://我在尝试grantUriPermissions().

这是我尝试保存文件的方法:

    OutputStream os;
try {
    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
    os = context.getContentResolver().openOutputStream(uri);
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
    writer.write(newText.trim());
    writer.flush();
    writer.close();
    os.close();
    context.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
} catch (IOException e) {
    e.printStackTrace();
}

我得到:

java.lang.SecurityException: Permission Denial: writing com.android.fileexplorer.provider.FileExplorerFileProvider uri content://com.mi.android.globalFileexplorer.myprovider/external_files/txtpad/uu.txt from pid=32456, uid=10208 requires the provider be exported, or grantUriPermission()

<provider/>在 AndroidManifest 中

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

我在 AndroidManifest 的活动标签中有这个

<intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />

            <data android:scheme="content" />
            <data android:scheme="file" />
            <data android:mimeType="text/*" />
        </intent-filter>

标签: androidandroid-fileprovider

解决方案


首先摆脱一些代码,留下:

OutputStream os;
try {
    os = context.getContentResolver().openOutputStream(uri);
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
    writer.write(newText.trim());
    writer.flush();
    writer.close();
    os.close();
} catch (IOException e) {
    e.printStackTrace();
}

我删除的代码与授予其他应用程序Uri. 您没有对其他应用程序做任何事情,revokeUriPermission()特别是可能会破坏您自己的应用程序对内容的访问。

然后,完全卸载并重新安装您的应用程序,看看一切是否开始工作。

如果不是,请确保:

  • 您只能Uri在获得它的活动中使用它(通过getIntent().getData()),或者

  • 如果您将 传递Uri给另一个组件,请添加FLAG_GRANT_WRITE_URI_PERMISSIONIntent您用来启动该组件的 (也许FLAG_GRANT_READ_URI_PERMISSION,取决于其他组件需要什么)


推荐阅读