Android
 Computer >> コンピューター >  >> システム >> Android

Androidストレージ入門:内部ストレージと外部ストレージの違いと使い分け

ストレージは誰もが知っている存在でありながら、ついその重要性を見過ごしてしまいがちなものです。かつてはストレージ容量のわずかな増加さえも大きな飛躍であり、実現不可能に思えることさえありました。しかし今では、デバイスにどれだけの容量があるかを気にする人はほとんどいません(その違いに関心を持つ人はさらに少ないでしょう)。

より重要なのは、ストレージに保存されるデータの変遷に目を向けることです。スマートフォン以前の時代、私たちが保存していたのはたまに撮影した写真数枚、いくつかのゲーム、そして大量のテキストメッセージ程度でした。しかし現在、標準的なスマートフォンには、アプリケーション、ドキュメント、写真、動画、音楽ファイルなど、さまざまなデータが混在しています。本記事では、アプリケーションのためにデバイスのストレージ領域をどのように活用できるのかを見ていきましょう。

この記事で取り上げる内容は以下の通りです。

  1. Androidスマートフォンにおけるストレージの種類
  2. 各ストレージタイプの違い
  3. アプリケーションでストレージを使用する方法

すべてのアプリケーションは、内部ストレージ外部ストレージという2種類のストレージにアクセスできます。この2つには大きな違いがあり、それを理解しておくことは、次のアプリケーションを設計する際に必ず役立ちます。

本題に入る前に、ストレージとキャッシュについて一点触れておきます。ストレージは永続的に保存したいデータのためのものであり、キャッシュは一時的にデータを保存するためのものです。

Androidストレージ入門:内部ストレージと外部ストレージの違いと使い分け
Photo by Erda Estremera / Unsplash

内部ストレージ(Internal Storage)

アプリケーションがOS上で実行されると、それぞれ固有の内部ストレージが割り当てられます。このストレージはプライベートであり、そのアプリケーション専用です。つまり、他のアプリケーションからアクセスすることはできず、ユーザーもアクセスできません。また、内部ストレージを使用する際に覚えておきたいもう一つのポイントは、その可用性です。外部ストレージとは異なり、内部ストレージは常にアプリケーションから利用可能です。

ただし、このストレージの利用には欠点もあります。ユーザーがアプリケーションをアンインストールすると、アプリの内部ストレージに保存されていたすべてのデータも一緒に削除されます。ゲームをスマートフォンにインストールし、しばらく後に削除することを想像してみてください。万が一再びゲームをインストールしたときのために、ゲームの進行状況は保存されていてほしいはずです。

では、内部ストレージにファイルを保存するにはどうすればよいのでしょうか?

public void saveFileInternalStorage() {
   
        String FILENAME = "hello_world_file";
        String inputToFile = "Hello From Internal Storage!";
   
        try {
            FileOutputStream fileOutputStream = openFileOutput(FILENAME, Context.MODE_PRIVATE);
            fileOutputStream.write(inputToFile.getBytes());
            fileOutputStream.close();
            Toast.makeText(getApplicationContext(),
                    "File " + FILENAME + " has been saved successfully",
                    Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),
                    "File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(),
                    Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),
                    "File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(),
                    Toast.LENGTH_SHORT).show();
        }
 }
hello_world_file という名前のファイルを保存する

コード例でわかるように、テキスト「Hello From Internal Storage!」を含む hello_world_file という名前のファイルを保存しています。ここでは、この処理で発生しうる例外を示すために2つのcatch句を作成しましたが、汎用的なExceptionオブジェクトを使って1つのcatch句にまとめることも可能です。

注目すべきは openFileOutput メソッドです。このメソッドは、ファイルが既に存在する場合はそれを開き、存在しない場合は新しく作成します。第2引数はファイルモードで、ファイルのスコープとアクセス権を指定します。デフォルト値は MODE_PRIVATE で、この場合ファイルは自分のアプリケーションからのみアクセス可能になります。

このパラメータには他に MODE_WORLD_READABLE と MODE_WORLD_WRITEABLE という値がありますが、これらはAPI 17以降非推奨となっています。プライベートファイルを他のアプリケーションと共有するには、別のロジックを使用する必要があります。詳細については公式ドキュメントを参照してください。最後に、ファイルへの書き込み時には文字列をバイト配列に変換し、処理の最後で必ずファイルを閉じるようにしましょう。

Androidストレージ入門:内部ストレージと外部ストレージの違いと使い分け
Photo by Markus Spiske / Unsplash

外部ストレージ(External Storage)

名前から受ける印象とは異なり、外部ストレージとは「常にアクセスできるとは限らない」ストレージのことです。これは外部SDカード(セカンダリ外部ストレージ)の場合もあれば、デバイス本体に搭載されたストレージ(プライマリ外部ストレージ)の場合もあります。

端的に言えば、外部ストレージとは、USBケーブルでデバイスをパソコンに接続したときにアクセスできるストレージのことです。お察しの通り、この種のストレージに保存されたデータは、デバイス上の他のアプリケーションからもアクセス可能ですが、アプリケーションをアンインストールしてもデータは残ります。

外部ストレージへのファイル保存方法を示す前に、2つの準備が必要です。

  1. ファイルを保存するのに十分な空き容量があることを確認する
  2. 実行時に権限をリクエストする

