⚙️

[React Native] Expo Android アプリの権限を全て削除する

2022/08/20に公開約6,500字

Expo SDK 45 から app.config 内で android.blockedPermissions が使えるようになり簡単にアプリの権限を削除できるようになりましたので、Expo アプリ作成直後の初期状態で追加されている権限を全て削除したいと思います。

https://docs.expo.dev/versions/v45.0.0/config/app/#blockedpermissions

アプリ作成

アプリを作成して、ビルドするために適当なパッケージ名を追加します。

$ npx create-expo-app TestApp
app.json
    "android": {
+     "package": "com.example.testapp",
      "adaptiveIcon": {

初期状態の権限を確認

まずは何も変更を加えずにアプリにどのような権限が追加されているのか確認します。

EAS で production ビルドを実行。

$ eas build --profile production --platform android

production ビルドでは aab が作成されるため、bundletool を使用します。

$ java -jar /bundletool-path/bundletool-all-1.11.0.jar dump manifest --bundle TestApp.aab

bundletool の dump manifest でアプリの AndroidManifest.xml を出力します。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"/>

development ビルドの場合

development ビルドの場合は apk ファイルが作成されるため権限確認の手順が若干異なります。

$ eas build --profile development --platform android

apk の場合は Android SDK の build-tools 内にある aapt2 を使用します。

$ /android-build-tools-path/aapt2 dump xmltree --file AndroidManifest.xml TestApp.apk

フォーマットが少し異なりますが、AndroidManifest.xml の内容を確認することができます。

A: http://schemas.android.com/apk/res/android:name(0x01010003)="android.permission.SYSTEM_ALERT_WINDOW" (Raw: "android.permission.SYSTEM_ALERT_WINDOW")
A: http://schemas.android.com/apk/res/android:name(0x01010003)="android.permission.INTERNET" (Raw: "android.permission.INTERNET")
A: http://schemas.android.com/apk/res/android:name(0x01010003)="android.permission.READ_EXTERNAL_STORAGE" (Raw: "android.permission.READ_EXTERNAL_STORAGE")
A: http://schemas.android.com/apk/res/android:name(0x01010003)="android.permission.VIBRATE" (Raw: "android.permission.VIBRATE")
A: http://schemas.android.com/apk/res/android:name(0x01010003)="android.permission.WRITE_EXTERNAL_STORAGE" (Raw: "android.permission.WRITE_EXTERNAL_STORAGE")
A: http://schemas.android.com/apk/res/android:name(0x01010003)="android.permission.ACCESS_WIFI_STATE" (Raw: "android.permission.ACCESS_WIFI_STATE")
A: http://schemas.android.com/apk/res/android:name(0x01010003)="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" (Raw: "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE")

アプリをインストールして確認

大半はユーザへの同意確認が不要な権限ですが、設定からアプリの詳細情報を表示すると何の権限を使用しているか確認できます。

権限を削除する

app.json の android.blockedPermissions に削除したい権限を全て追加します。

app.json
    "android": {
      "package": "com.example.testapp",
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
-     }
+     },
+     "blockedPermissions": [
+       "android.permission.INTERNET",
+       "android.permission.READ_EXTERNAL_STORAGE",
+       "android.permission.SYSTEM_ALERT_WINDOW",
+       "android.permission.VIBRATE",
+       "android.permission.WRITE_EXTERNAL_STORAGE",
+       "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"
+     ]
    },

権限を使用する場合は「VIBRATE」といった短い名称で書けますが、削除する場合は AndroidManifest に書かれた通りの「android.permission.VIBRATE」で書く必要があります。

削除後、再度ビルドを実行します。

$ eas build --profile production --platform android
or
$ eas build --profile development --platform android

アプリをインストールして確認

権限が全て無くなりました🎉

権限を削除した事による影響

当然ですが権限を削除することで Expo の機能が正しく動かなくなる場合もあります。

「android.permission.INTERNET」を削除した場合、当たり前ですがネットワークが使用できなくなるため development ビルドの場合開発サーバに接続できずアプリの起動に失敗してしまいます。

ビルド環境に応じて削除する

開発時は何かと権限が必要になってきます。Expo Go クライアントを使用するのも一つの手ですが、本番ビルドの時だけ権限が削除されるようにしてみたいと思います。

最初に追加した blockedPermissions を app.json から削除します。

app.json
    "android": {
    "package": "com.example.testapp",
    "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
-   },
-   "blockedPermissions": [
-       "android.permission.INTERNET",
-       "android.permission.READ_EXTERNAL_STORAGE",
-       "android.permission.SYSTEM_ALERT_WINDOW",
-       "android.permission.VIBRATE",
-       "android.permission.WRITE_EXTERNAL_STORAGE",
-       "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"
-   ]
+   }
},

app.json と同じ階層に新たに app.config.js を作成します。

app.config.js
export default ({ config }) => {
    if (process.env.EAS_BUILD_PROFILE == 'production') {
        return {
            ...config,
            "android": {
                ...config.android,
                "blockedPermissions": [
                    "android.permission.INTERNET",
                    "android.permission.READ_EXTERNAL_STORAGE",
                    "android.permission.SYSTEM_ALERT_WINDOW",
                    "android.permission.VIBRATE",
                    "android.permission.WRITE_EXTERNAL_STORAGE",
                    "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"
                ]
            }
        }
    } else {
        return config;
    }
};

process.env.EAS_BUILD_PROFILE にビルド時のプロファイル名が入っているため、production の時だけ blockedPermissions を追加するようにしました。

これで本番環境向けにビルドした時のみ権限を削除することができました。

Discussion

ログインするとコメントできます