Skip to content

Most visited

Recently visited

navigation

特定のディレクトリへのアクセス

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

Android 7.0 では、一般的な外部ストレージ ディレクトリにアクセスできるシンプルな API が提供されています。

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

StorageManager クラスを使用して、適切な StorageVolume インスタンスを取得します。次に、そのインスタンスの StorageVolume.createAccessIntent() メソッドを呼び出して、インテントを作成します。このインテントを使用して、外部ストレージ ディレクトリにアクセスします。リムーバブル メディア ボリュームなど、使用できるすべてのボリュームのリストを取得するには、StorageManager.getStorageVolumes() を使用します。

特定のファイルの情報がある場合は、StorageManager.getStorageVolume(File) を使用して、そのファイルを含む StorageVolume を取得します。この StorageVolumecreateAccessIntent() を呼び出し、このファイルがある外部ストレージ ディレクトリにアクセスします。

外部 SD カードなどのセカンダリ ボリュームで、createAccessIntent() を呼び出すときに null を渡し、特定のディレクトリではなくボリューム全体へのアクセスをリクエストします。プライマリ ボリュームに null を渡すか、無効なディレクトリ名を渡すと、createAccessIntent() は null を返します。

次のコード スニペットは、プライマリ共有ストレージの Pictures ディレクトリを開く方法の例を示しています。

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

システムは外部ディレクトリへのアクセス権の付与を試み、必要に応じてシンプルな UI で、アクセスを許可するかユーザーに確認します。

図 1 Pictures ディレクトリへのアクセスをリクエストするアプリ

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

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

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

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

特定のディレクトリへのアクセスを使用してリムーバブル メディア上のディレクトリにアクセスするには、まず 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 はできる限り保持してください。そうすれば、ユーザーに何度もアクセス権の付与を求める必要がなくなります。ユーザーがアクセス権を付与したら、getContentResolver() を呼び出し、返された ContentResolver で、ディレクトリのアクセス URI を指定して takePersistableUriPermission() を呼び出します。システムが URI を保持し、以降のアクセス リクエストでは RESULT_OK を返して、ユーザーに確認の UI を表示しません。

ユーザーが外部ディレクトリへのアクセスを拒否した直後に、アクセスを再度リクエストしないようにしてください。何度もアクセスをリクエストすると、ユーザー エクスペリエンスが低下します。リクエストがユーザーによって拒否され、アプリがアクセスを再度リクエストすると、UI に [Don't ask again] チェックボックスが表示されます。

図 1 リムーバブル メディアへのアクセスを再度リクエストしているアプリ。

ユーザーが [Don't ask again] を選択してリクエストを拒否すると、特定のディレクトリに対するアプリからのリクエストは、今後すべて自動的に拒否され、リクエストに関する UI は表示されなくなります。

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.