Tech Sketch Bucket of Technical Chips by TIS Inc.

Padrino + MongoMapperでGoogle Cloud Messaging

Pocket

C2DMからGCMへ

Android端末にメッセージをPushする仕組みとしてC2DM(Android Cloud to Device Messaging)があります。Push型のメッセージ配信は利用者がPullして情報を得る方法とは違った大きなアドバンテージがあるため、C2DMを利用したアプリケーションを作成されている方も多いと思います。このC2DMですが、2012年6月26日で正式にdeprecated(非推奨)となってしまいました。

C2DMの代替として、Google Cloud Messaging(GCM)という仕組みを利用することができるようになりました。今後、Android端末にメッセージをPushさせるような仕組みを導入するには、GCMを採用することが推奨されています。
※C2DMもしばらくの間はサポートはされるようですが、GCMへの移行も簡単なのでなるべく早く移行する方が良さそうです。

実際に移行するとなるとGCMとC2DMの違いが気になるところですが、少し触ってみた感じではGCMもC2DMも基本的な思想は同じで、GCMではC2DMにはなかった様々なアドバンテージが得られるといった印象です。
詳細については、 このページ を参照してもらいたいのですが、本ブログではその中で以下の3点に注目してみました。

  • GCMサーバへのアクセスがとても簡単になった
  • メッセージの形式としてJSONがサポートされた
  • 複数のデバイスに同時にメッセージが(簡単に)送れるようになった

ということで、JSON形式のメッセージを複数端末にPush通知するアプリを1から作成してみることにします。
※C2DMのソースコードをGCMに対応する方法もあるのですが、それは このページ を見れば迷うことなくできる(と思う)ので割愛します。

C2DMでもそうだったのですが、GCMでもPush通知を受けるAndroidアプリだけでなく、サードパーティアプリケーションサーバを構築する必要があります。今回はサードパーティアプリケーションサーバを「Padrino + MongoMapper」で構築してみます。

※本ブログではGCMのアーキテクチャについては触れていません。どのような仕組みでメッセージがPushされるかについては、 Architectural OverviewC2DMのドキュメント (ほとんど思想は同じです)を参照してください。

完成イメージ

Nexus SとHTC Desireの2つのAndroid端末にメッセージを送信し、ステータスバーに通知を出します。イメージとしてはこんな感じです。

nexus_screenshot.png desire_screenshot.png

アプリケーション作成手順

ここからは実際のアプリケーションの作成手順を見ていきましょう。実際の構築手順としては、

  1. API Key、Sender IDの取得
  2. Androidアプリの作成
  3. サードパーティアプリケーションサーバの構築

の3段階となります。

1. API Key、Sender IDの取得

GCMを利用するためにはGoogleが管理しているGCMサーバと呼ばれるサーバにアクセスし、サインアップする必要があります。そのためにAPI Keyと呼ばれるKeyが必要となります。C2DMを利用したアプリを作成されたことのある方はご存知だと思いますが、C2DMサーバにアクセスするためには「Client Login」や「OAuth2」のトークンが必要でした。GCMではそのような複雑な処理を実装する必要がなくなり、API Keyを利用することで簡単にアクセスできるようになりました。

また、C2DMの場合と同様にGCMでもSender IDも必要となります。API Keyを取得する過程で併せて取得しておきます。C2DMの場合は、Sender IDはemailアドレスでしたが、GCMではProjectのIDに変更になっているので注意が必要です。

API Keyの取得方法は こちらのページ を参考にしてください。具体的な方法は以下のようになります。

  1. Google APIs Console pageを開く
  2. Projectを作成する。初めてGoogle APIs Console pageを開いた場合は「Create Project」ボタンを押してProjectを作成する。(すでに作成済みの場合はDashboardが開くので、ドロップダウンメニューから「Other projects > Create」を選択)
  3. Projectを作成すると、ブラウザのURLがhttps://code.google.com/apis/console/#project:4815162342のような形式となっているので、4815162342(これがSender ID)を控えておく
  4. Servicesを選択して、Google Cloud Messaging for AndroidのトグルをONにする
  5. API Accessを選択して、Create new Server keyボタンを押して、API Keyを作成する

これで、API KeyとSender IDが取得できました。これらの値は後で使うので控えておいてください。

Androidアプリの作成

ここからはPushされたメッセージを受け取るAndroidアプリを作成します。Androidアプリを作成する際はC2DMで利用していたコードを再利用して実装することもできます(一部修正が必要です)が、GCMを使ったアプリを簡単に実現できるライブラリが提供されるのでこれを利用します。

ライブラリはAndroid SDK Managerを利用してダウンロードすることができます。ダウンロードしたAndroidクライアント用のライブラリ(今回は利用しませんが、サードパーティアプリケーションサーバ用もあります)は、YOUR_SDK_ROOT/extras/google/gcm/gcm-client/distに格納してあるので、その中のgcm.jarをAndroidのlibs(というディレクトリを作成)以下に配置します。後はこのjarを読み込むようにBuild Pathを通せば事前準備は完了です。

実装

ここからはコードを書いていきます。GCMを利用したアプリは基本的にメインとなるAcitvity(このアプリではGcm_sampleActivity)とGCMBaseIntentServiceというクラスを継承したGCMIntentServiceの2つのコードで構成されます。具体的な処理の内容はコード内のコメントを参照してください。

