我想使用作为Storage Access Framework一部分提供的android系统对话框来打开文件.我这样做
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf");
startActivityForResult(intent, EDIT_REQUEST);
Run Code Online (Sandbox Code Playgroud)
然后处理返回的URI onActivityResult().
问题是,在结果菜单中,我得到的内容提供商远远少于我的预期.仅限Google云端硬盘和下载(请参阅下面的左侧屏幕截图).其他人,如Dropbox,Solid Explorer,......都没有显示.
我怀疑原因是这些应用程序根本没有设置必要的intent过滤器显示在此列表中.
但是,其他应用程序(例如Kaiten Mail或Chrome)以某种方式设法显示系统对话框,其中包含完全实现的内容提供程序,位于列表顶部,然后其他应用程序(如Dropbox和Solid Explorer)在下方用细条分隔(请参阅正确的屏幕截图).
我怎么能得到这种行为?

我正在尝试编写一个自定义规则DocumentsProvider,以允许其他应用程序对其提供的Uris拥有持久权限
我有一个DocumentsProvider我声明AndroidManufest.xml如下
<provider
android:name="com.cgogolin.myapp.MyContentProvider"
android:authorities="com.cgogolin.myapp.MyContentProvider"
android:grantUriPermissions="true"
android:exported="true"
android:permission="android.permission.MANAGE_DOCUMENTS"
android:enabled="@bool/atLeastKitKat">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
</intent-filter>
</provider>
Run Code Online (Sandbox Code Playgroud)
并且我的应用具有MANAGE_DOCUMENTS权限设置
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
Run Code Online (Sandbox Code Playgroud)
(显然,这不是必需的,但是添加/删除它也没有关系)。然后,当我打开ACTION_OPEN_DOCUMENT选择器用户界面时,可以看到我的提供者
Intent openDocumentIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
openDocumentIntent.addCategory(Intent.CATEGORY_OPENABLE);
openDocumentIntent.setType("application/pdf");
openDocumentIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
startActivityForResult(openDocumentIntent, EDIT_REQUEST);
Run Code Online (Sandbox Code Playgroud)
然后,从我的提供商那里选择一个文件之后,在onActivityResult()我的App 的方法中,我可以通过我DocumentsProvider从Uri那里获取,成功打开我提供的文件intent.getData()。
但是,尝试通过以下方式持久保留读或写权限:
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
Run Code Online (Sandbox Code Playgroud)
要么
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Run Code Online (Sandbox Code Playgroud)
总是失败,并出现类似的异常
No permission grant found for UID 10210 and Uri content://com.cgogolin.myapp.MyContentProvider/document/tshjhczf.pdf
Run Code Online (Sandbox Code Playgroud)
如果我从Google驱动器中选取文件,或者在选择器UI中选择下载提供程序,则以这种方式获得许可就可以了。所以我认为问题出在我的提供者中。
尽管我进行了指定,为什么没有创建许可授予android:grantUriPermissions="true"?
如何说服Android为我创建这样的权限授予?
毕竟我不认为自己可以做,因为我不知道UID打开选择器UI的过程,或者至少我不知道该怎么做。
permissions android android-contentprovider storage-access-framework