概要
いろんな理由で社内などでライブラリを作ってmavenサーバーで公開して、それをアプリで参照したりとかってよくありますよね?
最初に結論ですが、そのときにライブラリ側でtargetSdkVersionが指定されていないと勝手にREAD_PHONE_STATE
とREAD_EXTERNAL_STORAGE
とWRITE_EXTERNAL_STORAGE
が追加されてしまいます
リリース前にGoogle Playで気づいたりすると再アップロードして確認などでリリースが翌日になったり、面倒なことになりがちです。(パーミッション変更がプルリクで検知できるともっといいですね)
どう調べたか
通常、mafniestに追加されているPermissionはAndroidManifest.xmlにあるMerged Manfiest
という項目をみて、そこで右クリックして Go to Declaration
することで、ライブラリを特定できます。
しかし、今回はメインのManfiest.xmlに飛ばされるのみで、原因がわかりませんでした。
ドキュメントより、ビルド中に生成される anifest-merger-[バリアント名]-report.txt
という項目を見れば良いことが分かったので、それを見てみました。
find . -name "manifest-merger*txt"
./app/build/outputs/logs/manifest-merger-[バリアント名]-report.txt
そこで以下のように吐き出されていました。
reason: library has a targetSdkVersion < 4
IMPLIED from .../src/main/AndroidManifest.xml:2:1-550:12 reason: library has a targetSdkVersion < 4
uses-permission#android.permission.READ_PHONE_STATE
IMPLIED from .../src/main/AndroidManifest.xml:2:1-550:12 reason: library has a targetSdkVersion < 4
uses-permission#android.permission.READ_EXTERNAL_STORAGE
IMPLIED from .../src/main/AndroidManifest.xml:2:1-550:12 reason: library requested WRITE_EXTERNAL_STORAGE
で以下のスタックオーバーフローにたどり着きました。
原因はなにか
ここからはちょっと興味の話なのですが、なぜtargetSdkVersion < 4だとパーミッションが追加されるのでしょうか?
ここにドキュメントがあります
https://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE
コードをたどっていくと、以下にたどり着きます。
https://android.googlesource.com/platform/tools/base/+/5521274ec220aea3f2b38d77dd34aeb463666da2
When importing libraries targeting past versions of the SDK with some
implied permissions (and possible other element types) into an
application targeting a newer SDK, we must explicitely declare those
implied permissions for the application to run correctly.
正しくアプリが動くために、新しいOSでは明示的に指定する必要があるパーミッションを全部追加しちゃうっぽいです。
そのパーミッションを追加するmergerのコードはここにあるようです
https://android.googlesource.com/platform/tools/base/+/2343d80f0fed536331249d0190294de0a9660358/build-system/manifest-merger/src/main/java/com/android/manifmerger/XmlDocument.java