十分なストレージ容量があるかどうかの確認には、以下のコードを使用します。

//Check if you can read/write to external storage
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}
外部ストレージへの読み書きが可能かどうかを確認する

外部ストレージにアクセスするには、AndroidManifest.xml に以下の権限を追加する必要があります。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
外部ストレージへの書き込み権限

さらに、API 23以降、危険性の高いパーミッションはインストール時ではなく実行時に許可を求める仕様になりました。外部ストレージへの書き込みもこれに該当するため、ユーザーがアプリケーションに権限を付与するかどうかを判断できるようにするロジックを追加する必要があります。

public void saveFileExternalStorage(View view) {
        if (isExternalStorageWritable()) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
                PackageManager.PERMISSION_GRANTED) {
                    writeFileToExternalStorage();
                } else{
                    ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
                }
            }
        }

        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            switch (requestCode) {
                case 0:
                {
                    writeFileToExternalStorage();
                    break;
                }
            }
        }
ユーザーが権限を付与したかどうかを確認する

writeFileToExternalStorage メソッドは以下のようになります。

public void writeFileToExternalStorage() {
            String root = Environment.getExternalStorageDirectory().toString();
            File myDir = new File(root + "/saved_files");
            if (!myDir.exists()) {
                myDir.mkdirs();
            }
            try {
                File file = new File(myDir, "myfile.txt");
                FileOutputStream out = new FileOutputStream(file);
                out.write(inputToFile.getBytes());
                out.close();
                Toast.makeText(getApplicationContext(),
                        "File myfile.txt" + " has been saved successfully to external storage",
                        Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
外部ストレージにファイルを書き込む

ここで紹介したコード全体のサンプルを見たい方は、GitHubリポジトリをご覧ください。

Androidストレージ入門:内部ストレージと外部ストレージの違いと使い分け
Photo by Steve Johnson / Unsplash

知っておくと良いこと

以上が、アプリケーションでさまざまな種類のストレージを扱うためのシンプルな2つの例でした。システムが管理するリソースを扱う以上、それに関連する動作についても把握しておく必要があります。

デフォルトでは、アプリケーションは内部ストレージにインストールされます(internalOnly の説明を参照)。しかし、APIレベル8以降では、マニフェストに installLocation 属性を追加することで、アプリケーションを外部ストレージにインストールできるようになります。これを行う理由の一つは、アプリケーションが非常に大きい場合に、空き容量の多い外部ストレージへインストールしてもらいたいというケースです。

この属性には3つの値があります。

  • auto — インストール先に特別なこだわりがないことを意味します。まず内部ストレージへのインストールが試みられ、内部ストレージが満杯の場合は外部ストレージにインストールされます。
  • internalOnly — アプリケーションは内部ストレージにのみインストールされ、そこに十分な空き容量がない場合はインストールされません。
  • preferExternal — アプリケーションを外部ストレージにインストールしたいという意向を示しますが、そこに十分な空きがない場合は内部ストレージにインストールされます。

auto と preferExternal の両方のオプションでは、ユーザーはアプリケーションを外部ストレージから内部ストレージへ、またはその逆へ移動することができます。

なお、ユーザーがデバイスをパソコンに接続してデータ共有を有効にしたり、SDカードをアンマウントしたりすると、外部ストレージから実行されているすべてのアプリケーションは強制終了されることに注意してください。アプリケーションが以下の機能を使用している場合は、外部ストレージにインストールすべきではありません。

各種サービス(特にアラームサービス)、インプットメソッドエンジン(IME)、ライブ壁紙、アプリウィジェット、アカウントマネージャー、同期アダプタ、デバイス管理者、および BOOT_COMPLETED を受け取るブロードキャストレシーバー。
  1. Androidで.estrongsフォルダを使う方法!ESファイルエクスプローラーの基本と活用術

    Androidスマートフォン上のファイルやフォルダを管理するうえで、ファイルマネージャーアプリは非常に便利な存在です。フォルダの作成・編集・移動から不要データの削除まで、あらゆる操作をサポートしてくれます。その中でも「ESファイルエクスプローラー」は、手軽にファイル操作ができることで人気を集めてきたアプリです。 ESファイルエクスプローラーには複数の内蔵フォルダが用意されており、そのひとつが「.estrongs」です。この見慣れない隠しフォルダについて気になっている方も多いのではないでしょうか。本記事では、Androidにおける.estrongsフォルダの役割や、「.estrongsとは何か」

  2. ファイルマネージャーだけでは不十分?Androidスマホのストレージ管理を徹底解説

    すべてのAndroidスマートフォンには、純正Android OSであれ、Android Open Source Project(AOSP)ベースのサードパーティOSであれ、ファイルマネージャーアプリが標準搭載されています。万一プリインストールされていない場合でも、Playストアからサードパーティ製のファイルエクスプローラーをダウンロードすれば対応可能です。 ファイルマネージャーでは、スマホに保存されたすべてのファイルやフォルダを一覧でき、ストレージの使用状況を把握できます。ユーザーはファイルを閲覧・オープンし、削除できそうなものを見つけて空き容量を確保します。こうしたストレージの節約こそが、