●ファイル処理


■アプリケーション自身が使うファイルの読み書き

自分自身の設定をちょっと保存しておくという感じのものでしょうか。
自分自身以外からはアクセスできません。
誰でもアクセスできる通常のファイル読み書きは下の方にあります。

この方法で書き込んだファイルがアプリケーションどうしの通信に使えたのは過去の話です。
かつては使えたMODE_WORLD_READABLEやMODE_WORLD_WRITEABLEは新しい端末では動作しませんので注意が必要です。


▼ファイル書き込み

android.content.Context.MODE_PRIVATE の部分を、
android.content.Context.MODE_APPEND にするとファイルに追記されます。

try {
    java.io.FileOutputStream fos= getApplicationContext().openFileOutput("FILENAME", android.content.Context.MODE_PRIVATE);
    String str = "abcdefg";
    fos.write(str.getBytes());
    fos.close();
}catch(Exception e){
}

▼ファイル読み込み

try {
    java.io.FileInputStream fis = getApplicationContext().openFileInput("FILENAME");
    byte[] buffer = new byte[256];
    fis.read(buffer, 0, buffer.length);
    fis.close();
    String str = new String(buffer);
}catch(Exception e){
}

▼ファイル削除

try {
    java.io.File file = getApplicationContext().getFileStreamPath("FILENAME");
    if (file.exists()){
        file.delete();
    }else{
        t.setText("ファイルが見つかりません");
        t.show();
    }
}catch(Exception e){
}

■誰もがアクセスできる領域へのファイルの読み書き

いわゆる、パソコンなどのファイル読み書きと同じです。
通常の画像ファイルやテキストファイルなどの読み書きはこちらですね。

まずは権限を追加しないと動きません。
そこで、AndroidManifest.xmlファイルを開きます。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.myapplication">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"

赤文字の部分を追加して権限をアプリに与えます。
WRITE_EXTERNAL_STORAGEだと読み書きの権限があたえられます。
READ_EXTERNAL_STORAGEだと読み込みのみの権限があたえられます。
都合により使い分けてください。

しかし、Android6.0以降は、Dangerous Permissionのためこのままでは動きません。
アプリ起動後にユーザーに権限を許可してもらう必要があります。
対応するには
下の方を見てください。


▼書き込み先のパスの取得


外部公開領域(内部ストレージのパス)の取得には
android.os.Environment.getExternalStorageDirectory().getPath()

外部公開共有領域(内部ストレージのピクチャやダウンロードなどの共有ディレクトリ)の取得には
android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getPath()

引数として与えられているandroid.os.Environmentは環境変数を管理するクラスです。
ピクチャのディレクトリの取得には、Environment.DIRECTORY_PICTURESを引数に渡します。

((android.widget.Button)findViewById(R.id.button))
        .setOnClickListener(new android.view.View.OnClickListener() {
            public void onClick(android.view.View view) {
                android.widget.Toast.makeText(getApplicationContext(),
                        android.os.Environment.getExternalStorageDirectory().getPath()+"\n"+
                        android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getPath()+"\n"+
                        android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_PICTURES).getPath()
                        , android.widget.Toast.LENGTH_LONG).show();
            }
        });
試しに上のプログラムを走らせてみたところこのような結果になりました。




■外部公開領域のファイル操作

▼ディレクトリ作成

java.io.File dir = new java.io.File(android.os.Environment.getExternalStorageDirectory().getPath()+"/test");
if (!dir.exists()){
    dir.mkdir();
}

▼ディレクトリ削除

フォルダ内にあるファイルをすべて削除してからでないと削除できません。

java.io.File dir = new java.io.File(android.os.Environment.getExternalStorageDirectory().getPath()+"/test");
if (dir.exists()){
    dir.delete();
}

▼ファイル書き込み

try {
    java.io.File file = new java.io.File(android.os.Environment.getExternalStorageDirectory().getPath()+"/test.txt");
    java.io.FileWriter filewriter = new java.io.FileWriter(file);
    filewriter.write("test_text");
    filewriter.close();
}catch(Exception e){
    android.widget.Toast.makeText(getApplicationContext(),e.toString(), android.widget.Toast.LENGTH_LONG).show();
}

