欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android如何實(shí)現(xiàn)一個DocumentProvider示例詳解

 更新時間:2022年12月25日 16:55:40   作者:storytellerF  
這篇文章主要為大家介紹了Android如何實(shí)現(xiàn)一個DocumentProvider示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

假如你做了一個云盤類的app,或者可以保存用戶導(dǎo)入的配置。用戶在未來肯定需要獲取這些文件,一個辦法是寫一個Activity,向一個文件管理軟件一樣把他們列出來。但是這個有一個問題是用戶必須進(jìn)入app 才能訪問。

現(xiàn)在有一個解決方案是實(shí)現(xiàn)一個DocumentProvider

步驟

DocumentProvider 繼承自Content Provider。

首先在Manifest 中注冊這個Provider

<provider
    android:name=".StorageProvider"
    android:authorities="com.storyteller_f.ping.documents"
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">
    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>

創(chuàng)建這個Provider

class StorageProvider : DocumentsProvider() {
    companion object {
        private val DEFAULT_ROOT_PROJECTION: Array<String> = arrayOf(
            DocumentsContract.Root.COLUMN_ROOT_ID,
            DocumentsContract.Root.COLUMN_MIME_TYPES,
            DocumentsContract.Root.COLUMN_FLAGS,
            DocumentsContract.Root.COLUMN_ICON,
            DocumentsContract.Root.COLUMN_TITLE,
            DocumentsContract.Root.COLUMN_SUMMARY,
            DocumentsContract.Root.COLUMN_DOCUMENT_ID,
            DocumentsContract.Root.COLUMN_AVAILABLE_BYTES
        )
        private val DEFAULT_DOCUMENT_PROJECTION: Array<String> = arrayOf(
            DocumentsContract.Document.COLUMN_DOCUMENT_ID,
            DocumentsContract.Document.COLUMN_MIME_TYPE,
            DocumentsContract.Document.COLUMN_FLAGS,
            DocumentsContract.Document.COLUMN_DISPLAY_NAME,
            DocumentsContract.Document.COLUMN_LAST_MODIFIED,
            DocumentsContract.Document.COLUMN_SIZE
        )
        private const val TAG = "StorageProvider"
    }
    override fun onCreate(): Boolean {
        return true
    }
}

重寫queryRoot

在我們的需求下只有一種情況,訪問的路徑應(yīng)該是/data/data/packagename/,不過如果一個app 支持多用戶,那就應(yīng)該有多個目錄。所以需要一個方法告知文件管理應(yīng)用我們的app 有多少個根。

override fun queryRoots(projection: Array<out String>?): Cursor {
    Log.d(TAG, "queryRoots() called with: projection = $projection")
    val flags = DocumentsContract.Root.FLAG_LOCAL_ONLY or DocumentsContract.Root.FLAG_SUPPORTS_IS_CHILD
    return MatrixCursor(projection ?: DEFAULT_ROOT_PROJECTION).apply {
        newRow().apply {
            add(DocumentsContract.Root.COLUMN_ROOT_ID, DEFAULT_ROOT_ID)
            add(DocumentsContract.Root.COLUMN_MIME_TYPES, DocumentsContract.Document.MIME_TYPE_DIR)
            add(DocumentsContract.Root.COLUMN_FLAGS, flags)
            add(DocumentsContract.Root.COLUMN_ICON, R.drawable.ic_launcher_foreground)
            add(DocumentsContract.Root.COLUMN_TITLE, context?.getString(R.string.app_name))
            add(DocumentsContract.Root.COLUMN_SUMMARY, "your data")
            add(DocumentsContract.Root.COLUMN_DOCUMENT_ID, "/")
        }
    }
}

返回值是Cursor 就像一個數(shù)據(jù)庫連接查詢數(shù)據(jù)時一樣,不過我們沒有操作數(shù)據(jù)庫,返回的數(shù)據(jù)是文件系統(tǒng)。所以我們返回一個MatrixCursor。

返回的數(shù)據(jù)沒有什么真實(shí)數(shù)據(jù),僅僅作為一個入口。

此時打開Android 系統(tǒng)的文件管理,就能看到了

此時點(diǎn)擊的話就會崩潰,因?yàn)檫€沒有重寫queryDocument

重寫queryDocument

/**
 * Return metadata for the single requested document. You should avoid
 * making network requests to keep this request fast.
 *
 * @param documentId the document to return.
 * @param projection list of {@link Document} columns to put into the
 *            cursor. If {@code null} all supported columns should be
 *            included.
 * @throws AuthenticationRequiredException If authentication is required from
 *            the user (such as login credentials), but it is not guaranteed
 *            that the client will handle this properly.
 */
public abstract Cursor queryDocument(String documentId, String[] projection)
        throws FileNotFoundException;        

這個方法才是真正返回數(shù)據(jù)的地方,上面返回root 更像是盤符,這里是返回root 盤符對應(yīng)的根文件夾。數(shù)據(jù)結(jié)構(gòu)是一個樹形結(jié)構(gòu),queryDocument 返回根文件夾,根只有一個,所以返回的數(shù)據(jù)也是只有一個。如果你返回了多個數(shù)據(jù)應(yīng)該也是無效的,系統(tǒng)會忽略掉。

