page.title=特定のディレクトリへのアクセス page.keywords=preview,sdk,scoped directory access page.tags=androidn @jd:body

このドキュメントの内容

  1. 外部ストレージのディレクトリへのアクセス
  2. リムーバブル メディアのディレクトリへのアクセス
  3. ベスト プラクティス

写真アプリなどは通常、外部ストレージの特定のディレクトリ(Pictures ディレクトリなど)のみにアクセスする必要があります。 外部ストレージへのアクセスに関する従来のアプローチでは、このようなアプリに目的のディレクトリへのアクセスを容易に提供できる設計にはなっていませんでした。 次に例を示します。

外部ストレージのディレクトリへのアクセス

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. Pictures ディレクトリへのアクセスを要求するアプリケーション

ユーザーがアクセスを付与すると、 Activity.RESULT_OK の結果コードと、URI を含むインテント データを指定して、 onActivityResult() のオーバーライドを呼び出します。提供された URI を使用して、ディレクトリの情報にアクセスします。これは、ストレージ アクセス フレームワークで返された URI を使用する場合と同様です。

ユーザーがアクセスを付与しなかった場合は、 Activity.RESULT_CANCELED の結果コードと、null のインテント データを指定して、 onActivityResult() のオーバーライドを呼び出します。

注: 特定の外部ディレクトリへのアクセスを取得すると、そのディレクトリ内のサブディレクトリへのアクセスも取得します。

リムーバブル メディアのディレクトリへのアクセス

特定のディレクトリへのアクセスを使用してリムーバブル メディア上のディレクトリにアクセスするには、まず {@link android.os.Environment#MEDIA_MOUNTED} 通知をリッスンする {@link android.content.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 カードなどのリムーバブル メディアをマウントすると、システムは {@link android.os.Environment#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 を表示しません。

ユーザーが外部ディレクトリへのアクセスを拒否した直後に、またアクセスを要求しないようにしてください。 何度もアクセスを要求すると、ユーザー エクスペリエンスが低下します。