Skip to content

Most visited

Recently visited

navigation

ストレージ オプション

ストレージ クィックビュー

  • プリミティブ データに共有の環境設定を使用する
  • プライベート データに内部デバイス ストレージを使用する
  • プライベート以外の大きなデータセットに外部ストレージを使用する
  • 構造化ストレージに SQLite データベースを使用する

このドキュメントの内容

  1. 共有の環境設定を使用する
  2. 内部ストレージを使用する
  3. 外部ストレージを使用する
  4. データベースを使用する
  5. ネットワーク接続を使用する

関連ドキュメント

  1. コンテンツ プロバイダとコンテンツ リゾルバ

Android では、永続的なアプリ データを保存するための複数のオプションを利用できます。選択できるソリューションは、データがそのアプリ専用のデータか、他のアプリ(およびユーザー)からアクセス可能か、データに必要な領域はどれくらいか、といった特定のニーズにより異なります。

データ ストレージのオプションは次のとおりです。

共有の環境設定
キーと値のペアでプリミティブ データを保存します。
内部ストレージ
端末のメモリにプライベート データを保存します。
外部ストレージ
共有外部ストレージにパブリック データを保存します。
SQLite データベース
プライベート データベースに構造化データを保存します。
ネットワーク接続
独自のネットワーク サーバーを使用してウェブにデータを保存します。

Android では、プライベート データでも他のアプリに公開する方法があります。それには、コンテンツ プロバイダを使用します。 コンテンツ プロバイダは、アプリのデータの読み取り / 書き込みアクセス許可を公開するためのオプションのコンポーネントで、必要に応じて制限を課すことができます。 コンテンツ プロバイダの使い方については、コンテンツ プロバイダのドキュメントをご覧ください。

共有の環境設定を使用する

SharedPreferences クラスを使用すると、プリミティブ データ型の永続的なキーと値のペアを保存および取得できます。 SharedPreferences を使用して、boolean、float、int、long、string など、任意のプリミティブ データを保存できます。 このデータはユーザー セッションをまたがって(アプリを強制終了しても)保持されます。

アプリの SharedPreferences オブジェクトを取得するには、次の 2 つのメソッドのいずれかを使用します。

値を書き込むには:

  1. edit() を呼び出して SharedPreferences.Editor を取得します。
  2. putBoolean()putString() などのメソッドを使用して値を追加します。
  3. commit() を使用して新しい値をコミットします。

値を読み取るには、getBoolean()getString() など、SharedPreferences のメソッドを使用します。

次に、電卓のキー入力の消音モードを保存する例を示します。

public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";

    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .

       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }

    @Override
    protected void onStop(){
       super.onStop();

      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);

      // Commit the edits!
      editor.commit();
    }
}

内部ストレージを使用する

端末の内部ストレージに直接ファイルを保存できます。デフォルトでは、内部ストレージに保存されたファイルはそのアプリのプライベート ファイルになり、それ以外のアプリはアクセスできません(ユーザーもアクセスできません)。 ユーザーがアプリをアンインストールすると、これらのファイルも削除されます。

内部ストレージにプライベート ファイルを作成して書き込むには:

  1. ファイル名と動作モードを指定して、openFileOutput() を呼び出します。 これは、FileOutputStream を返します。
  2. write() でファイルに書き込みます。
  3. close() でストリームを閉じます。

次に例を示します。

String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

MODE_PRIVATE は、ファイルを作成(または同じ名前のファイルを置換)して、アプリのプライベート ファイルに設定します。 他に使用できるモードは、MODE_APPENDMODE_WORLD_READABLEMODE_WORLD_WRITEABLE です。

注: 定数 MODE_WORLD_READABLE および MODE_WORLD_WRITEABLE は、API レベル 17 で廃止されました。Android N 以降、これらの定数を使用すると、SecurityException がスローされます。したがって、Android N 以降を対象とするアプリは、名前を指定してプライベート ファイルを共有することはできません。"file://" URI を共有しようとすると、FileUriExposedException がスローされます。 アプリのプライベート ファイルを他のアプリと共有する必要がある場合は、FLAG_GRANT_READ_URI_PERMISSION を指定して FileProvider を使用できます。ファイルの共有も併せてご覧ください。

