Androidのファイル操作について

Androidのファイル操作はjavaのファイル操作とほとんど同様ですが、操作対象となるディレクトリを内部ストレージと外部ストレージというAndroidの作法に従う必要があります。

 

1 内部ストレージ

Androidがインストールされているストレージです。

ファイルサイズがそれほど大きくない場合はこちらを用いれば良いでしょう。

1.1 永続的なディレクトリfilesと一時的なディレクトリcache

Androidアプリケーションのファイル操作で使用する内部ストレージのディレクトリは以下のとおりです。

 

/data/data/[PackageName]/files 永続的に残るディレクトリ
/data/data/[PackageName]/cache 一時的なディレクトリ

 

/data/data/[PackageName]を使うよりもContextの次のメソッドを用いるべきです。

 

getFilesDir filesディレクトリまでのパス
getCacheDir cacheディレクトリまでのパス

 

1.2 サンプルコード

getFilesDirメソッドを利用したコードは次の通りです。

File file = new File(getFilesDir(), "hello.txt");
FileWriter fileWriter = null;

try {
  fileWriter = new FileWriter(file);
} catch (IOException e) {
  e.printStackTrace();
  return;
}

PrintWriter printWriter = new PrintWriter(new BufferedWriter(fileWriter));
printWriter.println("hello");
printWriter.close();

端末に接続してhello.txtにアクセスするとhelloという文字列が書かれていることを確認できます。

$ adb shell
# cat /data/data/com.hiroom2.samplefile/files/hello.txt
hello

2 外部ストレージ

AndroidがインストールされていないSDカード等のストレージです。

ファイルサイズが大きい場合はこちらを用いるべきです。

パーミッション追加とマウント確認が必要になります。

2.1 パーミッション

外部ストレージへのアクセスには次のパーミッションがあります。

 

WRITE_EXTERNAL_STORAGE 外部ストレージへの書き込み
READ_EXTERNAL_STORAGE 外部ストレージからの読み込み(将来的に必要)

 

AndroidManifest.xmlで次のようにパーミッションを指定します。

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.hiroom2.samplefile"
          xmlns:android="http://schemas.android.com/apk/res/android">

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

  <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".SampleActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>

        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
    </activity>
  </application>

</manifest> 

2.2 外部ストレージのマウント確認

外部ストレージへアクセスする前に外部ストレージがマウントされているかどうがを確認する必要があります。

getExternalStorageStateメソッドが返す戻り値で外部ストレージがマウントされているかを確認できます。

 

Environment.MEDIA_MOUNTED 書き込み可能でマウント済み
Environment.MEDIA_MOUNTED_READ_ONLY 書き込み禁止でマウント済み
上記以外 マウントされてない

 

2.3 外部ストレージのディレクトリ

Environmentクラスのstaticなメソッドは複数のアプリケーションの共有ディレクトリを取得できます。

 

Environment.getExternalStorageDirectory トップディレクトリ
Environment.getExternalStoragePublicDirectory アプリ共有ディレクトリ

 

Environment.getExternalStoragePublicDirectoryは Environment.DIRECTORY_PICTURES等を指定します。

 

Contextクラスのメソッドはアプリケーションのディレクトリを取得できます。

 

getExternalFilesDir filesディレクトリまでのパス
getExternalCacheDir cacheディレクトリまでのパス

 

getExternalFilesDirは引数が必要で、nullを指定した場合はfilesディレクトリを、Environment.DIRECTORY_PICTURES等を指定した場合はアプリケーション固有のPicturesディレクトリを取得できます。

2.4 サンプルコード

外部ストレージのディレクトリを取得するコードは以下のとおりです。

package com.hiroom2.samplefile;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class SampleActivity extends AppCompatActivity {

  private static final String gTag = "SampleActivity";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sample);

    Log.i(gTag, Environment.getExternalStorageDirectory().toString());
    Log.i(gTag, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString());
    Log.i(gTag, getExternalFilesDir(null).toString());
    Log.i(gTag, getExternalFilesDir(Environment.DIRECTORY_PICTURES).toString());
    Log.i(gTag, getExternalCacheDir().toString());
  }
}

実行結果は以下のようになりました。

I/SampleActivity: /storage/emulated/0
I/SampleActivity: /storage/emulated/0/Pictures
I/SampleActivity: /storage/emulated/0/Android/data/com.hiroom2.samplefile/files
I/SampleActivity: /storage/emulated/0/Android/data/com.hiroom2.samplefile/files/Pictures
I/SampleActivity: /storage/emulated/0/Android/data/com.hiroom2.samplefile/cache