一般我們需要根據(jù)documentId (盤符)返回,不過這里只有一個,就不做區(qū)分了。

override fun queryDocument(documentId: String?, projection: Array<out String>?): Cursor {
    Log.d(TAG, "queryDocument() called with: documentId = $documentId, projection = $projection")
    return MatrixCursor(projection ?: DEFAULT_DOCUMENT_PROJECTION).apply {
        val root = context?.filesDir?.parentFile ?: return@apply
        newRow().apply {
            add(DocumentsContract.Document.COLUMN_DOCUMENT_ID, "/")
            add(DocumentsContract.Document.COLUMN_MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR)
            val flags = 0
            add(DocumentsContract.Document.COLUMN_FLAGS, flags)
            add(DocumentsContract.Document.COLUMN_DISPLAY_NAME, root.name)
            add(DocumentsContract.Document.COLUMN_LAST_MODIFIED, root.lastModified())
            add(DocumentsContract.Document.COLUMN_SIZE, 0)
        }
    }
}

重寫getChildDocument

override fun queryChildDocuments(parentDocumentId: String?, projection: Array<out String>?, sortOrder: String?): Cursor {
    Log.d(TAG, "queryChildDocuments() called with: parentDocumentId = $parentDocumentId, projection = $projection, sortOrder = $sortOrder")
    return MatrixCursor(projection ?: DEFAULT_DOCUMENT_PROJECTION).apply {
        handleChild(parentDocumentId)
    }
}

我們只需要根據(jù)parentDocumentId 來搜索就可以。就像一個遍歷出一個文件夾的子文件夾和子文件一樣。

除了上面介紹的,還可以繼承打開document,創(chuàng)建document,顯示document thumbnail 等功能。

代碼可以在這里看 github.com/storyteller…

以上就是Android如何實(shí)現(xiàn)一個DocumentProvider示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Android實(shí)現(xiàn)DocumentProvider的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android studio 4.1打包失敗和插件錯誤提示的解決

    Android studio 4.1打包失敗和插件錯誤提示的解決

    這篇文章主要介紹了Android studio 4.1打包失敗和插件錯誤提示的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Android  Spinner列表選擇框的應(yīng)用

    Android Spinner列表選擇框的應(yīng)用

    這篇文章主要介紹了Android Spinner列表選擇框的應(yīng)用的相關(guān)資料,這里對spinner的屬性和常用事件和數(shù)據(jù)綁定都做了介紹,需要朋友可以參考下
    2017-07-07
  • Android實(shí)現(xiàn)漸變色的圓弧虛線效果

    Android實(shí)現(xiàn)漸變色的圓弧虛線效果

    最近在學(xué)習(xí)Android的paint類的時候,學(xué)習(xí)了PathEffect路徑效果和Shader渲染效果。所以就做了下面的一個效果,其中自定義的view組主要是用DashPathEffect、SweepGradient的API形成的效果。感興趣的朋友們可以參考借鑒,下面來一起看看吧。
    2016-10-10
  • 實(shí)例詳解用戶輸入 i. 檢測常用手勢

    實(shí)例詳解用戶輸入 i. 檢測常用手勢

    通過本段代碼給大家介紹當(dāng)用戶輸入i檢測常用手勢的相關(guān)內(nèi)容,代碼簡單易懂,感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • Android仿QQ空間動態(tài)界面分享功能

    Android仿QQ空間動態(tài)界面分享功能

    這篇文章主要介紹了Android仿QQ空間動態(tài)界面分享功能,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2017-04-04
  • Android編程實(shí)現(xiàn)類似于圓形ProgressBar的進(jìn)度條效果

    Android編程實(shí)現(xiàn)類似于圓形ProgressBar的進(jìn)度條效果

    這篇文章主要介紹了Android編程實(shí)現(xiàn)類似于圓形ProgressBar的進(jìn)度條效果,結(jié)合實(shí)例形式分析了Android通過自定義View實(shí)現(xiàn)圓形進(jìn)度條效果的操作方法,需要的朋友可以參考下
    2017-03-03
  • Android接收和發(fā)送短信的實(shí)現(xiàn)代碼

    Android接收和發(fā)送短信的實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了Android接收和發(fā)送短信的實(shí)現(xiàn)代碼,感興趣的小伙伴們可以參考一下
    2016-08-08
  • idea下Android各目錄所代表的含義介紹

    idea下Android各目錄所代表的含義介紹

    這篇文章主要給大家介紹了關(guān)于idea下Android各目錄所代表含義的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Android開發(fā)之ListView、GridView 詳解及示例代碼

    Android開發(fā)之ListView、GridView 詳解及示例代碼

    本文主要介紹Android開發(fā)之ListView、GridView,這里整理了相關(guān)資料及簡單示例代碼,幫助大家學(xué)習(xí)參考,有需要的小伙伴可以參考下
    2016-08-08
  • Android開發(fā)仿bilibili刷新按鈕的實(shí)現(xiàn)代碼

    Android開發(fā)仿bilibili刷新按鈕的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Android 仿bilibili刷新按鈕的實(shí)現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-10-10

最新評論