2013 年 5 月 10 日

アンドロイドアプリからGoogle Cloud Messagingを使う方法(第3回)

アンドロイドアプリからGoogle Cloud Messagingを使う方法(第3回)

[Google Cloud Messageing]

今回は、サーバサイドの実装方法について、説明します。サーバサイドでは、GCMサーバから通知を受信したクライアントアプリからレジストレーションID登録・解除要求を受け付けて、レジストレーションIDを管理する必要があります。サーバアプリから端末へメッセージを送信するには、このレジストレーションIDに対しメッセージを指定して、送信します。

サーバアプリはPHPとcurlコマンドを利用します。レジストレーションIDを登録・解除するプログラムはPHPで実装して、メッセージ送信はcurlコマンドで実行します。

参考リソース

  1. GCM Architectural Overview

レジストレーションIDを登録・解除

以下のURLのPHPスクリプトを実装します。

http://www.notice.co.jp/gcm/register.php&regId=レジストレーションID // 登録
http://www.notice.co.jp/gcm/unregister.php&regId=レジストレーションID // 解除

登録

<?php
  $fp = fopen("register.txt", "a");
  fwrite($fp, $_REQUEST['regId'] . PHP_EOL);
  fclose($fp);
?>

解除

<?php
  $fp = fopen("unregister.txt", "a");
  fwrite($fp, $_REQUEST['regId'] . PHP_EOL);
  fclose($fp);
?>

単純にregIdパラメータの内容をファイルに書き込むだけのPHPスクリプトです。本来は、ユーザーIDなどとひもづけて、データベースなどで管理することになるでしょう。

クライアントアプリを実行

ここまで準備ができたら、クライアントアプリを起動します。端末が登録されていなければ、サーバアプリのregister.phpが呼び出しされるはずです。

クライアントの画面には、以下のようなメッセージが表示されます。

From Demo Server: successfully added device!

このとき、サーバサイドのregister.phpの直下のregister.txtにレジストレーションIDが保存されます。

APA91bHrvxmo4BSggNgx****省略***swuAaOd2o_KtkyqXtzw

サーバアプリからメッセージ送信

このレジストレーションIDと第1回で作成したAPI_KEY(サーバーキーのAPI key)を使って、メッセージを送信してみます。以下のようなshellスクリプトを作成します。もちろん、コマンドを直接実行してもかまいません。

#!/bin/sh

API_KEY=サーバーキー(第1回で生成したサーバーキーのAPI keyを指定する)
REG_ID=レジストレーションID

curl -o result -w '%{http_code}\n' \
      --header "Authorization: key=$API_KEY"
      --header Content-Type:"application/json" https://android.googleapis.com/gcm/send 
      -d "{\"registration_ids\":[\"$REG_ID\"], \"data\":{\"message\":\"Hi.Doroid.\"}}"

送信メッセージ形式

送信するデータ形式は、プレインテキストとJSONが利用できます。ここではJSONで説明します。

registration_idsは複数のレジストレーションIDをカンマ区切りで指定できます。送信したいデータは、dataとして4kb以内のJSON形式のデータを指定します。これらのメッセージはGCMサーバにて4weeks(デフォルト)保存されます。

 "registration_ids" : ["レジストレーションID",...],
 "data" : {
   "message" : "Hi. Droid."
 }

オプション

他に以下のようなオプションが指定できます。

パラメータ 説明
registration_ids レジストレーションIDを複数指定可能。registraion_idとすれば、単一のIDのみ
collapse_key 同じメッセージを集約するためのキー(端末がoffline時、同一メッセージを繰り返し送信したくないときに利用)
data 送信メッセージ(4KiB以内のJSON)
delay_while_idle 端末がアイドリング中はメッセージを送信しない
time_to_live メッセージの生存期間を秒で指定(デフォルトは4weeks)
restricted_package_name クライアントアプリのパッケージ名でメッセージ送信を制限
dry_run メッセージ送信しない(デバッグ用)

このコマンドを実行すると、標準出力にHTTPステータスが表示されます。それらの意味は以下の通りです。

HTTPステータス

以下のようなHTTPステータスが返ってきます。

ステータス 説明
200 正常
400 JSONが不正なフォーマット
401 認証エラー(API_KEYの誤りなど)
5XX GCM serverの内部エラー

送信結果

resultに以下のようなJSONが出力されます。

{
  "multicast_id" : 8263883890992153518,
  "success"      : 1,
  "failure"      : 0,
  "canonical_ids": 0,
  "results": [
               {message_id" : "0:1367991662486218%caefdb16f9fd7ecd"}
             ]
}

各フィールドの意味は以下の通りです。

フィールド 説明
multicast_id multicast messageのID
success 正常に処理された数
failure エラーがあった数
canonical_ids 不正なレジストレーションIDの数(一端末に対して重複したようなID)
result message_idは成功したメッセージのID,canonical_idsが0以上なら、registration_idに正規IDが返ってくる。エラーがあれば、errorにエラーメッセージが返る。

クライアントアプリの画面には、以下のメッセージが表示されて、ステータスバーにも同様なメッセージが表示されます。

From GCM: you got message! = Hi. Droid.

これで、サーバアプリからメッセージを送信できました。

レジストレーションIDの解除

レジストレーションIDの解除には二通りの方法があります。クライアントアプリから明示的に解除する方法と、クライアントアプリのアンインストールで自動的に解除する方法です。

前者は、クライアントアプリの設定で、メッセージ送信をオフにするような場合です。メッセージ送信をオフにしたとき、レジストレーションIDの解除が必要なら、APIから可能です。

  GCMRegistrar.unregister(this); // thisはContext

このAPIの呼び出しによって、レジストレーションID解除が実行されて、サーバアプリの解除APIが呼び出しされます。サーバアプリでは、以後、このレジストレーションIDに対して、メッセージ送信しないようにします。

画面には以下のようなメッセージが表示されます。

From GCM: device successfully unregistered!

GCMのサンプルコード(android-sdk/extras/google/gcm/samples/gcm-demo-client
)を自分の環境で動作させるための解説と変更点を中心に、3回に渡ってご説明しました。GCMの理解とサンプルを動作させるときの参考になれば、幸いです。

関連記事

  1. アンドロイドアプリからGoogle Cloud Messagingを使う方法(第1回)- 準備編
  2. アンドロイドアプリからGoogle Cloud Messagingを使う方法(第2回)- クライアントアプリ編
  3. アンドロイドアプリからGoogle Cloud Messagingを使う方法(第3回)- サーバーアプリ編