内部ストレージからファイルを読み込むには:

  1. openFileInput() を呼び出し、読み込むファイルの名前を渡します。 これは、FileInputStream を返します。
  2. read() でファイルからバイト単位で読み込みます。
  3. close() を使用してストリームを閉じます。

ヒント: コンパイル時にアプリに静的ファイルを保存する必要がある場合は、プロジェクトの res/raw/ ディレクトリにファイルを保存します。 openRawResource() でファイルを開き、R.raw.<filename> リソース ID を渡します。 このメソッドは、ファイルの読み込みに使用できる InputStream を返します(ただし、元のファイルに書き込むことはできません)。

キャッシュ ファイルを保存する

データを永続的に保存するのではなくキャッシュしたい場合は、getCacheDir() を使用して File を開きます。これは、アプリが一時キャッシュ ファイルを保存する内部ディレクトリを示します。

端末の内部ストレージ領域が小さい場合、Android は領域を確保するためにこれらのキャッシュ ファイルを削除することがあります。 ただし、これらのファイルをシステムがクリーンアップするものとは考えないほうがよいでしょう。 常に自分でキャッシュ ファイルを管理して、適度な使用領域の上限(たとえば 1 MB)を超えないようにしてください。 ユーザーがアプリをアンインストールすると、これらのファイルも削除されます。

その他の有用なメソッド

getFilesDir()
内部ファイルが保存されたファイルシステム ディレクトリの絶対パスを取得します。
getDir()
内部ストレージ領域内にディレクトリを作成します(または既存のディレクトリを開きます)。
deleteFile()
内部ストレージに保存したファイルを削除します。
fileList()
現在アプリによって保存されているファイルの配列を返します。

外部ストレージを使用する

すべての Android 互換端末は、ファイルの保存先として共有の「外部ストレージ」をサポートしています。 これは、リムーバブル ストレージ メディア(SDカードなど)か、(取り外しできない)内部ストレージです。 外部ストレージに保存されたファイルは誰でも読み取り可能です。また、USB マスストレージからパソコンへのファイル転送を有効にすると、ユーザーがファイルを変更することもできます。

警告: 外部ストレージは、ユーザーがパソコンに外部ストレージをマウントしたりメディアを取り外したりすると、使用できなくなる可能性があります。また、外部ストレージに保存したファイルにはセキュリティが適用されません。 すべてのアプリは、外部ストレージに配置されたファイルの読み取り / 書き込みが可能です。また、ユーザーはファイルを削除できます。

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

Android 7.0 以降で、外部ストレージの特定のディレクトリにアクセスする必要がある場合、特定のディレクトリへのアクセスを使用します。 この特定のディレクトリへのアクセスによって、アプリから標準の外部ストレージ ディレクトリ(Pictures ディレクトリなど)へのアクセス方法が簡素化されます。さらに、アプリがアクセス許可を求めているディレクトリをわかりやすく説明する、シンプルなパーミッション UI を使用できます。 特定のディレクトリへのアクセスについては、特定のディレクトリへのアクセスをご覧ください。

外部ストレージへのアクセス許可を取得する

外部ストレージ上のファイルを読み取る、または書き込むには、アプリが READ_EXTERNAL_STORAGE または WRITE_EXTERNAL_STORAGE のシステム パーミッションを取得する必要があります。 次に例を示します。

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

ファイルの読み取りと書き込みの両方を行う際に必要なパーミッションは、WRITE_EXTERNAL_STORAGE のみです。これは暗黙的に読み取りアクセスも要求するからです。

注: Android 4.4 以降、アプリのプライベート ファイルのみの読み取りや書き込みには、これらのパーミッションは不要です。 詳細については、以下のアプリのプライベート ファイルの保存のセクションをご覧ください。

