KitKatで仕様変更になった外部記憶装置へアクセス権限の記事を、11月にAndroid:KitkatのREAD_EXTERNAL_STORAGEと外部記憶領域というタイトルで書きました。
当時は、調査ほやほやで、「下位互換があるから、すぐには使用できない」という纏めになりましたが、きちんと下位互換も考えられていましたので、その解説になります。

maxSdkVersion

AndroidOS4.4(API Level19)での仕様変更により、WRITE_EXTERNAL_STORAGEパミッションが必要な機能はかなり減る事となりました。安心してユーザにアプリケーションを使用してもらうためにも、大変良い仕様変更ですが、今回の仕様変更はKitKatからです。この変更を既存のアプリに適用してしまうと、KitKat以前のアプリケーションでは、Security Exceptionが出てしまいます。
このため、新しくUses-PermissionにmaxSdkVersion属性が追加されました。
以前からあった、の属性のmaxSdkVersionと混同しないように注意してください。

以前からあった<uses-sdk>のmaxSdkVersion


<uses-sdk android:minSdkVersion="integer"
android:targetSdkVersion="integer"
android:maxSdkVersion="integer" />

新機能の<uses-permission>のmaxSdkVersion


<uses-permission android:name="string"
android:maxSdkVersion="integer" />

<uses-permission>ののmaxSdkVersionは、先のバージョンの違いによる問題を回避するために用意された物で、maxSdkVersionの値まで、このパーミッションを利用宣言し、それよりも大きいAPI Levelの環境では、パーミションの取得はしません。

上記のパーミッション宣言をした同じアプリを実際に作成し、Android 4.4と未満の環境にインストールして、設定画面からアプリケーションが取得している権限を表示してみました。

Android 4.3の画面

write_external_maxsdk4.2.png

Android 4.4の画面

write_external_maxsdk4.4.png

上記のように、同じプログラムにも拘わらず、4.3ではWRITE_EXTERNAL_STRAGE(USBストレージのコンテンツの変更または削除)が表示されていますが、Android4.4では、アプリが取得している権限は何もありません。

WRITE_EXTERBAL_STRAGEの下位互換

アプリケーションが、外部記憶領域上のアプリケーションディレクトリのみにアクセスしている典型的なアプリケーションは、以下のように記載ができます。


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

上記により、API Level18以下では、WRITE_EXTERBAL_STRAGEが利用宣言され、読み書き可能になります。またAndroid OS4.4(API Level19)以上では、WRITE_EXTERNAL_STRAGEの利用宣言はされません。

READ_EXTERBAL_STRAGGEの下位互換

次に、AndroidOS4.4でREAD_EXTERNAL_STRAGEだけを利用宣言するアプリは下位互換にどのような注意をしたら良いでしょうか
READ_EXTERNAL_STORAGEは、Android OS4.4で正式導入されました。API Level18以下では未知のパーミッションとなります。従ってmaxSdkVersionを指定しても、しなくても読み込み権限の取得は出来ませんので、SecurityExceptionは発生します。SecurityExceptionを発生しないようにするには以下の記載となります。


<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission
android:name="android.permission.READ _EXTERNAL_STORAGE"/>

上記により、API Level18以下では、WRITE_EXTERBAL_STRAGEが利用宣言され、読み込みアクセスが可能になります。(READ_EXTERBAL_STRAGEの利用宣言は無視されます)またAndroid OS4.4(API Level19)以上では、WRITE_EXTERNAL_STRAGEの利用宣言はされず、READ_EXTERNAL_STRAGEのみ利用宣言される事になります。(過去に導入期間とかありましたが、そのあたりは忘れたほうが良いかと思います)

参考資料

まとめと宣伝

このmaxSdkVersion情報ってあまり情報として出てこなくて、知らない人も多いと思います。書かなきゃ書かなきゃと思い続けて、前回の記事からずいぶんとたってしまいました….

勿論、このmaxSdkVersionに関する事項もアンドロイドアプリの脆弱性検知ツールTao RiskFinderには組み込まれており、WRITE_EXTERNAL_STRAGEの記載を見つけると、「maxSdkVersion属性入れたほうがいいよ」と教えてくれます。

ブログ内の関連する記事