Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了android – 尝试通过ACTION_OPEN_DOCUMENT forPersistableUriPermission()无法自定义DocumentsProvider大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试编写一个自定义DocumentsProvider,允许其他应用程序对其提供的Uris采取持久权限

我有一个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;
    }
}
@H_262_100@

大佬总结

以上是大佬教程为你收集整理的android – 尝试通过ACTION_OPEN_DOCUMENT forPersistableUriPermission()无法自定义DocumentsProvider全部内容,希望文章能够帮你解决android – 尝试通过ACTION_OPEN_DOCUMENT forPersistableUriPermission()无法自定义DocumentsProvider所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。