外部媒体に書込権限を付与するAndroidアプリ「StorageAgent」

先日、手持ちのAndroidタブレットに画像閲覧アプリ「Perfect Viewer」を導入してから気がついたのですが、microSDカード上のデータの削除ができない...。

使用タブレットは、Acerの"ICONIA A1-810"です。
だいぶ前にアップデートしていて、"Android 4.4.2"になっています。
※タブレットの詳細は、「携帯端末まとめ」をご覧ください

調べてみると、"Android 4.4"ではSDカードなど外部媒体への書き込みが制限されているようです。

Android 4.4の制限

なんで変わったの?

主な理由としては、セキュリティの向上だそうです。

何がいけなかったの?

  • 今までの問題点
    • 外部媒体に保存したファイルを保護する機能がない(暗号化などの機能がない)
    • WRITE権限"WRITE_EXTERNAL_STORAGE"があれば、別アプリからも参照可能
    • アプリがアンインストールされるとき、システムがファイルをクリーンアップできない
      (設定ファイルが外部媒体に残ってしまう)
    • READ権限"READ_EXTERNAL_STORAGE"が無かった(Android 4.4で追加)
      • つまり常にWRITE権限を付与していた...

確かに"Android 4.4"より前のバージョンでは、アプリが外部記憶領域にデータ書込を許可する権限"WRITE_EXTERNAL_STORAGE"を使わないアプリを探すほうが難しかったような。
(従来のWRITE権限はREAD権限も兼ねていたので、よく使うであろう"インターネットアクセス"権限と組み合わせればデータを送信することも可能ですし)。

改善点の概要

このようなことを受けて、"WRITE_EXTERNAL_STORAGE"の使用シーンを減らすための試みがなされました。
具体的には、以下の2点です。

  • Android 4.4での変更点
    • "外部記憶領域上のアプリケーションデータディレクトリ"は、権限不要でアクセス可
    • パスの中にパッケージ名が入っていれば、アプリをアンインストールした時、同時に当該ディレクトリが削除され、不必要なデータが端末上に残らない

つまり、当該アプリのデータディレクトリに対しては"WRITE_EXTERNAL_STORAGE"が不要になるので、「ユーザに権限の確認が不要になる」という訳です。

でも困る

セキュリティ向上はありがたい限りですが、そうはいってもmicroSDにデータを書き込みたい。
具体的にはデータを削除したい!

というのも、"Perfect Viewer"で画像閲覧している際に、不要な画像をその場で削除したいんですよ。
だいたい画像収集しているのは、業務外の夜中なので翌日になって見てみると「消そう」ということもしばしばあるので・・・。

対処法

対処法は2パターンあるようです。

root化

この現象は、設定ファイルのXMLを編集すると回避できるようなので、root化して作業すれば対応できそうです。

書込権限を付与するアプリを追加導入

他の用途で困っていないのに今更root化するのも何なので、今回はアプリで対応することにしました。

Google Playストアから「StorageAgent」を導入しました。

base on https://play.google.com/store/apps/details?id=net.amilab.StorageAgent&hl=ja

Android4.4(Kitkat)以降が稼働している場合でも、SDカードの場所へのコピー(移動)が可能です。

特に設定しなくても導入するだけで、"Perfect Viewer"からファイルの削除ができるようになりました。

おまけ

Android 5.0以降は上記作業は不要

外部媒体への書き込み機能の復活

アプリへの権限付与が細かく設定できるようになり、アプリ導入時にユーザが許可を与えると書き込みできるようになります。
ただし、アプリ側が対応している必要があります(さすがに有名どころはほぼ対応済みでしょう)。

WRITE権限について

base on https://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE

WRITE_EXTERNAL_STORAGE
added in API level 4

Allows an application to write to external storage.

Note: If both your minSdkVersion and targetSdkVersion values are set to 3 or lower, the system implicitly grants your app this permission. If you don't need this permission, be sure your targetSdkVersion is 4 or higher.

Starting in API level 19, this permission is not required to read/write files in your application-specific directories returned by getExternalFilesDir(String) and getExternalCacheDir().

Protection level: dangerous

外部ストレージ上のファイルの書き込み権限
APIレベル4で追加されました

アプリケーションが外部ストレージに書き込むことを許可します。

注:"targetSdkVersion"が3以下に設定されている場合、システムは暗黙のうちにアプリにこの許可を与えます。この許可が必要ない場合は、4以上であることを確認してください。

APIレベル19以降では、"getExternalFilesDir(String)"および"getExternalCacheDir()"によって返されたアプリケーション固有のディレクトリ内のファイルを読み書きするために、このアクセス権は必要ありません。

保護レベル:危険

*1 : targetSdkVersion : アプリのターゲットとなるAPIバージョン

APIバージョン

Android API code name
4.0 - 4.0.4 14, 15 Ice Cream Sandwich
4.1 - 4.3.1 16 - 18 Jelly Bean
4.4 - 4.4.4 19, 20 KitKat
5.0 - 5.1.1 21, 22 Lollipop
6.0 - 6.0.1 23 Marshmallow
7.0 - 7.1.2 24, 25 Nougat
8.0 - 8.1 26, 27 Oreo