※2021年11月追記あり
Androidでのファイル読み書き方法は、任意のディレクトリのファイルを対象と出来るJavaのFileOutputStream/FileInputStream を使う方法と、アプリケーションのdataディレクトリ内のファイルしかアクセスできないopenFileOutput/openFileInputを使う方法がある。
作成したサンプルプログラムの画面
プログラムの画面設計と共通部分
MainActivity.java
package com.example.android_file_test_1; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBar; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.os.Build; import android.os.Environment; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Button; import android.widget.Toast; import android.view.View.OnClickListener; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.IOException; public class MainActivity extends ActionBarActivity implements OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // システムで規定されているディレクトリ一覧を文字列strに格納 String str = ""; str = "SD Card = " + Environment.getExternalStorageDirectory() + "\n"; str = str + "SD Card Status = " + Environment.getExternalStorageState() + "\n"; str = str + "Cache = " + getCacheDir() + "\n"; str = str + "File = " + getFilesDir() + "\n"; str = str + "Data = " + Environment.getDataDirectory() + "\n"; str = str + "Download = " + Environment.getDownloadCacheDirectory() + "\n"; LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); setContentView(layout); // 書き込み、読み込みのボタン定義 Button button = new Button(this); button.setText("ファイル書き込み(java)"); button.setId(0x1001); layout.addView(button); button.setOnClickListener(this); button = new Button(this); button.setText("ファイル読み込み(java)"); button.setId(0x1002); layout.addView(button); button.setOnClickListener(this); button = new Button(this); button.setText("ファイル書き込み(android)"); button.setId(0x1003); layout.addView(button); button.setOnClickListener(this); button = new Button(this); button.setText("ファイル読み込み(android)"); button.setId(0x1004); layout.addView(button); button.setOnClickListener(this); // テキスト文字列表示領域(最初は、システムdir一覧を表示する) TextView text = new TextView(this); text.setId(0x1005); text.setText(str); layout.addView(text); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @Override public void onClick(View v) { // ボタンのID番号で処理振り分け switch(v.getId()){ case 0x1001: FileWrite(); Toast.makeText(MainActivity.this, "書き込みました", Toast.LENGTH_LONG).show(); break; case 0x1002: FileRead(); Toast.makeText(MainActivity.this, "読み込みました", Toast.LENGTH_LONG).show(); break; case 0x1003: FileWriteAndroid(); Toast.makeText(MainActivity.this, "書き込みました", Toast.LENGTH_LONG).show(); break; case 0x1004: FileReadAndroid(); Toast.makeText(MainActivity.this, "読み込みました", Toast.LENGTH_LONG).show(); break; } } // 〜 ここに、下記に示すファイル読み書きのクラス関数が来る 〜 }
アクセス権限を得る
SDカードにアクセスするために、次の設定も行う。
Android 5以前の場合(Build.VERSION.SDK_INT < 23)
MainActivity.java
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android_file_test_1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.android_file_test_1.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
または、画面上で編集することも出来る(※ Android StudioではGUIによる権限編集はできない)
Android 6以降の場合(23 <= Build.VERSION.SDK_INT)
Androidの権限要求ダイアログ(SDK 23以降)
MainActivityでの権限要求処理部分のみ抜粋
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_PERMISSION = 0x100;
/*
権限リクエストのダイアログでユーザが許可・拒否を選択後の処理
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
// パーミッション取得が拒否された場合、デバッグログに表示する
for(int i=0; i<permissions.length; i++){
if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
Log.i("PERMISSION", "Permission Denied : " + permissions[i].toString());
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
/*
MainActivity作成時に1回処理される
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 外部記憶(SDカード)への書き込み権限の状況を得る
int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
// 書き込み権限が無い場合、権限を得るダイアログを表示する
if(permission != PackageManager.PERMISSION_GRANTED) {
// 書き込み・読み込みの2つの権限を要求する
ActivityCompat.requestPermissions(this,
new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE },
this.REQUEST_PERMISSION);
}
// ~ ここに各種処理(ボタンを押したときの処理)などが記述されている
}
}
SDカード上のファイルに書き込む
バッファ無しでの書き込み例
// SDカード等、任意のディレクトリに書きこむ
private void FileWrite() {
try{
// 外部ディスクに書き込み権限があるかチエック(SDK 23以降対応)
int permission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permission == PackageManager.PERMISSION_GRANTED) {
// SDカード上のファイルの「絶対パス」フルパス名を作成
String filename = Environment.getExternalStorageDirectory().getPath() + File.separator + "test.txt";
// ファイルを開く(FileOutputStreamはパス名に「/」を含むことができる)
OutputStreamWriter writer = new OutputStreamWriter(
new FileOutputStream(filename, true), "utf-8"
);
// ファイルに書き込み
writer.write("サンプル文字列".toString());
writer.flush();
writer.close();
}
else{
Log.i("PERMISSION", "Permission Denied : WRITE_EXTERNAL_STORAGE");
}
} catch(Exception e){
Log.i("FILE ACCESS", e.toString());
}
}
バッファ有りでの書き込み例
// SDカード等、任意のディレクトリに書きこむ
private void FileWrite() {
try{
// 外部ディスクに書き込み権限があるかチエック(SDK 23以降対応)
int permission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permission == PackageManager.PERMISSION_GRANTED) {
// SDカード上のファイルの「絶対パス」フルパス名を作成
String filename = Environment.getExternalStorageDirectory().getPath() + File.separator + "test.txt";
// ファイルを開く(FileOutputStreamはパス名に「/」を含むことができる)
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(filename, true), "utf-8"
));
// ファイルに書き込み
writer.write("サンプル文字列".toString());
writer.flush();
writer.close();
}
else{
Log.i("PERMISSION", "Permission Denied : WRITE_EXTERNAL_STORAGE");
}
} catch(Exception e){
Log.i("FILE ACCESS", e.toString());
}
}
SDカード上のファイルから読み込む
private void FileRead() { String filename = Environment.getExternalStorageDirectory() + "/test.txt"; try { FileInputStream fileInputStream = new FileInputStream(filename); BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream,"UTF-8")); String str = ""; String strTemp; while ((strTemp = reader.readLine() ) != null){ str = str + strTemp + "\n"; } TextView text = (TextView)findViewById(0x1005); text.setText(str); reader.close(); fileInputStream.close(); } catch (FileNotFoundException e) { } catch (IOException e) { } }
ユーザディレクトリを指定するには
Download, Pictures などのユーザディレクトリはどのように指定すればよいのか...DOWNLOADディレクトリを得る場合
String filename = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + File.separator + "test.txt";
Androidのアプリケーションディレクトリ下のファイルに書き込む
バッファ無しでの書き込み例
// SDカード等、任意のディレクトリに書きこむ
private void FileWrite() {
try{
// ファイル名(/data/data/com.example/file 以下のファイル名)
String filename = "test.txt";
// ファイルを開く(openFileOutputはパス名に「/」を含むことができない)
OutputStreamWriter writer = new OutputStreamWriter(
openFileOutput(filename, Context.MODE_PRIVATE|Context.MODE_APPEND), "utf-8"
);
// ファイルに書き込み
writer.write("サンプル文字列".toString());
writer.flush();
writer.close();
} catch(Exception e){
Log.i("FILE ACCESS", e.toString());
}
}
バッファ有りでの書き込み例
// SDカード等、任意のディレクトリに書きこむ
private void FileWrite() {
try{
// ファイル名(/data/data/com.example/file 以下のファイル名)
String filename = "test.txt";
// ファイルを開く(openFileOutputはパス名に「/」を含むことができない)
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
openFileOutput("test.txt", Context.MODE_PRIVATE|Context.MODE_APPEND)
));
// ファイルに書き込み
writer.write("サンプル文字列".toString());
writer.flush();
writer.close();
} catch(Exception e){
Log.i("FILE ACCESS", e.toString());
}
}
Androidのアプリケーションディレクトリ下のファイルから読み込む
private void FileReadAndroid() { String filename = "test.txt"; try { FileInputStream fileInputStream = openFileInput(filename); BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream,"UTF-8")); String str = ""; String strTemp; while ((strTemp = reader.readLine() ) != null){ str = str + strTemp + "\n"; } TextView text = (TextView)findViewById(0x1005); text.setText(str); reader.close(); fileInputStream.close(); } catch (FileNotFoundException e) { } catch (IOException e) { } }