メディアの使用可否の確認

外部ストレージに対して何らかの処理を行う前に、必ず getExternalStorageState() を呼び出してメディアの使用可否を確認してください。メディアがパソコンにマウントされている、見つからない、読み取り専用などの状態になっていることがあります。 以下のように、使用可否を確認できるメソッドはいくつかあります。

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

getExternalStorageState() メソッドは、メディアが共有されているか(パソコンに接続されているか)、完全に見つからないか、不正に取り外されたかなど、確認すべきその他の状態を返します。 アプリがメディアにアクセスする必要があるときは、これらの結果を使用してユーザーに詳しい情報を通知することができます。

他のアプリと共有できるファイルを保存する

一般に、ユーザーがアプリから取得する可能性がある新しいファイルは、他のアプリからアクセス可能でユーザーが端末から容易にコピーできる、端末上の「パブリック」な場所に保存する必要があります。 その場合、Music/Pictures/Ringtones/ などの共有パブリック ディレクトリを使用する必要があります。

適切なパブリック ディレクトリを示す File を取得するには、getExternalStoragePublicDirectory() を呼び出し、DIRECTORY_MUSICDIRECTORY_PICTURESDIRECTORY_RINGTONES など、必要なディレクトリのタイプを渡します。 対応するメディアタイプのディレクトリにファイルを保存すると、システムのメディア スキャナがファイルをシステム内で適切に分類します(たとえば、着信音はシステム設定で音楽ではなく着信音として表示されます)。

以下はパブリックの写真ディレクトリに新しい写真アルバム用のディレクトリを作成するメソッドの例です。

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

アプリのプライベート ファイルを保存する

他のアプリでは使用しないファイルを扱う場合は(アプリのみで使用するグラフィック テクスチャやサウンド エフェクトなど)、getExternalFilesDir() を呼び出して、外部ストレージ上のプライベート ストレージ ディレクトリを使用する必要があります。このメソッドはサブディレクトリのタイプを指定する type 引数(DIRECTORY_MOVIES など)も受け取ります。 特定のメディア ディレクトリを指定する必要がない場合は、null を渡すと、アプリのプライベート ディレクトリのルート ディレクトリを受け取ります。

Android 4.4 以降、アプリのプライベート ディレクトリにあるファイルの読み取りや書き込みの際は、READ_EXTERNAL_STORAGE または WRITE_EXTERNAL_STORAGE のパーミッションは不要になりました。 maxSdkVersion 属性を追加することで、それより前の Android でのみパーミッションをリクエストする必要があることを宣言できます。

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                     android:maxSdkVersion="18" />
    ...
</manifest>

注: ユーザーがアプリをアンインストールすると、このディレクトリおよびディレクトリ内のすべてのコンテンツは削除されます。また、システムのメディア スキャナはこれらのディレクトリにあるファイルを読み込まないため、MediaStore コンテンツ プロバイダからアクセスすることはできません。 このように、キャプチャまたはアプリで編集した写真、アプリで購入した曲など、最終的にユーザーに属するメディアには、これらのディレクトリを使用しないでください。このようなファイルは、パブリック ディレクトリに保存する必要があります。

内部メモリを外部ストレージとして使用するためにパーティションを割り当てている端末では、SDカード スロットも使用できる場合があります。このような端末が Android 4.3 以下を実行している場合、getExternalFilesDir() メソッドを使用すると、内部パーティションへのアクセス権のみが付与され、アプリは SDカードを読み書きできません。しかし Android 4.4 以降では、getExternalFilesDirs() を呼び出すと、各場所のエントリを示す File 配列が返され、どちらの場所にもアクセスできます。 配列の最初のエントリはプライマリ外部ストレージと見なされます。いっぱいになっているか使用できない場合を除いて、この場所を使用する必要があります。 使用可能な両方の場所にアクセスし、Android 4.3 以下にも対応する必要がある場合は、Support Library の静的メソッド、ContextCompat.getExternalFilesDirs() を使用します。 このメソッドでも File 配列が返されますが、Android 4.3 以下では常に 1 つのエントリしか含まれていません。

