先日、手持ちの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 4Allows 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 |