使用儲存空間存取架構開啟檔案

Android 4.4 (API 級別 19) 推出了儲存空間存取架構 (SAF)。SAF 可讓使用者瀏覽及開啟所有偏好的文件儲存空間供應商提供的文件、圖片和其他檔案。標準且易於使用的 UI 可讓使用者在各應用程式和供應器中,以一致的方式瀏覽檔案和存取近期檔案。

雲端或本機儲存空間服務可以實作封裝服務的 DocumentsProvider,加入這個生態系統。需要存取提供者文件的用戶端應用程式,只要透過幾行程式碼即可與 SAF 整合。

SAF 包含下列項目:

  • 文件供應器:內容供應器,可讓儲存空間服務 (例如 Google 雲端硬碟) 顯示其管理的檔案。文件供應器會實作為 DocumentsProvider 類別的子類別。文件提供者結構定義是以傳統檔案階層為基礎,但您可以自行決定文件提供者如何實際儲存資料。Android 平台包含多個內建文件提供者,例如「下載內容」、「圖片」和「影片」。
  • 用戶端應用程式:這是會叫用 ACTION_CREATE_DOCUMENTACTION_OPEN_DOCUMENTACTION_OPEN_DOCUMENT_TREE 意圖動作的自訂應用程式,並接收文件提供者傳回的檔案。
  • Picker:系統 UI,可讓使用者存取符合用戶端應用程式搜尋條件的所有文件供應器。

SAF 提供下列功能:

  • 讓使用者瀏覽所有文件供應商的內容,而非單一應用程式。
  • 讓應用程式能夠長期存取文件供應器擁有的文件。使用者可透過這項存取權,在提供者上新增、編輯、儲存及刪除檔案。
  • 支援多個使用者帳戶和暫時性根目錄,例如 USB 儲存空間提供者,這些項目只會在插入磁碟時顯示。

總覽

SAF 以內容供應器為中心,而內容供應器是 DocumentsProvider 類別的子類別。在文件供應器中,資料的結構是傳統檔案階層:

圖 1. 文件提供者資料模型。根節點會指向單一文件,然後開始展開樹狀結構。

注意事項:

  • 每個文件供應器都會回報一或多個,這是探索文件樹狀結構的起點。每個根目錄都有一個不重複的 COLUMN_ROOT_ID,且會指向代表該根目錄下內容的文件 (目錄)。根目錄是動態設計,可支援多個帳戶、暫時性 USB 儲存裝置,或使用者登入和登出等用途。
  • 每個根目錄下方都有一個文件。該文件會指向 1 到 N 個文件,而每個文件又可指向 1 到 N 個文件。
  • 每個儲存空間後端都會使用不重複的 COLUMN_DOCUMENT_ID 參照個別檔案和目錄。文件 ID 是唯一值,且一旦核發就不會變更,因為它們會用於在裝置重新啟動時持續授予 URI。
  • 文件可以是可開啟的檔案,具有特定 MIME 類型,或是包含其他文件的目錄,具有 MIME_TYPE_DIR MIME 類型。
  • 每份文件的功能可能不同,請參閱 COLUMN_FLAGS 瞭解詳情。例如 FLAG_SUPPORTS_WRITEFLAG_SUPPORTS_DELETEFLAG_SUPPORTS_THUMBNAIL。同一個 COLUMN_DOCUMENT_ID 可納入多個目錄。

控制流程

文件提供者資料模型是以傳統檔案階層為基礎。不過,您可以自由選擇資料的實際儲存位置,只要能使用 DocumentsProvider API 存取即可。舉例來說,您可以使用標記式雲端儲存空間來儲存資料。

圖 2 顯示相片應用程式如何使用 SAF 存取已儲存的資料:

圖 2. 儲存空間存取架構流程。

注意事項:

  • 在 SAF 中,提供者和用戶端不會直接互動。用戶端要求取得與檔案互動的權限,也就是讀取、編輯、建立或刪除檔案的權限。
  • 當應用程式 (在本例中為相片應用程式) 觸發意圖 ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT 時,互動就會開始。意圖可包含篩選器,進一步細化條件,例如「提供所有可開啟的 MIME 類型為 'image' 的檔案」。
  • 意圖觸發後,系統挑選器會前往每個已註冊的供應器,並向使用者顯示相符的內容根目錄。
  • 即使基礎文件提供者大不相同,挑選器仍可為使用者提供標準的文件存取介面。舉例來說,圖 2 顯示 Google 雲端硬碟供應器、USB 供應器和雲端供應器。

在圖 3 中,使用者在搜尋圖片時,從開啟的挑選器中選取「下載」資料夾。挑選器也會顯示可供用戶端應用程式使用的所有根目錄。

系統選擇器中的資料夾選項。
圖 3. 挑選器顯示「下載」資料夾已選為搜尋位置。

使用者選取「下載」資料夾後,系統就會顯示圖片。圖 4 顯示此程序的結果。使用者現在可以透過供應器和用戶端應用程式支援的方式與圖片互動。

圖 4. 系統挑選器中顯示的「下載」資料夾內圖片。

編寫用戶端應用程式

在 Android 4.3 以下版本中,如果您希望應用程式從其他應用程式擷取檔案,則必須叫用 ACTION_PICKACTION_GET_CONTENT 等意圖。使用者接著選取要從中挑選檔案的單一應用程式。所選應用程式必須提供使用者介面,讓使用者瀏覽及挑選可用的檔案。

在 Android 4.4 (API 級別 19) 以上版本中,您還可以選擇使用 ACTION_OPEN_DOCUMENT 意圖,這會顯示系統控管的挑選器 UI,讓使用者瀏覽其他應用程式提供的所有檔案。使用者可以透過這個單一 UI 從任何支援的應用程式中選取檔案。

在 Android 5.0 (API 級別 21) 以上版本中,您也可以使用 ACTION_OPEN_DOCUMENT_TREE 意圖,讓使用者選擇用戶端應用程式可存取的目錄。

注意: ACTION_OPEN_DOCUMENT 無法取代 ACTION_GET_CONTENT。您使用的版本取決於應用程式的需求:

  • 如果您希望應用程式讀取或匯入資料,請使用 ACTION_GET_CONTENT。使用這種方法時,應用程式會匯入資料的副本,例如圖片檔案。
  • 如果您希望應用程式能長期持續存取文件供應商擁有的文件,請使用 ACTION_OPEN_DOCUMENT。例如,相片編輯應用程式可讓使用者編輯儲存在文件提供者中的圖片。

如要進一步瞭解如何使用系統挑選工具 UI 瀏覽檔案和目錄,請參閱存取文件和其他檔案指南。

其他資源

如要進一步瞭解文件供應器,請參考下列資源:

範例

影片