【ReactNative】ExpoでAndroidのPermissonを設定する

# はじめに

Expoのアプリを利用して開発をしていると権限回りはすべて許可された状態になりがちです。
開発中はいいのですが、いざリリースをしようとするとアップロード時に何故バックグラウンドで位置情報を使うのか申請が必要だったり、GooglePlay上でユーザー不用意に情報を取得しているアプリとみなされてしまうなどの問題が発生します

基本的には公式の[ドキュメント](https://docs.expo.io/versions/latest/config/app/)通りではあるのですが、日本語訳されていないのと各パーミッションについての説明がされていないためわかりにくいです
Androidのパーミッションはあまり詳しくないため、基本的に１つずつ調べて概要をまとめますが、説明が正確じゃないなどあれば編集リクエストいただけると助かります

こちらは2020/11/23現在のドキュメントを基準にしています

# 設定方法
Expoの設定を記載する`app.json`に下記の設定を追記します（permissions以外の項目は省略しています）


```
{
  "expo": {
    "android": {
      "permissions": [
        "CAMERA",
        "READ_EXTERNAL_STORAGE",
        "WRITE_EXTERNAL_STORAGE"
      ]
    }
  }
}
```
今回はカメラへのアクセスと外部ストレージの読み込み、書き込みの権限を要求しています
`permissions`は空配列にすることも可能で、その場合はプライバシーポリシーが不要になります
ただし、下記の機能はPermissionsの設定にかかわらず、Expoでビルドする限り常時利用可能です

* インターネットからのデータの受信
* ネットワーク接続の表示
* 完全なネットワークアクセス
* オーディオ設定の変更
* デバイスがスリープしないようにする

`permissions`を設定しなければ、設定可能なすべての権限を要求します

# 各権限項目の詳細

## Androidの共通の権限
* **ACCESS_COARSE_LOCATION**
    * 街・区レベルの位置情報を取得したい時に必要
* **ACCESS_FINE_LOCATION**
    * ACCESS_COARSE_LOCATIONよりも精度の高い正確な位置を取得したい時に必要
    * [Androidのドキュメント](https://developer.android.com/training/location/permissions?hl=ja)によるとBLE(Bluetooth Low Energy)を使う際にも必要みたいです
* **ACCESS_BACKGROUND_LOCATION**
    * バックグラウンドでの位置情報を取得する場合に必要
    * バックグラウンド位置情報アクセスを利用する場合は[GooglePlayでリリースする前に承認が必要になります](https://support.google.com/googleplay/android-developer/answer/9799150?hl=ja)
* **CAMERA**
    * アプリ内で[カメラ](https://docs.expo.io/versions/latest/sdk/camera/)を利用する場合に必要
* **RECORD_AUDIO**
    * アプリケーションで録音機能を利用する場合に必要
* **READ_CONTACTS**
    * 電話帳の読み取りに必要
    * 下記のWRITE_CONTACTSと合わせて、機能上不要なのに許可しているとマルウェアかと疑われやすいです
* **WRITE_CONTACTS**
    * 電話帳の書き込みに必要
* **READ_CALENDAR**
    * カレンダーの読み取りに必要
* **WRITE_CALENDAR**
    * カレンダーの書き込みに必要
* **READ_EXTERNAL_STORAGE**
    * 外部ストレージの読み込みに必要
* **WRITE_EXTERNAL_STORAGE**
    * 外部ストレージの書き込みに必要
* **USE_FINGERPRINT**
    * 指紋データを取得する場合に必要
    * ただし、APIレベル28では非推奨になっているらしく、より汎用的なUSE_BIOMETRICを推奨されているようです
* **USE_BIOMETRIC**
    * デバイスでサポートされている生体認証モダリティを取得する場合に必要
    * 指紋データもこちらに含まれるようです
* **WRITE_SETTINGS**
    * Androidのシステム設定を読み書きできるようにする場合に必要
* **VIBRATE**
    * バイブレーション機能を使用する場合に必要
* **READ_PHONE_STATE**
    * 現在のセルラーネットワーク情報や通話ステータスなどを含む電話の状態への読み取りに必要
* **com.android.launcher.permission.INSTALL_SHORTCUT**
    * Android 7.1以前でホーム画面にショートカットを追加する場合に必要
    * Anrdoid 8以降は変更されており、新しい方法では権限追加なしでショートカットの追加が可能なようです

## Google提供のライブラリ向け（すべて非推奨）
* **com.google.android.c2dm.permission.RECEIVE**
    * プッシュ通知をGoogleCloudMessageing(CGM)をつかって実装する場合に必要
    * 現在はGCMではなくFGM(Firebase Cloud Messaging)の利用が推奨されているため、新規でプッシュ通知を利用する場合は不要です
* **com.google.android.gms.permission.ACTIVITY_RECOGNITION**
    * Activity Recognition APIを利用する場合に必要
* **com.google.android.providers.gsf.permission.READ_GSERVICES**
    * 古いGoogleMapのAPIを組み込む場合に必要だったようです
    * Google Maps Android API v2以降は不要になりました

## 特定のデバイス・アプリケーション向け
情報が少なく公式の情報ソースがないものも多いため、参考までに
iOSで存在するバッジ機能に類似した機能が、独自ランチャーに組み込まれている場合に要求される場合が多いみたいです
許可内容については設定名からの推測になるため、対象となるアプリケーション or メーカーをまとめておきます

* **Apex Launcher**
    * com.anddoes.launcher.permission.UPDATE_COUNT
    * com.android.launcher.permission.INSTALL_SHORTCUT
* **HTC**
    * com.htc.launcher.permission.READ_SETTINGS
    * com.htc.launcher.permission.UPDATE_SHORTCUT
* **Solid Launcher**
    * com.majeur.launcher.permission.UPDATE_BADGE
* **Samsung**
    * com.sec.android.provider.badge.permission.READ
    * com.sec.android.provider.badge.permission.WRITE
* **Sony**
    * com.sonyericsson.home.permission.BROADCAST_BADGE