まずは、Gcm_sampleActivity.javaの例です。

続いて、GCMBaseIntentService.javaのコードです。ここでは、RegistrationId(GCMサーバへのサインアップが完了すると付与されるAndroid端末を一意に特定できるID)をサードパーティアプリケーションサーバにアップロードするという処理と、Android端末にメッセージが送信されたときの処理(今回はステータスバーに通知を表示させる)を実装しています。

C2DMやGCMを利用する場合、Permission関連ではまってしまうことがあります。ということで、AndroidManifest.xmlを以下に示しておきます。

これで、Androidアプリは実装できました。

サードパーティアプリケーションサーバの構築

ここからはサードパーティアプリケーションサーバを構築します。冒頭でも書いたとおり、この部分の実装は、Padrino + MongoMapperを利用して実装します。

ちなみに、 Padrino はSinatraをベースに開発されたRuby製のフレームワークで、 MongoMapper はRubyで扱えるMongo ODM(Object-Document-Mapper)です。PadrinoではMongoMapper以外にもMongoid、ActiveRecordなど様々なORMがサポートされています。PadrinoとMongoMapperについてここでは詳しく説明しませんので、詳細については公式HPを参照してください。

サードパーティアプリケーションサーバでは以下の処理を実装していきます。

  • AndroidアプリからアップロードされたRegistrationIdをDB(今回はMongoDB)に保存しておく(RegistrationIdだけだとメッセージを送る際にどの端末かわからないので、今回はデバイス名と共に保存します)
  • GCMサーバに「どのAndroid端末」に対して「どんなメッセージを送信する」かという情報(JSON形式のデータ)を送信する
  • GCMサーバに送信した情報をDBに保存する

Padrino及びMongoDBのインストール方法については公式HPを参照してください。ここではすでにPadrino, MongoDBのインストール及びセットアップが終わっているものとして話を進めます。

実装

では、Padrinoでアプリケーションを作成していきましょう。今回用意するのは、以下の2つのControllerと2つのModelです。

  • Controller
    • Androidアプリから送られてきたRegistrationIdとname(デバイス名)を受け取り、MongoDBに保存するなどDevice関連を扱うapp/controller/device.rb
    • Android端末にメッセージを送信する処理や、送信したメッセージ一覧を参照できるようにするなどMessage関連を扱うapp/controller/message.rb
  • Model
    • Deviceに関する情報(RegistrationIdとname)を扱うmodel/message.rb
    • Messageに関する情報(どの端末にどんなメッセージを送ったかなど)を扱うmodel/device.rb

PadrinoにはRails同様、Generatorが多数用意されているので、これらを使ってgcm_pusherというプロジェクトを作成し、Controller, Modelの雛形を作ってから細かい修正を行っていくことにします。雛形を作成するコマンドは以下のようになります。

これで雛形ができました。作成されたコードを修正していきましょう。まずはapp/controller/device.rbからです。
http://YourServerURL/device/regiserというURLにPOSTされたときに、RegistrationIdとnameを保存するコードはこんな感じになります。

app/controller/device.rb

http://YourServerURL/にアクセスしたときに今まで送信されたメッセージの一覧とメッセージ投稿画面を表示するようにします。これを実現するためには、controllerのapp/controller/message.rbとview(app/views/message/new.haml、app/views/message/_form.haml)を以下のように実装します。

app/controller/message.rb

app/views/message/new.haml

app/views/message/_form.haml

app/controller/message.rbではメッセージをPOSTする(/messageがPOSTで呼ばれた)際に、GcmAccess.gcm_post_message(registration_ids, data)を呼んでいるのですが、この処理によりGCMサーバにメッセージが送信され、各Android端末にメッセージがPushされます。GcmAccess.gcm_post_message(registration_ids, data)の中身は、lib/gcm_access.rbというモジュール内に以下のように実装しています。

Controllerの実装はここまでです。最後にモデルを実装していきます。MessageとDeviceを多:多のRelationで保持したいので、以下のようにdevice.rbとmessage.rbを実装します。

これで、サードパーティアプリケーションサーバの準備は完了です。

動作確認

Androidアプリ、サードパーティアプリケーションサーバの実装が終わったので、動作確認を行っていきす。まず、サードパーティアプリケーションを以下のコマンドで起動しておきます。

サードパーティアプリケーションサーバの起動が確認されたら、Androidアプリを起動します。すると、以下のような画面が出るので、Deviceの名前(例:nexus)を入れてRegistボタンを押します。

regist_screen_shot.png

次に、登録された端末にメッセージを送ります。ブラウザからhttp://YourSeverURL/ にアクセスすると、メッセージ送信用の画面が出るので、以下のように入力してSubmitボタンを押すと、完成イメージで示したようにAndroid端末にメッセージを送信することができます。

gcm_screenshot2.PNG

ちなみにmongoDBにはこのように格納されています。

最後に

このような感じで、GCMはC2DMよりも簡単に実装することができるようになっています。今回紹介できなかった新たな機能もいくつかあるので、色々組み合わせて試してみるのも面白いと思います!

エンジニア採用中!私たちと一緒に働いてみませんか?