ReactNative+ExpoでAndroidアプリをビルドする

ReactNative+ExpoでAndroidアプリをビルドする場合にいくつか面倒なことがあったので、備忘録を残します。


# ReactNativeとは
![1280px-React-icon.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275351/996bf1d4-2f96-d612-dfcd-93db90c1156a.png)

[ReactNative](https://reactnative.dev/)はFacebookが開発したモバイルアプリケーションフレークワークです。
Reactの機能をネイティブアプリに使うことができ、マルチプラットフォーム対応で、JavascriptでiOSアプリとAndroidアプリを作ることができます。

Javascriptを使うモバイルアプリケーションフレークワークはMonacaやCORDOVAなどいくつかありますが、ReactNativeの私的なメリット・デメリットは下記です。

### メリット
**・ネイティブアプリ並の速さが出る**
　ブリッジモジュールを介して、OSのネイティブな機能を使っているので速い（らしい）
　ただ、ハードウェア性能と該当OSのJavaScriptインタプリタの性能に依存する（らしい）ので、端末依存の面も大きい
**・独自のネイティブモジュールを実装することができる**
　※カメラや通知などを行うネイティブモジュールはデフォルトで揃っています
**・ReactやReact ReduxなどのReactの機能を使うことができ、React開発者は学習コストが少なくすむ**

### デメリット
**・AndroidJava＋AndroidStudioやSwift+Xcodeを使ったアプリ開発よりも自由度が低い**
　これは他のフレークワークも当てはまりますが、色々とビルドが面倒だったり、最新のAndroid／iOSに対応していなかったりします。
**・独自のネイティブモジュールを作るには、AndroidJava／Swiftの知識が必要**

といったところです。大規模なアプリの開発なら、素直にAndroidJava＋AndroidStudioとSwift+Xcodeを使った方がいいです。


# Expo
![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275351/31c25858-5327-5d80-dd29-2aae50ad94dc.png)

[Expo](https://docs.expo.io/)は、ReactNativeの開発支援ツールです。
ReactNative+Expoによって、ビルドやエミュレータ・実機での確認が楽になります。

Expoにもデメリットはありますが、ここは[以前Expoを使った開発について書いた記事](https://qiita.com/khara_nasuo486/items/cc1c3cf748e868d2e754)がありますので、
読んでいただけますとありがたいです。
他者様の記事も参考にしてみてください。

前置きはここまで、ここからAndroidアプリのビルドに入ります。


# Androidアプリのビルド

ReactNative+Expoのビルドの設定は、app.jsonで行います。
AndroidManifest.xmlのようなものです。

```app.json
{
  "expo": {
    "name": ${アプリ名},
    "slug": ${アプリ名},
    "platforms": [
      "ios",
      "android",
      "web"
    ],
    "sdkVersion": "36.0.0",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
        "supportsTablet": true,
        "bundleIdentifier": ${開発者ドメイン}
    },
    "android": {
        "package": ${開発者ドメイン},
        "versionCode": 4,
        "permissions": []
    }
  }
}

```

カスタムした点だけ書きます。

### "sdkVersion"
ReactNativeのSdkVersionを指定します。2020年7月現在、ここを指定しないと、AndroidSdkVersionが28に指定されるため、2020年8月以降、アプリ非対応になります。
なお、expoのバージョンが古いと、そもそもAndroidSdkVersion29以上に対応できません。
expoやreact-nativeの更新は、

```
$ expo upgrade
```

で行えます。
参考に動作したアプリのバージョンを書きます。

```package.json
"dependencies": {
  "expo": "^37.0.0",
  "react": "16.9.0",
  "react-dom": "16.9.0",
  "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
  "react-native-web": "^0.11.7",
},
```

### "versionCode"

Androidアプリのリリースでは、同じバージョンコードのファイルをアップすることはできません。
VersionCodeを指定すると対応できます。

### "permissions"

この項目を指定しないでビルドすると、カメラやストレージを使用する設定になっています。そのため、使用しない設定にする必要があります。空カッコ（[]）で使用しない設定になります。
使用する場合は下記のように書きます。

```
"permissions": [
  "ACCESS_COARSE_LOCATION",
  "ACCESS_FINE_LOCATION",
  "CAMERA",
  "READ_EXTERNAL_STORAGE",
  "WRITE_EXTERNAL_STORAGE",
  "VIBRATE",
]
```


### ビルド

ApkファイルとAndroid App Bundleファイルは下記のコマンドで作れます。

ビルドでApkファイルを作成

```expo
$ expo build:android
```

ビルドでAndroid App Bundleファイル（最適化している）を作成

```expo
$ expo build:android --type app-bundle
```
![build.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275351/4c837e1e-1d02-ed4d-8dd3-88d1c9f4e15c.png)

特に理由がなければ、Android App Bundleファイルを作りましょう。
作ったファイルをアップロードしてリリース完了です。

Expoは便利ですね〜。