我对grantUriPermission函数有点困惑。我想用它通过FileProvider授予对另一个应用程序的文件访问权限。由于 FileProvider 必须是本地的(非导出的)有充分的理由,我必须授予其他应用程序临时读/写权限。文档说:
通常你应该使用 Intent.FLAG_GRANT_READ_URI_PERMISSION 或 Intent.FLAG_GRANT_WRITE_URI_PERMISSION 来启动一个活动,而不是直接使用这个函数。如果直接使用此函数,则应确保在不再允许目标访问它时调用 revokeUriPermission(Uri, int)。
很公平,因为我不需要打开活动,也不需要显式启动服务(其他应用程序会在时机成熟时要求提供该文件),但我可以简单地接受:
Uri newFileUri = FileProvider.getUriForFile(this, AUTHORITY, file);
grantUriPermission(OTHER_APP_PACKAGE_NAME, newFileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
令我惊讶的是,我仍然收到安全异常:
java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{42ee0b98 5878:example.com.myapplication3/u0a82} (pid=5878, uid=10082) that is not exported from uid 10081
经过几次实验后,我发现我必须至少通过 Intent 调用另一个应用程序一次:
Intent intent = new Intent();
intent.setClassName(OTHER_APP_PACKAGE_NAME, OTHER_APP_SERVICE_NAME);
startService(intent);
一旦我这样做了,我就可以按预期做所有事情——我可以删除这个意图代码,我什至可以重新安装这两个应用程序,它仍然可以工作(!)。似乎有一个隐藏的要求,即所有者必须至少调用另一个应用程序一次并将其存储在系统中的某个位置。
这是在某处记录的吗?
编辑:首先我想我也必须使用 Intent.FLAG_GRANT_READ_URI_PERMISSION 标志,但这似乎没有必要。