📱

Android:ファイルの保存先に注意する

2022/10/21に公開

はじめに

Androidアプリを作っている際に、ログファイルを端末に出力する必要がありました。
そして、そのログファイルを定期的に端末から取り出すことを考えていました。
その実装での気づきを本記事ではまとめます。

直面した問題と解決策

はじめはログファイルのアプリ固有の内部ストレージに保存するようにしていました。
しかし、端末にアクセスしファイルを取り出す際にファイルを見つけることができませんでした。
よくよく調べてみると、ログファイルの保存先をアプリ固有の内部ストレージしていました。そして、アプリ固有の内部ストレージでは、その保存場所は暗号化されてしまうためアクセスできないようです。

https://developer.android.com/training/data-storage/app-specific?hl=ja

よって、ログファイルの保存先を外部ストレージにすることで解決することができました。

内部ストレージに保存するサンプルコード

アプリ固有の内部ストレージに保存するサンプルコードは下記のようになります。
fileDirで保存先を指定すると、端末にアクセスした際、見えなくなるようです。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        appendLog("test")

    }

    fun appendLog(text: String?) {
	// ファイル名
        val fileName = "test.log"
        val filePath = File(fileDir, fileName)
        if (filePath.exists() == false) {
            Log.d("Log", "File not exists.")
            try {
                filePath.createNewFile()
            } catch (e: IOException) {
                Log.d("Log", e.toString())
            }
        }else{
            Log.d("Log", "File exists.")
        }
        try {
            Log.d("Log", "Success")
            val buf = BufferedWriter(FileWriter(filePath, true))
            buf.append(text)
            buf.newLine()
            buf.close()
        } catch (e: IOException) {
            Log.d("Log", e.toString())
        }
    }
}

外部ストレージに保存するサンプルコード

例えば、externalMediaDirsでディレクトリを指定するとログファイルを保存でき、端末からアクセスことができます。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        appendLog("test")
    }

    fun appendLog(text: String?) {
	// ファイル名
        val fileName = "test.log"
        // 外部ストレージ
        val mediaDir = externalMediaDirs.firstOrNull()?.let{
            File(it, "").apply { mkdir() }
        }
        val filePath = File(mediaDir, fileName)
        Log.d("Log", "filePath + $filePath")

        if (filePath.exists() == false) {
            Log.d("Log", "File not exists.")
            try {
                filePath.createNewFile()
            } catch (e: IOException) {
                Log.d("Log", e.toString())
            }
        }else{
            Log.d("Log", "File exists.")
        }
        try {
            Log.d("Log", "Success")
            val buf = BufferedWriter(FileWriter(filePath, true))
            buf.append(text)
            buf.newLine()
            buf.close()
        } catch (e: IOException) {
            Log.d("Log", e.toString())
        }
    }
}

おわりに

ファイルを保存して端末にアクセスし取り出せるようにしておくには、fileDirでディレクトリを指定せず、他の方法でディレクトリを指定したほうが良いでしょう。

Discussion