Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

Android ストレージのユースケースとおすすめの方法

ユーザーがファイルをより細かく制御して整理できるように、Android 10 では対象範囲別ストレージという新しいアプリ用ストレージ パラダイムが導入されました。対象範囲別ストレージは、アプリがデバイスの外部ストレージにファイルを保存しアクセスする方法を刷新します。対象範囲別ストレージをサポートするようにアプリを移行するには、このガイドで概説する一般的なストレージ ユースケースのおすすめの方法に従ってください。ユースケースは、メディア ファイルの処理メディア以外のファイルの処理という 2 つのカテゴリに分かれています。

Android でファイルを保存しアクセスする方法について詳しくは、ストレージのトレーニング ガイドをご覧ください。

メディア ファイルを処理する

このセクションでは、メディア ファイル(動画、画像、音声ファイル)を扱う一般的なユースケースと、アプリで使用できる大まかな方法について説明します。そうした各ユースケースと、詳細を含む各セクションへのリンクを次の表にまとめます。

ユースケース 概要
すべての画像ファイルまたは動画ファイルを表示する Android のすべてのバージョンで同じ方法を使用します。
特定のフォルダの画像または動画を表示する Android のすべてのバージョンで同じ方法を使用します。
写真から位置情報にアクセスする アプリで対象範囲別ストレージを使用する場合は、1 つの方法を使用します。アプリで対象範囲別ストレージをオプトアウトしている場合は、別のアプローチを使用します。
1 回の操作で複数のメディア ファイルを変更または削除する Android 11 では 1 つの方法を使用します。Android 10 の場合は、対象範囲別ストレージをオプトアウトし、代わりに Android 9 以前の方法を使用します。
既存の単一の画像を読み込む Android のすべてのバージョンで同じ方法を使用します。
単一の画像をキャプチャする Android のすべてのバージョンで同じ方法を使用します。
メディア ファイルを他のアプリと共有する Android のすべてのバージョンで同じ方法を使用します。
メディア ファイルを特定のアプリと共有する Android のすべてのバージョンで同じ方法を使用します。
直接ファイルパスを使用するコードまたはライブラリからファイルにアクセスする Android 11 では 1 つの方法を使用します。Android 10 の場合は、対象範囲別ストレージをオプトアウトし、代わりに Android 9 以前の方法を使用します。

複数のフォルダの画像ファイルまたは動画ファイルを表示する

query() API を使用してメディア コレクションをクエリします。メディア ファイルをフィルタするか並べ替えるには、projectionselectionselectionArgssortOrder パラメータを調整します。

特定のフォルダの画像または動画を表示する

次の方法を使用します。

  1. アプリの権限をリクエストするで概説されているおすすめの方法に沿って、READ_EXTERNAL_STORAGE 権限をリクエストします。
  2. ディスク上のメディア アイテムへの絶対ファイルシステム パスを含む MediaColumns.DATA の値に基づいてメディア ファイルを取得します。

写真から位置情報にアクセスする

対象範囲別ストレージを使用しているアプリでは、メディア ストレージ ガイドの写真の位置情報セクションの手順に従います。

1 回の操作で複数のメディア ファイルを変更または削除する

アプリが動作する Android のバージョンに基づいてロジックを組み込みます。

Android 11 で動作するアプリ

次の方法を使用します。

  1. MediaStore.createWriteRequest() または MediaStore.createTrashRequest() を使用してアプリの書き込みまたは削除リクエストのペンディング インテントを作成してから、そのインテントを取得することで一連のファイルを編集する権限をユーザーに求めます。
  2. ユーザーのレスポンスを評価します。

    • 権限が付与されている場合は、変更または削除の操作を行います。
    • 権限が付与されていない場合は、アプリの機能に権限が必要な理由をユーザーに説明します。

詳細については、Android 11 で利用可能なメソッドを使用して一括操作を行う方法をご覧ください。

Android 10 で動作するアプリ

