ArduinoからGoogle Cloud Messaging(GCM)を使う

やりたいこと

ArduinoからGoogle Cloud Messaging(以下「GCM」)を叩いて、Android端末にメッセージを送ってみたい。

要件的なもの

・GCMメッセージを送るAndroid端末(以下「端末」)は2台。(device1, device2とする。1台しかない場合はdevice1の値をdevice2に使いまわす。)
・ブレッドボート上に置いたDIPスイッチでメッセージ送信先の端末を決める。
・ブレッドボート上に置いたタクトスイッチを押すと、タクトスイッチごとに設定したメッセージが端末に送信される。
・REGISTRATION_ID(GCMが端末を識別するために必要な文字列)は手動で取得し、inoファイル上にコピペする。
・ArduinoはデフォルトではSSL通信をサポートしていないので、GCMのPOST先はhttpsではなくてhttpを使用する。(httpでも送れちゃったのでよしとする)

必要なもの

やり方

GCM with Arduino

GCM with Arduino

1. REGISTRATION_IDを取得する

GcmArduinoアプリからREGISTRATION_IDを取得し、GoogleCloudMessaging.inoにコピペする。
REGISTRATION_IDは「Implementing GCM Client on Android」にあるtokenのこと。

2. DIPロータリースイッチで送信先を決める

ブレッドボード上のDIPロータリースイッチで送信先の端末を決める。
DIPロータリースイッチの値が、
0ならdevice1とdevice2に送信する。
1ならdevice1に送信する。
2ならdevice2に送信する。

3. タクトスイッチでメッセージを送信する

タクトスイッチごとに以下のメッセージを送信する。
黄色:タイトルが「Yellow」・本文が「YELLOW!」・着信音が端末のTYPE_RINGTONE
青色:タイトルが「Blue」・本文が「BLUE!」・着信音が端末のTYPE_NOTIFICATION
緑色:タイトルが「Green」・本文が「GREEN!」・着信音が端末のTYPE_ALARM

4. GCMサーバにメッセージをPOSTする

ArduinoはデフォルトでSSL通信をサポートしていないので、POST先のURLは「https」ではなくて「http」を使用する。
(なのでREGISTRATION_IDはダダ漏れになるという前提で使うこと)

5. GCM GCM GCM…

Google様にゴニョゴニョして頂く。

6. 端末でメッセージを受け取る

押したタクトスイッチごとに着信音とかが変わってメッセージが受信されていれば成功。

Android側(GcmArduinoアプリ)

・IDEはAndroid Studio
・大元のソースはCode Samplesにあるサンプルコードなので詳細はそっち参照で。

アプリを起動してしばらくすると、logcatに「REGISTRATION_ID」が表示されるので、これをGoogleCloudMessaging.ino(後述)の「REGISTRATION_IDS[]」にコピペすること。(端末2台分)

構成

GcmArduino

GcmArduino

・アプリが起動すると、MyGcmRegistrationIntentServiceがGCMサーバにREGISTRATION_IDを登録してくれる。
・MyGcmListenerServiceはGCMからメッセージが来るのをじっと待つ。(Arduinoからメッセージが送られると通知する)
・MyInstanceIdListenerServiceは「REGISTRATION_ID」(GCMが端末を識別するために必要な文字列)が変更された場合に、再取得処理を行う。

ソースコード

ここに記載が無いものはデフォルトのまま。

AndroidManifest.xml

「GcmReceiver」は必要そうなので入れておく。

activity/MainActivity.java

config/Const.java

「SENDER_ID」はGoogle Developers Consoleの「プロジェクト番号」に書き換えること。

gcm/MyGcmListenerService.java

GCMからメッセージが届いた場合の処理+通知を表示する処理を記述する。

gcm/MyGcmRegistrationIntentService.java

GCM側に端末のREGISTRATION_IDを登録する処理を記述する。

gcm/MyInstanceIdListenerService.java

アプリの再インストール時などにGCM側からREGISTRATION_IDのリフレッシュがかかるらしいので、それを受け取るための処理(onTokenRefresh())を記述する。
GCM側からどういった場合にどういう命令?が飛んでくるのかはよくわからない。

lib/Util.java

res/strings.xml

build.gradle(Module: app)

「dependencies」に「play-services-gcm」を追加する。

Arduino側

上記GcmArduinoアプリで取得したREGISTRATION_IDをGoogleCloudMessaging.inoの「REGISTRATION_IDS[]」にコピペし、メッセージ送信先端末の識別子として利用する。

配線

GCM fritzing

GCM fritzing

GCM ブレッドボード

GCM ブレッドボード

ソースコード(GoogleCloudMessaging.ino)

・タクトスイッチの入力はArduino側でプルアップ(INPUT_PULLUP)にしておく。
・「ip[]」と「mac[]」は適宜変更すること。
・「YOUR-API-KEY」はGoogle Developers Consoleで作成したAPIキーに書き換えること。
・「REGISTRATION_IDS[]」の「REGID1」と「REGID2」はGcmArduinoアプリで取得したREGISTRATION_IDに書き換えること。
・SSLの通信はできないので、送信先のポートは443ではなくて80(httpのまま)に送る。
・ポインタとかハイレツとかよくわからないのでよしなに。

動かしてみる

右の端末がdevice1(DIPが1の時に鳴る方)
左の端末(白)がdevice2(DIPが2の時に鳴る方)

1回目:黄色スイッチでdevice1,device2両方にメッセージが飛ぶ
2回目:青色スイッチでdevice1(右)だけにメッセージが飛ぶ
3回目:緑色スイッチでdevice2(左)だけにメッセージが飛ぶ

Google Cloud Messaging with Arduino