Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Android編)

---
# :book: Flutterの記事を整理し本にしました :book:
https://zenn.dev/kazutxt/books/flutter_practice_introduction

* <font color="red"><b>本稿の記事を含む様々な記事を体系的に整理し本にまとめました</b></font>
* 今後はこちらを最新化するため、<font color="red"><b>最新情報はこちらをご確認くださ</b>い</font>
* 10万文字を超える超大作になっています(笑)


---

# 注意
<font color="red"><b>本記事の内容は古くなりましたので、下記の新しい内容をご参照下さい</b></font>

* [Flutterで GooglePlay(Android) / AppStore(iOS) / FirebaseHosting(Web) にリリースする方法まとめ](https://qiita.com/kazutxt/items/f463441840292f0bbe5b)

---

# はじめに
* 最近やたらとFlutterにハマっていていよいよリリースできる状態になってきたので、具体的なリリース方法を整理したいと思います。
* 何かと注目のFlutterですが、同じソースで、Androidアプリ、iOSアプリ、Webアプリと3刀流で同じものをベースにというのも地味に感動
    * ↓がFlutterで始めるアプリ開発というサイトからの引用なのですがよくできていると思います。
    * firebaseもホスティングやその他の機能を持っていて、良い感じに連携してくれます。
        * さすがGoogle!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/666841f3-4fea-6ffc-2b36-2e7b12abbf6b.png)

# 記事の概要/前提
* Android編では、作ったアプリをGooglePlayに登録するまでを行います。
* アプリの作り方そのものではありません。
* 何らかのアプリが出来上がり、それをリリースするまでを紹介しています。
* 写真が少なくてすみません。。。