Android 10(API レベル 29)をターゲットとしているアプリの場合は、対象範囲別ストレージをオプトアウトし、Android 9 以前の方法を使用してこの操作を行います。

Android 9 以前で動作するアプリ

次の方法を使用します。

  1. アプリの権限をリクエストするで概説されているおすすめの方法に沿って、WRITE_EXTERNAL_STORAGE 権限をリクエストします。
  2. MediaStore API を使用してメディア ファイルを変更または削除します。

既存の単一の画像を読み込む

既存の単一の画像を読み込む場合(ユーザーのプロフィール写真として使用するなど)、アプリは操作に独自の UI を使用するか、システムの選択ツールを使用できます。

独自のユーザー インターフェースを表示する

次の方法を使用します。

  1. アプリの権限をリクエストするで概説されているおすすめの方法に沿って、READ_EXTERNAL_STORAGE 権限をリクエストします。
  2. query() API を使用してメディア コレクションをクエリします
  3. 結果をアプリのカスタム UI に表示します。

システムの選択ツールを使用する

読み込む画像を選択するようユーザーに求める ACTION_GET_CONTENT インテントを使用します。

システムの選択ツールでユーザーに提示して選択させる画像の種類をフィルタする場合は、setType() または EXTRA_MIME_TYPES を使用できます。

単一の画像をキャプチャする

アプリで使用する単一の画像をキャプチャする場合(ユーザーのプロフィール写真として使用するなど)、ACTION_IMAGE_CAPTURE インテントを使用して、ユーザーに対し、デバイスのカメラを使用して写真を撮影するよう求めます。キャプチャされた写真は MediaStore.Images テーブルに保存されます。

メディア ファイルを他のアプリと共有する

insert() メソッドを使用して、MediaStore にレコードを直接追加します。詳細については、メディア ストレージ ガイドのアイテムを追加するをご覧ください。

メディア ファイルを特定のアプリと共有する

ファイル共有の設定ガイドで説明されているように、Android FileProvider コンポーネントを使用します。

直接ファイルパスを使用するコードまたはライブラリからファイルにアクセスする

アプリが動作する Android のバージョンに基づいてロジックを組み込みます。

Android 11 で動作するアプリ

次の方法を使用します。

  1. アプリの権限をリクエストするで概説されているおすすめの方法に沿って、READ_EXTERNAL_STORAGE 権限をリクエストします。
  2. 直接ファイルパスを使用してファイルにアクセスします。

詳細については、raw パスを使用してファイルにアクセスするをご覧ください。

Android 10 で動作するアプリ

Android 10(API レベル 29)をターゲットとしているアプリの場合は、対象範囲別ストレージをオプトアウトし、Android 9 以前の方法を使用してこの操作を行います。

Android 9 以前で動作するアプリ

次の方法を使用します。

  1. アプリの権限をリクエストするで概説されているおすすめの方法に沿って、WRITE_EXTERNAL_STORAGE 権限をリクエストします。
  2. 直接ファイルパスを使用してファイルにアクセスします。

メディア以外のファイルを処理する

このセクションでは、メディア以外のファイルを処理する一般的なユースケースと、アプリで使用できる大まかな方法について説明します。そうした各ユースケースと、詳細を含む各セクションへのリンクを次の表にまとめます。

ユースケース 概要
ドキュメント ファイルを開く Android のすべてのバージョンで同じ方法を使用します。
以前の保存先から既存のファイルを移行する 可能であれば、ファイルを対象範囲別ストレージに移行します。必要に応じて、Android 10 の対象範囲別ストレージをオプトアウトします。
コンテンツを他のアプリと共有する Android のすべてのバージョンで同じ方法を使用します。
メディア以外のファイルをキャッシュに保存する Android のすべてのバージョンで同じ方法を使用します。

ドキュメント ファイルを開く

ACTION_OPEN_DOCUMENT インテントを使用して、システムの選択ツールで開くファイルを選択するようユーザーに求めます。システムの選択ツールでユーザーに提示して選択させるファイルの種類をフィルタする場合は、setType() または EXTRA_MIME_TYPES を使用できます。

