限定範圍目錄存取

應用程式 (例如,相片應用程式) 通常只需要存取外部儲存空間中的特定目錄,例如 Pictures 目錄。 目前用來存取外部儲存空間的方式並非設計來輕鬆地為這些類型的應用程式提供已設定目標的目錄存取。 例如:

  • 在您的宣示說明中要求 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE 可允許存取外部儲存空間ac上的所有公用目錄,但這可能超過您應用程式所需的存取權。
  • 使用儲存空間存取架構通常會使得您的使用者透過系統 UI 挑選目錄,這在您的應用程式一律存取相同外部目錄的情況下是不必要的。

Android N 提供新的簡化 API,可用來存取常用外部儲存空間目錄。

存取外部儲存空間目錄

使用 StorageManager 類別來取得適當的 StorageVolume 實例。 接著,透過呼叫該實例的 StorageVolume.createAccessIntent() 方法以建立意圖。使用此意圖來存取外部儲存空間目錄。 若要取得所有可用的磁碟區 (包括抽取式媒體磁碟區) 清單,請使用 StorageManager.getVolumesList()

下列程式碼片段是一個範例,它說明如何開啟主要共用儲存空間中的 Pictures 目錄:

StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = sm.getPrimaryVolume();
Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);

系統會嘗試授予對外部目錄的存取權,並在需要時使用簡化的 UI 向使用者確認存取權:

圖 1. 應用程式要求對 [圖片] 目錄的存取權。

若使用者授予存取權,系統會呼叫您的 onActivityResult() 覆寫並傳回 Activity.RESULT_OK 的結果代碼,以及包含 URI 的意圖資料。 使用提供的 URI 來存取目錄資訊,這類似於使用儲存空間存取架構所傳回的 URI。

若使用者未授予存取權,系統會呼叫您的 onActivityResult() 覆寫並傳回 Activity.RESULT_CANCELED 的結果代碼,以及 Null 意圖資料。

注意:取得對特定外部目錄的存取權也會取得對該目錄之子目錄的存取權。

存取抽取式媒體上的目錄

若要使用「限定範圍目錄存取」來存取抽取式媒體上的目錄,請先新增會接聽 MEDIA_MOUNTED 通知的 BroadcastReceiver,例如:

<receiver
    android:name=".MediaMountedReceiver"
    android:enabled="true"
    android:exported="true" >
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_MOUNTED" />
        <data android:scheme="file" />
    </intent-filter>
</receiver>

當使用者掛接抽取式媒體 (例如 SD 卡) 時,系統會傳送 MEDIA_MOUNTED 通知。 此通知會在意圖資料中提供 StorageVolume 物件,讓您用來存取抽取式媒體上的目錄。 下列範例會存取抽取式媒體上的 Pictures 目錄:

// BroadcastReceiver has already cached the MEDIA_MOUNTED
// notification Intent in mediaMountedIntent
StorageVolume volume = (StorageVolume)
    mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);

最佳做法

如果可能,請將外部目錄存取 URI 設定為持續性,這樣您就不需要重複地要求使用者授予存取權。 一旦使用者授予存取權,請使用目錄存取 URI 呼叫 getContentResolver().takePersistableUriPermssion()。 系統會將該 URI 設定為持續性,而且後續存取要求將會傳回 RESULT_OK,而且不會為使用者顯示確認 UI。

若使用者拒絕對外部目錄的存取權,請勿立刻又要求存取權。 重複堅持取得存取權會導致極差的使用者體驗。