大佬教程收集整理的这篇文章主要介绍了android – 尝试通过ACTION_OPEN_DOCUMENT forPersistableUriPermission()无法自定义DocumentsProvider,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个DocumentsProvider,我在@L_427_4@manufest.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>
我的应用程序具有MANAGE_DOCUMENTS权限集
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
(显然这不是必要的,但添加/删除它也无关紧要).
当我打开ACTION_OPEN_DOCUMENT选择器UI时,我可以看到我的提供者
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);
然后,在我的提供者那里选择一个文件之后,在我的应用程序的onActivityResult()方法中,我可以通过我从intent.getData()获得的Uri成功打开我的DocumentsProvider提供的文件.
但是,尝试保持读取或写入权限
getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_READ_URI_PERMISSION);
要么
getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
总是失败,例如
No permission grant found for UID 10210 and Uri content://com.cgogolin.myapp.MyContentProvider/document/tshjhczf.pdf
如果我从选择器UI中的google驱动器或下载提供程序中选择一个文件,以这种方式获取权限.所以我认为问题出在我的提供者身上.
尽管我指定了android:grantUriPermissions =“true”,为什么没有创建权限授予?
我怎样才能说服Android为我创建这样的权限授予?
毕竟我不认为我可以自己做,因为我不知道打开选择器UI的过程的UID,或者至少不知道我知道如何.
我之前的回答并不好.出于安全原因,您可以使用“android.permission.MANAGE_DOCUMENTS”.
只有系统UI选择器才能列出您的文档.
但是,在打开文档的应用程序的清单中,您不需要此权限.
实际上,您不应该获得此权限,因为这是系统权限.
我刚刚测试了它并调用了takePersistableUriPermission表单onActivityResult成功了.
我使用了DocumentProvider和模拟数据(一个根,3个txt文档).
如果它仍然不适合您,您的文档提供程序可能会有一些问题.
EDIT2:
示例代码
package com.example.test; import android.database.cursor; import android.database.Matrixcursor; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; import android.provider.DocumentsProvider; import java.io.FileNotFoundException; public class MyContentProvider extends DocumentsProvider { private final static String[] rootcolumns = new String[]{ "_id","root_id","title","icon" }; private final static String[] doccolumns = new String[]{ "_id","document_id","_display_name","mime_type","icon" }; Matrixcursor matrixcursor; Matrixcursor matrixRootcursor; @Override public Boolean onCreate() { matrixRootcursor = new Matrixcursor(rootcolumns); matrixRootcursor.addRow(new Object[]{1,1,"TEST",R.mipmap.ic_launcher}); matrixcursor = new Matrixcursor(doccolumns); matrixcursor.addRow(new Object[]{1,"a.txt","text/plain",R.mipmap.ic_launcher}); matrixcursor.addRow(new Object[]{2,2,"b.txt",R.mipmap.ic_launcher}); matrixcursor.addRow(new Object[]{3,3,"c.txt",R.mipmap.ic_launcher}); return true; } @Override public cursor queryRoots(String[] projection) throws FileNotFoundException { return matrixRootcursor; } @Override public cursor queryDocument(String documentId,String[] projection) throws FileNotFoundException { return matrixcursor; } @Override public cursor queryChildDocuments(String parentDocumentId,String[] projection,String sortOrder) throws FileNotFoundException { return matrixcursor; } @Override public ParcelFileDescriptor openDocument(String documentId,String mode,CancellationSignal signal) throws FileNotFoundException { int id; try { id = Integer.valueOf(documentId); } catch (@R_674_10793@erFormatException E) { throw new FileNotFoundException("Incorrect document ID " + documentId); } String filename = "/sdcard/"; switch (id) { case 1: filename += "a.txt"; break; case 2: filename += "b.txt"; break; case 3: filename += "c.txt"; break; default: throw new FileNotFoundException("UnkNown document ID " + documentId); } return ParcelFileDescriptor.open(new File(fileName),ParcelFileDescriptor.MODE_READ_WRITE); } }
注意:
您可以使用DocumentsContract.Document和DocumentsContract.Root中的常量.
我不确定是否需要“_id”.
EDIT3:
更新了示例代码以从/ sdcard打开文档.
添加了读/写外部存储权限.
AndroidManifest.xml中
<?xml version="1.0" encoding="utf-8"?> <manifest package="com.example.test" xmlns:android="http://scheR_489_11845@as.android.com/apk/res/android"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:icon="@mipmap/ic_launcher" android:label="@String/app_name"> <provider android:name="com.example.test.MyContentProvider" android:authorities="com.example.test.document" android:enabled="true" android:exported="@bool/atleastKitKat" android:grantUriPermissions="true" android:permission="android.permission.MANAGE_DOCUMENTS"> <intent-filter> <action android:name="android.content.action.DOCUMENTS_PROVIDER"/> </intent-filter> </provider> </application> </manifest>
客户端应用
具有空活动的新项目,未添加任何权限.
打开文件
Intent openDocumenTintent = new Intent(Intent.ACTION_OPEN_DOCUMENT); openDocumenTintent.addCategory(Intent.CATEGORY_OPENABLE); openDocumenTintent.setType("text/plain"); openDocumenTintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); startActivityForResult(openDocumenTintent,1);
onActivityResult
@Override protected void onActivityResult(int requestCode,int resultCode,Intent data) { switch (requestCodE) { case 1: // TODO: Use constant if (resultCode == RESULT_OK) { if (data == null) return; // TODO: Show error Uri uri = data.getData(); if (uri == null) return; // TODO: Show error getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_READ_URI_PERMISSION); InputStream is = null; try { is = getContentResolver().openInputStream(uri); // Just for quick sample (I kNow what I will read) byte[] buffer = new byte[1024]; int read = is.read(buffer); String text = new String(buffer,read); ((TextView) findViewById(R.id.text)).setText(text); } catch (IOException E) { e.printStackTrace(); } finally { if (is != null) try { is.close(); } catch (IOException E) { e.printStackTrace(); } } } break; } }
以上是大佬教程为你收集整理的android – 尝试通过ACTION_OPEN_DOCUMENT forPersistableUriPermission()无法自定义DocumentsProvider全部内容,希望文章能够帮你解决android – 尝试通过ACTION_OPEN_DOCUMENT forPersistableUriPermission()无法自定义DocumentsProvider所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。