最終更新日:2025年4月29日
「Androidストレージ、内部ストレージへアクセスする」などの説明を参考に、以下の内容を実施せよ。
![]() |
![]() |
![]() |
Android は、他のプラットフォームのディスクベース ファイル システムと同様のファイル システムを使用しています。システムには、アプリデータの保存方法として次のような選択肢が用意されている(Android Developers Guideを参照)。
内部ストレージの場合、許可(PERMISSION)は不要。
外部ストレージのファイルにアクセスする場合、READ_EXTERNAL_STORAGE または WRITE_EXTERNAL_STORAGE
の許可(PERMISSION)が必要。
MediaStore APIを用いる。
基本的に、ファイルにアクセスする場合、READ_EXTERNAL_STORAGE または WRITE_EXTERNAL_STORAGE
の許可(PERMISSION)が必要。
SharedPreference の Key - Value ペアを用いる
構造化データを保存するため、Room という永続ライブラリを用いる。
多くの場合、アプリが作成するファイルは、他のアプリがアクセスする必要のないファイルまたはアクセスすべきでないファイルです。このようなアプリ固有のファイルには、以下の保存場所が用意されています。
ユーザーがアプリをアンインストールすると、アプリ固有のストレージに保存されているファイルは削除されます。そのため、アプリから独立して保持されることをユーザーが期待するファイルは、このストレージに保存すべきではありません。たとえば、ユーザーがアプリで写真を撮影した場合、通常はアプリをアンインストールした後でも写真にアクセスすることを望みます。その種のファイルは、共有ストレージを使用して適切なメディア
コレクションに保存する必要があります。
内部ストレージ内にはアプリごとにディレクトリが用意されており、アプリはそこでアプリ固有のファイルを整理できます。1 つのディレクトリはアプリの永続ファイル用に設計されています。
もう 1 つのディレクトリにはアプリのキャッシュ ファイルを格納します。これらのディレクトリ内のファイルを読み書きするためのシステム権限は必要ありません。
他のアプリは内部ストレージ内に保存されているファイルにアクセスできません。
したがって、内部ストレージは他のアプリがアクセスすべきでないアプリデータを保存する場所に適しています。
ただし、これらのディレクトリは容量が小さいことが多いため、注意が必要です。
アプリ固有のファイルを内部ストレージに書き込む前に、デバイスの空き領域を問い合わせる必要があります。
アプリの通常の永続ファイルは、コンテキスト オブジェクトの filesDir プロパティを使用してアクセスできるディレクトリにあります。
フレームワークには、このディレクトリ内のファイルにアクセスして保存する方法がいくつか用意されています。
File API を使用すると、ファイルにアクセスして保存できます。
String filename = "myfile.txt";
File file = new File(getFilesDir(), filename);
File API を使用する代わりに、openFileOutput() を呼び出して、filesDir ディレクトリ内のファイルへの書き込みを行う FileOutputStream
を取得することもできます。
次のコード スニペットは、ファイルにテキストを書き込む方法を示しています。
String fileContents = "Hello world!";
try {
FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE)
fos.write(fileContents.getBytes());
}
fileList() を呼び出すことにより、filesDir ディレクトリ内のすべてのファイル名を含む配列を取得できます。次のコード スニペットをご覧ください。
File.createTempFile(filename, null, getCacheDir());
アプリは、コンテキスト オブジェクトの cacheDir プロパティと File API を次のように使用して、このディレクトリ内のファイルにアクセスします。
File cacheFile = new File(getCacheDir(), filename);
キャッシュ ファイルは随時 Android によって自動的に削除されますが、だからといってキャッシュ ファイルのクリーンアップをシステムにまかせるべきではありません。内部ストレージ内のアプリのキャッシュ
ファイルを常にメンテナンスする必要があります。
内部ストレージ内のキャッシュ ディレクトリからファイルを削除するには、次のいずれかのメソッドを使用します。
cacheFile.delete();
context.deleteFile(cacheFileName);
アプリ固有のファイルを保存するのに十分な容量が内部ストレージにない場合は、代わりに外部ストレージの使用を検討してください。外部ストレージには、特定のアプリ内でのみユーザーに価値を提供するファイルを整理するためのディレクトリが用意されています。1 つのディレクトリはアプリの永続ファイル用に設計されています。もう 1 つのディレクトリにはアプリのキャッシュ ファイルを格納します。
Android 9(API レベル 28)以下を実行するデバイスでは、適切なストレージ権限を持っていれば、どのアプリも外部ストレージ内のアプリ固有のファイルにアクセスできます。ユーザーがファイルをきめ細かく管理して整理できるように、Android 10(API レベル 29)以上をターゲットとするアプリには、外部ストレージに対する限定的なアクセス権がデフォルトで付与されます(そのようなストレージを対象範囲別ストレージと呼びます)。対象範囲別ストレージを有効にすると、アプリは他のアプリに属するアプリ固有のディレクトリにアクセスできなくなります。
外部ストレージはユーザーが削除できる物理ボリューム上にあるため、外部ストレージとの間でアプリ固有のデータの読み取りまたは書き込みを行う前に、ボリュームにアクセスできることを確認する必要があります。
ボリュームの状態を問い合わせるには、Environment.getExternalStorageState() を呼び出します。返された状態が MEDIA_MOUNTED
の場合は、外部ストレージ内のアプリ固有のファイルの読み取りと書き込みを行うことができます。MEDIA_MOUNTED_READ_ONLY
の場合は、それらのファイルの読み取りのみを行うことができます。
たとえば、以下のメソッドはストレージが使用可能かどうかを判断するのに役立ちます。
// Checks if a volume containing external storage is available for read and write.
private boolean isExternalStorageWritable() {
return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED;
}
// Checks if a volume containing external storage is available to at least read.
private boolean isExternalStorageReadable() {
return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED ||
Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED_READ_ONLY;
}
外部ストレージからアプリ固有のファイルにアクセスするには、次のコード スニペットに示すように、getExternalFilesDir() を呼び出します。
外部キャッシュ ディレクトリからファイルを削除するには、ファイルを表す File オブジェクトで delete() メソッドを使用します。
Media Contents のように、特定のアプリ内でのみユーザーに価値を提供するメディア ファイルを使用する場合は、次のコード スニペットに示すように、外部ストレージ内のアプリ固有のディレクトリに保存することをおすすめします。
「ファイルリストの取得と表示」の説明を参考に、以下の内容を実施せよ。
![]() |
fileList() を呼び出すことにより、アプリケーションの file directory 内のすべてのファイル名を含む配列を取得できる。
String[] files = fileList();
UI にある情報のリスト(配列)を表示したいとき、ListView を用いる。ListView とデータを結びつくため、文字列データは
ArrayList
ListView とリストを結びつけるのは、Adapter(アダプター)で、アダプターは android.widget.BaseAdapter
から派生したオブジェクトです。
特に配列やリストと結びついて使うために、 ArrayAdapter (android.widget.ArrayAdapter
例えば、listView 変数は findViewById() を用いて、取得するListView オブジェクトだとして、ArrayAdapter
を使って、 ListView にコレクションを結びつく方法は以下のコードになる。
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_single_choice,
files);
listView.setAdapter(adapter);
List view の item のタッチ操作を取得するため、ListView オブジェクトに対して、setOnItemClickListener() メソッドにて、AdapterView.OnItemClickListener を設定し、onItemClick() メソッドの実装にて、必要な処理を行う。
public class ... extends ... implements AdapterView.OnItemClickListener {
...
listView.setOnItemClickListener(this);
...
public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
...
}
}
また、root directory と新しい directory の名前を File コンストラクタに渡すことにより、Nest Directory(ネスト ディレクトリ)を作成したり、内部ディレクトリを開いたりすることができる。
File directory = getFilesDir();
File file = new File(directory, filename);
「ファイルの中身を読み込む」の説明を参考に、以下の内容を実施せよ。
![]() |
![]() |
File オブジェクトをFileReaderの生成に用いる方法。
FileReader fr = new FileReader(file);
ストリームを使用してファイルにアクセスすることもできる。ファイルをストリームとして読み取るには、次のように openFileInput() を使用する。
FileInputStream fis = openFileInput("myfilename.txt");
InputStreamReader inputStreamReader =
new InputStreamReader(fis, StandardCharsets.UTF_8);
注: インストール時にストリームとしてファイルにアクセスする必要がある場合は、ファイルをプロジェクトの /res/raw ディレクトリに保存する。それらのファイルを開くには、openRawResource() を使用し、R.raw プレフィックスを付けたファイル名をリソース ID として渡す。このメソッドから返される InputStream を使用して、ファイルを読み取ることができる。元のファイルに書き込むことはできない。
File reader および、input stream reader から、ファイルの中身を抽出するため、BufferedReader class を用いる。通常の file reader や input stream reader は Byte 配列としてファイルを読み込むのに対して、BufferedReader オブジェクトは文字単位および、文字列(行)単位で読み込むことできます。
try {
BufferedReader reader = new BufferedReader(inputStreamReader);
int moji = reader.read(); //一文字を読む
String line = reader.readLine(); //一行を読む
} catch (IOException e) {
// Error occurred when opening raw file for reading.
}