たとえば、次のコードを使用してすべての PDF、ODT、TXT ファイルを検索できます。

Kotlin

startActivityForResult(
        Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
            putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
                    "application/pdf", // .pdf
                    "application/vnd.oasis.opendocument.text", // .odt
                    "text/plain" // .txt
            ))
        },
        REQUEST_CODE
      )

Java

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
                "application/pdf", // .pdf
                "application/vnd.oasis.opendocument.text", // .odt
                "text/plain" // .txt
        });
        startActivityForResult(intent, REQUEST_CODE);

以前の保存先から既存のファイルを移行する

ディレクトリは、アプリ固有のディレクトリや公開共有ディレクトリでない場合に、以前の保存先と見なされます。アプリが以前の保存先でファイルを作成または使用する場合は、アプリのファイルを対象範囲別ストレージでアクセスできる場所に移行し、対象範囲別ストレージ内のファイルを扱うために必要な変更をアプリに加えることをおすすめします。

データ移行のために以前の保存先へのアクセス権を維持する

アプリのファイルを対象範囲別ストレージでアクセスできる場所に移行するには、以前の保存先へのアクセス権を維持する必要があります。使用する方法は、アプリのターゲット API レベルによって異なります。

Android 11 をターゲットとするアプリの場合
  1. preserveLegacyExternalStorage フラグを使用して以前のストレージ モデルを保持し、ユーザーが Android 11 をターゲットとするアプリの新しいバージョンにアップグレードする際に、ユーザーのデータを移行できるようにします。

  2. 対象範囲別ストレージをオプトアウトするに進み、Android 10 デバイスの以前の保存先にあるファイルにアプリで引き続きアクセスできるようにします。

Android 10 をターゲットとするアプリの場合

対象範囲別ストレージをオプトアウトして、Android バージョン間でアプリの動作を維持しやすくします。

アプリデータを移行する

アプリで移行の準備が整ったら、次の方法を使用します。

  1. アプリの作業ファイルが /sdcard/ ディレクトリまたはそのサブディレクトリにあるかどうかを確認します。
  2. 非公開のアプリファイルを /sdcard/ の現在の場所から、getExternalFilesDir() メソッドで返されるディレクトリに移動します。
  3. メディア以外の共有ファイルを /sdcard/ の現在の場所から、Downloads/ ディレクトリのアプリ専用サブディレクトリに移動します。
  4. アプリの以前のストレージ ディレクトリを /sdcard/ ディレクトリから削除します。

コンテンツを他のアプリと共有する

アプリのファイルを他の 1 つのアプリと共有するには、FileProvider を使用します。すべてのアプリ間でファイルを共有する必要がある場合は、アプリごとにコンテンツ プロバイダを使用して、アプリがコレクションに追加されたときにデータを同期することをおすすめします。

メディア以外のファイルをキャッシュに保存する

使用する方法は、キャッシュに保存する必要があるファイルの種類によって異なります。

対象範囲別ストレージを一時的にオプトアウトする

アプリが対象範囲別ストレージに完全に対応するまでは、次のいずれかの方法で一時的にオプトアウトできます。

  • Android 9(API レベル 28)以前をターゲットとする。
  • Android 10(API レベル 29)以降をターゲットとしている場合は、アプリのマニフェスト ファイルで requestLegacyExternalStorage の値を true に設定する。

    <manifest ... >
    <!-- This attribute is "false" by default on apps targeting
         Android 10 or higher. -->
      <application android:requestLegacyExternalStorage="true" ... >
        ...
      </application>
    </manifest>
    

Android 9 以前をターゲットとしているアプリが対象範囲別ストレージを使用したときにどのように動作するのかテストするには、requestLegacyExternalStorage の値を false に設定して、対象範囲別ストレージをオプトインします。Android 11 デバイスでテストする場合は、アプリの互換性フラグを使用して、対象範囲別ストレージの有無にかかわらずアプリの動作をテストすることもできます。