▼ファイル読み込み

try {
    java.io.File file = new java.io.File(android.os.Environment.getExternalStorageDirectory().getPath()+"/test.txt");
    java.io.FileReader filereader = new java.io.FileReader(file);
    StringBuffer sb=new StringBuffer();
    int c;
    while((c = filereader.read()) != -1){
        sb.append((char)c);
    }
    String str = sb.toString();
    android.widget.Toast.makeText(getApplicationContext(),str, android.widget.Toast.LENGTH_LONG).show();
}catch(Exception e){
    android.widget.Toast.makeText(getApplicationContext(),e.toString(), android.widget.Toast.LENGTH_LONG).show();
}

▼ファイル削除

try {
    java.io.File file = new java.io.File(android.os.Environment.getExternalStorageDirectory().getPath()+"/test.txt");
    if (file.exists()) {
        file.delete();
    }
    }catch(Exception e){
    android.widget.Toast.makeText(getApplicationContext(),e.toString(), android.widget.Toast.LENGTH_LONG).show();
}

▼ストリームでファイル書き込み

バイト単位での書き込みになります。
FileOutputStreamの最後の引数をtrueにすると追記モードになります。

try {
    java.io.FileOutputStream fos = new java.io.FileOutputStream(android.os.Environment.getExternalStorageDirectory().getPath()+"/test.txt",false);
    fos.write('a');
    fos.write('b');
    fos.write('c');
    fos.flush();
    fos.close();
    }catch(Exception e){
    android.widget.Toast.makeText(getApplicationContext(),e.toString(), android.widget.Toast.LENGTH_LONG).show();
}

▼ストリームでファイル読み込み

try {
    java.io.FileInputStream fis = new java.io.FileInputStream(android.os.Environment.getExternalStorageDirectory().getPath()+"/test.txt");
    java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(fis));
    StringBuffer sb=new StringBuffer();
    int i;
    while((i=br.read()) != -1 ){
        sb.append((char)i);
    }
    br.close();
    android.widget.Toast.makeText(getApplicationContext(),sb.toString(), android.widget.Toast.LENGTH_LONG).show();
    }catch(Exception e){
    android.widget.Toast.makeText(getApplicationContext(),e.toString(), android.widget.Toast.LENGTH_LONG).show();
}


■Dangerous Permissionに対応する

android6.0以前はインストールする段階で権限を取得できましたが、android6.0では実行時に権限を取得するように改良されました。
そのため、Android6.0以降は権限を取得するコードを書かないと例外が発生してしまい、このままでは動きません。
実行時に権限を取得するには次のようにする必要があります。

final int REQUEST_ID = 99;
void permission(String permission){
    //android version 6.0以上の場合は実行する必要がある
    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
        //権限が許可されてない場合には
        if (android.support.v4.app.ActivityCompat.checkSelfPermission(this, permission)!= android.content.pm.PackageManager.PERMISSION_GRANTED){
            //権限をリクエストする
            android.support.v4.app.ActivityCompat.requestPermissions(this, new String[]{permission}, REQUEST_ID);
        }
    }
}
//権限のリクエスト結果が返ってくる
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == REQUEST_ID) {
        if (grantResults[0] != android.content.pm.PackageManager.PERMISSION_GRANTED) {
            //権限が許可されなかった
            android.widget.Toast.makeText(getApplicationContext(), "権限が許可されませんでした\nアプリを終了します。", android.widget.Toast.LENGTH_LONG).show();
            //アプリを終了する
            finish();
            moveTaskToBack(true);
        }
    }
}
上の関数を追加した上で、権限を取得するタイミングで、次の関数をコールします

        //ファイル読み書きの権限をユーザーから取得する
        permission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
android6.0以上で関数をコールするとこのようなメッセージボックスが表示されます。



ファイル読み書きする前に権限を取得することによりandroid6.0以降でも例外が発生しなくなります。


▲トップページ > android