Ionic3でAndroidアプリを作る時に困ったいろいろ

最近(2018年10月)、Ionic3でAndroidアプリを作って、Play Storeで公開しました。

そこに至るにはいろいろと罠がありましたので、その記録を思い出せるうちに書いて残しておこうと思います。

困ったり解決したりする度に[ツイートしてた](https://twitter.com/agajo_tech)からいけるはず……！！

いくつかの記事にわけて、シリーズとしてまとめておきます。

なお、なんとかリリースできたアプリはこちら。日本語入力速度を測定します。→[フリックとローマジ 〜日本語入力スピード測定〜](https://play.google.com/store/apps/details?id=oka_ryunoske.work.flickromaji.app)

#シリーズ一覧

 - 小さめの奴をまとめて(この記事)
    - Ionicアプリにおける、色の指定のしかた
    - アプリのIDを初期値にしたまま端末に複数インストールすると上書きされる
    - iconとsplashの生成
    - android実機デバッグでエラーメッセージを見る
    - chromeでinspectタブを開いていると、端末ビルド時にno device error
    - play-services-ads v17 でAndroidManifest.xmlのmeta-data強制
 - [複数のファイルにまたがるPromiseの使い方](https://qiita.com/agajo/items/c466a4cdc3930dd43206)
    - IonicのNavControllerはProviderからは使えない
 - [プライバシーポリシー](https://qiita.com/agajo/items/e886afb7f5408141d1fc)
 - [admob-freeプラグインでのeventsオブジェクトの扱い](https://qiita.com/agajo/items/fd1e61e3325552aaefaf)
 - [firebaseプラグイン導入時のGoogle Play Services libraryのバージョン調整](https://qiita.com/agajo/items/8106eb0883d2d3c82add)
 - [Lazy Loading への対応](https://qiita.com/agajo/items/f13a2ae06c70fef8887b)
    - ngIf、ngForが動かない時


#Ionicアプリにおける色の指定のしかた

IonicやAngularのプロジェクトでは、PageやComponentごとに、htmlファイルとcssファイルが用意されて、このcssファイルに好きにデザイン情報を書き込めます。

(Ionicの場合はscssファイルになります。scssの詳細は省略)

でもアプリのデザインって、ページをまたぐ共通部分がたくさん出てきますよね。

そういうものは、PageやComponentごとに書くのではなく、別の場所に一括して記述します。

具体的には`src/theme/variables.scss`を編集します。使い方を2種類紹介しますね。

##$color変数の中身を変えて随所で使う

1つ目はこちら。

この中の`$colors`という変数の中身を、アプリ内でよく使う色で書き換えておきます。

それを個別のhtmlやscssファイルから呼び出します。

詳しくはこちら。

https://ionicframework.com/docs/theming/theming-your-app/

##色を指定している変数の初期値を上書きする

もう1つはこちら。

https://ionicframework.com/docs/theming/overriding-ionic-variables/

こちらに、Ionicアプリの各所の色を指定している変数がズラッと紹介されています。

その値を、`src/theme/variables.scss`に記述しなおして上書きすることで変更します。

例えば、`$background-color = #000000`とすると、アプリの背景が真っ黒になります。

上で作った`$color`変数も使えると思います。

厳密には、例えばios版なら背景色は`$background-ios-color`という変数に格納されているのですが、こいつの初期値が`$background-color`になっているので、`$background-color`を変えるだけでいいわけです。

`$background-color`は他にも何箇所かで参照されているので、個別に細かい調整をしたい場合はそれぞれの変数を個別に上書きすればOK。iosとandroidで背景色を微妙に変えたい場合、とかね。

かなりざっくり説明ですが次にいきます。

#アプリのIDを初期値にしたまま端末に複数インストールすると上書きされる

Ionicで複数のアプリを作っていて、android端末に`ionic cordova run android --device`でインストールした時に、

複数のアプリで同じidを使っていると、同じアプリとして認識されてしまい、上書きされてしまいます。

このidは、`config.xml`の`widget`タグの`id`属性に記述されています。初期値から変えておきましょう。

どうせリリースする時には、他のアプリと被らない一意な値を付けることになりますので、先にやっておけばいいですね。

詳しくはこちら。(Ionicに限らず、Androidアプリ一般について解説したページに飛びます。iOSについては未調査)

https://developer.android.com/studio/build/application-id?hl=ja

#iconとsplashの生成

iconはわかると思います。ホーム画面とかに表示される、アプリを表す画像ですね。

splashというのは、アプリ起動時のロード中に全画面表示される画像です。ロード画面ですね。

スマホアプリでは、これらを端末や表示条件に合わせていろんなサイズの奴を用意しなきゃいけないのですが、

Ionicではそれを元画像から一括生成するコマンドが用意されてます。便利〜。

1024px*1024pxの`resources/icon.png`と、2732px*2732pxの`resources/splash.png`を用意して、

`ionic cordova resources`コマンドでOKです。場合によっては`ionic cordova resources android`のように、対象OSを指定する必要や、`--force`オプションを指定する必要もあるかも。

ただし、この画像変換作業をサーバー側でやっているようで、利用するためにはIonicアカウントが必要になります。

なので、先にアカウントを作っておく必要がありますね。そして、`ionic cordova resources`を実行するとログインを要求されるので、指示に従います。

ちなみに有料のIonic Proアカウントである必要はないです。無料でOK。

詳しくはこちら。
https://ionicframework.com/docs/cli/cordova/resources/

##ちなみに

splash画像は上下や左右を対象に切られるので、何かモチーフを画像内に置く場合は中央に置くようにしましょう。それでも切られたらモチーフを小さくしましょう。

また、画像の作り方ですが、僕はGravit Designerというサービスを使ってブラウザ上で作成しました。

[Gravit Designer](https://www.designer.io/)

ちょっと前だったらAdobe Illustratorか、もしくはその代替ツールで有名なInkscapeをインストールしてたと思うんですが、便利な時代になったものです。

##用意する画像はこれで全てではない

アプリそのものが利用する画像はこれで十分なのですが、これをストアで公開する場合には、ストアで表示するための画像が追加で必要になります。

その点はAndroidでもiOSでも変わりません。

alphaチャンネルを抜いた画像を用意する必要があったりするので、お気をつけください。詳細はこの記事では省きます。

#android実機デバッグでエラーメッセージを見る

2つ紹介します。

##chromeのinspectタブ

アプリ内から発する`console.log("hogehoge");`の出力なんかを確認する方法です。

ブラウザで動かしてる場合は普通にブラウザのコンソールでいいんですが、実機で動かしてると、実機単体では見れません。

が、実機をUSBでつないで実機のUSBデバッグをオンにして、PCでchromeのアドレスバーに`chrome:inspect`と入力すると、デバッグ対象のデバイスを見つけることができます。

それをクリックすると、inspect画面が出ます。そこから実機上のアプリを操作したり、出力を確認したりできます。

##`adb logcat`

しかし、もし、そもそも実機でアプリが起動する前に落ちたりする場合は、chromeのinspectタブを使った方法は使えません。

android端末が直接出しているエラーメッセージを確認する必要があります。

その方法がこちら↓

https://developer.android.com/studio/command-line/logcat

要は、実機をUSBでつないでUSBデバッグをオンにして、PCから`adb logcat`というコマンドを実行すればいいんですが、この`adb`は最初からPCに入ったりはしてません。

Android Studioに付属しているもので、`platform-tools/`に入ってます。

じゃあ`platform-tools/`はどこにあるの、というと、Android Studioを起動してSDK Managerを開くと上の方にsdkの場所が書いてあり、その中にあります。

Mac OS Xを使っている人は多分↓のような感じになります。

`~/Library/Android/sdk/platform-tools/adb logcat`

実行すると、リアルタイムにメッセージが表示され続けるので、その状態でアプリを起動して該当エラーを引き起こしたあと、logcatは`Ctrl + c`とかで止めちゃって、ゆっくりメッセージを探しましょう。

#chromeでinspectタブを開いているとno deviceエラー

chromeでinspectタブを開いている状態で`ionic cordova run android --device`を実行すると、`no device found`というエラーが出ます。

なんかがバッティングして、デバイスの検出ができなくなるんですかね。多分。

タブを閉じてからもう一回やりましょう。そのあとまたinspectタブを開き直す分には問題ないです。


#play-services-ads v17 でAndroidManifest.xmlのmeta-data強制

(この項目は、これから開発する人には恐らく関係してこないので、読み飛ばしていただいてもOKです)

僕が開発をしていた2018年10月5日、ちょうどこの`play-services-ads v17`のアップデートが行われました。→ https://developers.google.com/android/guides/releases#october_5th_2018

結果、このplay-services-adsを使う人(≒AdMobを使う人)はAndroidManifest.xmlに追加の記述が強制になり、それを怠るとアプリが起動できなくなりました。

僕からしたら、ある日突然「何もしてないのに動かなくなった」という事態です。非常に困りました。

で、上記の`adb logcat`の方法でエラーメッセージを確認して、原因がこのアップデートにあることを突き止めたのですが

この「AndroidManifest.xmlへの追加の記述」が、できないんですね。

Ionicではアプリをビルドする時に`ionic cordova run`を実行しますが、この時に AndroidManifest.xml は自動で生成されます。

つまり、この自動生成ロジックをいじらないと修正できないわけで、非常に困りました。

結局どうしたのかと言うと、利用していた[cordova-plugin-admob-freeのgithub](https://github.com/ratson/cordova-plugin-admob-free)に、この事態に対応するためのissueが出ていて、その議論の中に出ていた方法を使って解決しました。

僕のような末端のプラグインユーザーも、ここまで見に行かないと解決できないケースが発生しうるってことですね。勉強になりました。

なお、現在は、この問題に対処するプルリクエストがマージされ、既に解決されているので、同様の問題にぶつかる人はいなくなると思われます。

(現在と言っても、この該当アップデートがなされてから1週間しか経ってない(2018年10月12日)わけで、僕はこのわずか1週間の間に開発作業をしてたからこの問題にぶつかったんですね…。)

[Ionicの解説](https://ionicframework.com/docs/native/admob-free/)はちょっと不親切なので、インストール時は[プラグイン本体のgithub](https://github.com/ratson/cordova-plugin-admob-free)も見たほうが良さそう。

プラグインインストール時に`--variable`オプションを指定する必要があるようですよ。

#おわりに

この記事は以上です。軽めの奴をバーーッとまとめて扱ってみました。次からは、もう少し重めの奴を個別に扱っていきます。