警告: getExternalFilesDir()getExternalFilesDirs() で提供されるディレクトリは、MediaStore コンテンツ プロバイダではアクセスできません。READ_EXTERNAL_STORAGE パーミッションを付与されたその他のアプリは、これらのディレクトリを含む外部ストレージ上のすべてのファイルにアクセスできます。 ファイルへのアクセスを完全に制限する必要がある場合は、代わりに内部ストレージにファイルを書き込む必要があります。

キャッシュ ファイルを保存する

キャッシュ ファイルを保存する必要がある外部ストレージ ディレクトリを示す File を開くには、getExternalCacheDir() を呼び出します。 ユーザーがアプリをアンインストールすると、これらのファイルは自動的に削除されます。

前述の ContextCompat.getExternalFilesDirs() と同様、ContextCompat.getExternalCacheDirs() を呼び出して、セカンダリ外部ストレージ上のキャッシュ ディレクトリ(使用可能な場合)にアクセスすることもできます。

ヒント: ファイルのスペースを確保しながらアプリのパフォーマンスを維持するには、キャッシュ ファイルを注意深く管理し、アプリのライフサイクル上、不要になったファイルを削除することが重要です。

データベースを使用する

Android は SQLite データベースを完全にサポートしています。作成したデータベースは、アプリの任意のクラスから名前を指定してアクセスできますが、アプリ以外からアクセスすることはできません。

新しい SQLite データベースを作成するには、SQLiteOpenHelper のサブクラスを作成し、onCreate() メソッドをオーバーライドして、このメソッド内で SQLite コマンドを実行してデータベースのテーブルを作成することをお勧めします。 次に例を示します。

public class DictionaryOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 2;
    private static final String DICTIONARY_TABLE_NAME = "dictionary";
    private static final String DICTIONARY_TABLE_CREATE =
                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
                KEY_WORD + " TEXT, " +
                KEY_DEFINITION + " TEXT);";

    DictionaryOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DICTIONARY_TABLE_CREATE);
    }
}

定義したコンストラクタを使用して、SQLiteOpenHelper の実装のインスタンスを取得できます。 データベースの書き込みや読み取りには、getWritableDatabase()getReadableDatabase() をそれぞれ呼び出します。 どちらのメソッドも SQLiteDatabase オブジェクトを返します。このオブジェクトはデータベースを示し、SQLite を操作するメソッドを提供します。

SQLiteDatabase query() メソッドを使用して、SQLite クエリを実行できます。このメソッドは、クエリするテーブル、射影、選択、列、グループ化など、各種のクエリ パラメータを受け入れます。 列のエイリアスを必要とするような複雑なクエリの場合は、クエリの構築に便利なメソッドがいくつか提供されている SQLiteQueryBuilder を使用します。

SQLite のクエリはすべて、クエリで検出されたすべての行を参照する Cursor を返します。 Cursor はもともと、データベースのクエリで取得した結果を操作して行や列を読み取ることができる仕組みです。

Android での SQLite データベースの使い方を示すサンプル アプリについては、Note Pad アプリや Searchable Dictionary アプリをご覧ください。

データベースのデバッグ

Android SDK には、sqlite3 データベース ツールが含まれており、SQLite データベースでコンテンツを参照したり、SQL コマンドを実行したり、その他便利な関数を実行できます。 このツールを実行する方法については、リモート シェルで sqlite3 データベースを調べるをご覧ください。

ネットワーク接続を使用する

ネットワーク(使用可能な場合)を使用して、独自のウェブベース サービスにデータを保存し、そこからデータを取得することができます。 ネットワークの操作を実行するには、次のパッケージのクラスを使用します。

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!

Follow Google Developers on WeChat

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 short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)