Android DocumentsProvider 自定义

如果我们希望自己 APP 的数据也能在 documentsui 中打开,那么就需要写一个自己的 Document provider

Document Provider 自定义

自定义 Document Provider 很简单,短短几步就实现了

  1. 要求 API 版本为 19+ ( Android 4.4+ )

  2. 自定义个一个 Document Provider,比如 MsCloudProvider

  3. AndroidManifest.xml 中注册自定义全限定的 Provider

    1. android:name 为类名加包名,比如

      cn.twle.android.storageprovider.MsCloudProvider
      
    2. android:authority包名 + provider 的类型名 ,如

      cn.twle.android.storageprovider.documents
      
    3. ndroid:exported 属性的值为 true

    下面是 Provider 的写法

    <manifest... >
        ...
        <uses-sdk
            android:minSdkVersion="19"
            android:targetSdkVersion="19" />
            ....
            <provider
                android:name="cn.twle.android.storageprovider.MsCloudProvider"
                android:authorities="cn.twle.android.storageprovider.documents"
                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>
        </application>
    </manifest>
    

DocumentsProvider 的子类

我们自定义的 DocumentsProvider 至少要实现以下几个方法,其它的按需实现

  • queryRoots()
  • queryChildDocuments()
  • queryDocument()
  • openDocument()

比如下面可能是我们的 MsCloudProvider 的大致写法

  1. 实现 queryRoots() 方法

    @Override
    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
    
        // Create a cursor with either the requested fields, or the default
        // projection if "projection" is null.
        final MatrixCursor result =
                new MatrixCursor(resolveRootProjection(projection));
    
        // If user is not logged in, return an empty root cursor.  This removes our
        // provider from the list entirely.
        if (!isUserLoggedIn()) {
            return result;
        }
    
        // It's possible to have multiple roots (e.g. for multiple accounts in the
        // same app) -- just add multiple cursor rows.
        // Construct one row for a root called "MyCloud".
        final MatrixCursor.RowBuilder row = result.newRow();
        row.add(Root.COLUMN_ROOT_ID, ROOT);
        row.add(Root.COLUMN_SUMMARY, getContext().getString(R.string.root_summary));
    
        // FLAG_SUPPORTS_CREATE means at least one directory under the root supports
        // creating documents. FLAG_SUPPORTS_RECENTS means your application's most
        // recently used documents will show up in the "Recents" category.
        // FLAG_SUPPORTS_SEARCH allows users to search all documents the application
        // shares.
        row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE |
                Root.FLAG_SUPPORTS_RECENTS |
                Root.FLAG_SUPPORTS_SEARCH);
    
        // COLUMN_TITLE is the root title (e.g. Gallery, Drive).
        row.add(Root.COLUMN_TITLE, getContext().getString(R.string.title));
    
        // This document id cannot change once it's shared.
        row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(mBaseDir));
    
        // The child MIME types are used to filter the roots and only present to the
        //  user roots that contain the desired type somewhere in their file hierarchy.
        row.add(Root.COLUMN_MIME_TYPES, getChildMimeTypes(mBaseDir));
        row.add(Root.COLUMN_AVAILABLE_BYTES, mBaseDir.getFreeSpace());
        row.add(Root.COLUMN_ICON, R.drawable.ic_launcher);
    
        return result;
    }
    
  2. 实现 queryChildDocuments() 方法

    public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
                                  String sortOrder) throws FileNotFoundException {
    
        final MatrixCursor result = new
                MatrixCursor(resolveDocumentProjection(projection));
        final File parent = getFileForDocId(parentDocumentId);
        for (File file : parent.listFiles()) {
            // Adds the file's display name, MIME type, size, and so on.
            includeFile(result, null, file);
        }
        return result;
    }
    
  3. 实现 queryDocument() 方法

    @Override
    public Cursor queryDocument(String documentId, String[] projection) throws
            FileNotFoundException {
    
        // Create a cursor with the requested projection, or the default projection.
        final MatrixCursor result = new
                MatrixCursor(resolveDocumentProjection(projection));
        includeFile(result, documentId, null);
        return result;
    }
    

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.