# 関連記事
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Android編)](https://qiita.com/kazutxt/items/66d52d78ec1349f2b249)
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Webアプリ編)](https://qiita.com/kazutxt/items/e86bec4d335488a8baa0)
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(iOS編)](https://qiita.com/kazutxt/items/0ea523d5ccf647c144ad)


# 参考文献
https://flutter.dev/docs/deployment/android
https://www.flutter-study.dev/create-app/publish-android/

# Androidアプリリリースへの道

## 1. GooglePlayConsoleのアカウントを作る
* https://play.google.com/apps/publish/signup/
* GooglePlayConsoleにアカウントを登録して、登録料25$を払います
* 支払いが終わると、GooglePaymentsから「Google: ありがとうございます」というメールが来ます
* アカウントが承認されると「Google Play へようこそ」というメールが来ます。自分の場合は↑から5日後でした

## 2. アイコンの設定
* アプリのランチャーアイコンを作ります
* 公式にも紹介されていますが、flutter_launcher_icon というプラグインを使うことが推奨されています。
* 過去にやり方を記事にしていますので、詳細はこちらをご参照ください
    * https://qiita.com/kazutxt/items/023b6ef94d095a694a60#%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3

## 3. 署名
* こちらも公式にコマンドが載っています。mac/linuxは↓になります。

`keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key` 

* appにkey.propertiesでパスワードとファイルを指定します
    * .gitignoreにすでに書かれているので、コミットはされないように配慮されているようです

``` key.properties
storePassword=<password from previous step>
keyPassword=<password from previous step>
keyAlias=key
storeFile=<location of the key store file, such as /Users/<user name>/key.jks>
```

## 4. 署名の組み込み
* 作った証明書をビルド時に組み込まれるようにします。

``` app/build.gradle
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
 // androidブロックの前に入れる
android {
      ...
 }
```

``` app/build.gradle
// buildTypesの前に入れる
signingConfigs {
  release {
    keyAlias keystoreProperties['keyAlias']
    keyPassword keystoreProperties['keyPassword']
    storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
    storePassword keystoreProperties['storePassword']
    }
}
   //debugからreleaseに変える
   buildTypes {
       release {
           signingConfig signingConfigs.release
       }
   }

```

## 5.アプリ名をつける
* アプリ名をlabel部分に入れる
* 日本語も可能でアプリアイコンの下に表示される

``` appdir/android/app/src/main/AndroidManifest.xml

<application
    android:label="XXX"
    <!--中略-->
>
```
* 必要なパーミッションが必要なとき(カメラとかGPSとか)は追記する

## 6.ビルド構成の確認
``` appdir/android/app/build.gradle
defaultConfig{
    applicationId "XXX"
    minSdkVersion XXX
    targetSdkVersion XXX
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
    multiDexEnabled true // メソッド数が64Kを超えた場合に起きる問題の回避用(2021/3/3 追記)
}
```

* com.exampleだとNGのようなので、自分のドメインに変更
* targetSdkVersionが28だとセキュリティ上NGと言われたので、29に変更　
* `multiDexEnabled true`は直接は関係ないのですが、メソッド数が64Kを超えた場合に起きる問題の回避用になります(2021/3/3 追記)

## 7.ビルドする
* アプリバンドル形式とapk形式があるようで、前者が新しく推奨方式とのこと
    * apkはもう古いのか。。。

`flutter build appbundle` で作成できる

*  出力先は、appdir/build/app/outputs/bundle/release/app.aab

## 8. 資材がインストールできることを確認
https://github.com/google/bundletool/releases/latest からbundletoolをダウンロードしてきます

```
java -jar bundletool-all-1.2.0.jar build-apks \
 --bundle=<app dir>/build/app/outputs/bundle/release/app-release.aab \
 --output=app.apks \
 --ks=keystore.jks \
 --ks-pass=pass:store_password \
 --ks-key-alias=key-alias \
 --key-pass=pass:key_password
```
keystore.jksがあるフォルダで実施し、同フォルダに出力。パスワードは直書き・・・file:でファイルも指定できます

出来上がったでインストールします。

```
java -jar bundletool-all-1.2.0.jar install-apks --apks=app.apks
``` 
* adbコマンドが通るようにパスを通しておく必要があります。
* androidをデバッグモードにし、USB接続し、デバイスが認識できるようにしておく必要があります。
    * スマホは設定から開発オプションを変える必要があります。


## 9.公開
* アプリの作成
    * Google Play Console > すべてのアプリ > アプリを作成
    * アプリ名、デフォルトの言語、アプリ/ゲーム、無料/有料、申告を選択肢、アプリを作成をクリック
        * 特段難しい要素はないと思います。

* 初期設定
    * アプリのアクセス権
    * 広告
    * コンテンツのレーティング
    * ターゲットユーザーおよびコンテンツ
    * ストアの設定
    * アプリの言語、説明、アイコン、フューチャーアイコン、スクリーンショット
        * アイコンやフューチャーアイコンはここで登録します。
            * フューチャーアイコンは1024×500の横長のバナーっぽいやつです
        * スクリーンショットは2枚以上必要です。
* リリース
    * 国や地域の選択
    * リリースするappbundleをアップロード
    * リリースバージョン、リリースノート記述
    * 警告でネイティブコードが含まれ、デバッグシンボルがアップロードされていませんと出ますが、警告なのでリリースはできるようです
    * 製品版としての公開を開始をクリックします
    * 審査中になれば、OKです。

## 10.Google Playでの公開
* 審査には1週間程度かかるようです。
    * コロナ禍になってから、更に伸びることが示唆されています
    * 今回のアプリは決して複雑で大きいものではありませんでしたが、まずまず時間がかかりました。
* 審査後、公開のステータスとなります。
    * 公開のステータス管理などをしていない限りは、審査が終わり次第公開されます
    * GooglePlayで表示のリンクがでて、DL可能な状態になりますが、GooglePlayでの検索でヒットするようになるにはさらに1日～2日程度の時間がかかるようです。
    * また、アプリ名や開発者名で直接検索しても1番最初に出るわけではないので、スクロールして確認してください。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/aafc7e5e-b25f-978f-8793-7a6c874b8e23.png)