android - 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>
解决方案
首先摆脱一些代码,留下:
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_PERMISSION
到Intent
您用来启动该组件的 (也许FLAG_GRANT_READ_URI_PERMISSION
,取决于其他组件需要什么)
推荐阅读
- java - 在画布中绘制时出现BufferOverflowException 在不同的组件中
- python - Pyspark:字符串列上的多个过滤器
- java - 由于状态发生变化,如何更新我的视图?
- jprofiler - 如何在 JProfiler 中获取从一种方法传递到另一种方法的数据大小?
- javascript - 如何在three.js中的360全景图像中添加div元素或热点?
- azure - 使用 2 个 URL 公开相同的 Azure webapp,一个仅在公司网络内,一个公共
- javascript - 过滤数组并获取过滤数组的计数
- javascript - 单击按钮时如何卸载脚本?
- python - 如何总结熊猫数据框中每个第 x 列和第 x+2 列的列?
- java - ngnix 挂起请求:上游在从上游读取响应标头时未发送有效的 HTTP/1.0 标头