我有一个应用程序,可以从文件管理器打开txt文件,编辑它们并保存对该文件的更改。
事情是,当 uri scheme 是file://
时,一切正常。但如果 uri scheme 为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()
我在AndroidManifest中的<provider/>
<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>
答案 0 :(得分:0)
首先删除一些代码,然后留下:
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
,具体取决于其他组件需要什么)