Android Cloud to Device Messaging Framework を。
おもしろそうなので、まずはドキュメントをみる。
Google Projects for Android: C2DM
処理の流れは、
だと書いてる。
C2DMサーバを経由するようだ。
Enabling C2DM. An Android application running on a mobile device registers to receive messages. Sending a message. A third-party application server sends messages to the device. Receiving a message. An Android application receives a message from a C2DM server.
あと、なんかいろいろかいてるのだが、いきなりサンプルコードをみてみる。
AndroidManifest.xmlはまあ気に留めておくとして。
受信(Android)アプリ側
C2DM サーバに登録と登録削除
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER"); registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0); // boilerplate registrationIntent.putExtra("sender", emailOfSender); startService(registrationIntent);
Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER"); unregIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0)); startService(unregIntent);
C2DM サーバに登録削除後のレスポンス受信
public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) { handleRegistration(context, intent); } else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { handleMessage(context, intent); } } private void handleRegistration(Context context, Intent intent) { String registration = intent.getStringExtra("registration_id"); if (intent.getStringExtra("error") != null) { // Registration failed, should try again later. } else if (intent.getStringExtra("unregistered") != null) { // unregistration done, new messages from the authorized sender will be rejected } else if (registration != null) { // Send the registration ID to the 3rd party site that is sending the messages. // This should be done in a separate thread. // When done, remember that all registration is done. } }
メッセージを受信するには、受信可能状態であることをCD2Mサーバに教えておくことが必要。
CD2Mサーバからテキストを受信
protected void onReceive(Context context, Intent intent) { String accountName = intent.getExtras().getString(Config.C2DM_ACCOUNT_EXTRA); String message = intent.getExtras().getString(Config.C2DM_MESSAGE_EXTRA); if (Config.C2DM_MESSAGE_SYNC.equals(message)) { if (accountName != null) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Messaging request received for account " + accountName); } ContentResolver.requestSync( new Account(accountName, SyncAdapter.GOOGLE_ACCOUNT_TYPE), JumpNoteContract.AUTHORITY, new Bundle()); } } }
CD2Mサーバに登録成功すれば、あとはこのサーバにテキストを送信すればよし。と。
登録時のレスポンスと、CD2Mサーバからのテキスト受信は、同じレシーバで実装。
送信元アプリ側
WEBアプリでもその他のアプリでもPOSTだけでいいような雰囲気。
To send a message, the application server issues a POST request to https://android.apis.google.com/c2dm/send
で何をPOSTするのかというと、
- registration_id
- collapse_key
- data.
- delay_while_idle
- Authorization: GoogleLogin auth=[AUTH_TOKEN]
リクエストヘッダを利用してトークンを渡す。
このAUTH_TOKENはGoogleのアカウントを利用して、GoogleClientLogintから取得する。
<?php /** * CD2M client for 3rd-party application */ define('GOOGLE_CLIENTLOGIN_URL', 'https://www.google.com/accounts/ClientLogin'); // Google Client Login $data = array('Email' => 'youracount@gmail.com', 'Passwd' => 'password', 'service' => 'ac2dm', 'source' => ''); $data = http_build_query($data, '', '&'); $header = array('Content-Type: application/x-www-form-urlencoded', 'Content-Length: ' . strlen($data)); $context = array('http' => array( 'method' => 'POST', 'header' => implode("\r\n", $header), 'content' => $data ) ); $response = file_get_contents(GOOGLE_CLIENTLOGIN_URL, false, stream_context_create($context)); $lines = explode("\n", trim($response)); $registers = array(); foreach ($lines as $line) { list($key, $value) = explode('=', $line); $registers[$key] = $value; } var_dump($registers);
array(3) { ["SID"]=> string(224) "DQAxxJYAAAA1UafTri1HGxbjgMRPL2oZhK-eubtwF9pv29rbLQCq_cESmEaa5K4XkiF6RkK9ZRn5ICvvamX5xpIpwNLcEHUQH9k3vyNz_bnLatCJhSYoC8DajjyhQn7r0mhmokh-AwJXupNgzhyzvMJNCncuNge8eALBjQEJeaaWreGc3cqxZhmH3FFxWsoOo8uTFW0iWsRayUSK5Ty-P8gaglri_I3I1d" ["LSID"]=> string(224) "DQAxxJcAAABsIHpacQ8gtaqtacyb3kIiDS0WfTiK9ve_j2GFttanBr7z5QLnnUwrQz2M6S1pHFFnJLHJ5vAaapur3bTnAQgKEYKLSYGN-FCyMtadCpwZOc3FxkZ80atUGGh23UcaakLu6Q54nRtR5BE5tgh1t18tmCMjISnyZMEz6UTX_O-JZE7xO8UoSfyCaCRRQPshGY-IcfWYDIa1wIWgTUWLfK0gbo" ["Auth"]=> string(224) "DQAxxJgAAAAlNWweqwVdTRzmpnK6FMgMwI6S2b4wnCku6WpjcwOQNF64RVoxf0TGoWocY8knlaMwnyRwdaaf7ZLH5KSkSV5msveMHcjh6Ll_f3itDxoZVMC9jx7z793cQwBUvHuidGKTsVtTXwEm0_O9TBuhe6W4-8slH-hvWqhR1YRYh8TrzWr3PZ-2pZHL0YIi3e4QWYL2c4Q3Zjb_NJxrceDl_1wV" }
また、shなコードがありました。
#!/bin/sh # USAGE : get_auth_token.sh email password curl https://www.google.com/accounts/ClientLogin \ -d Email=$1 -d "Passwd=$2" -d accountType=GOOGLE \ -d source=Google-cURL-Example -d service=ac2dm
ワンタイムなトークンの仕組みを利用するのはYoutubeAPIなどでも同じ。
Android側のアプリをつくる
こんな記事が。
http://androidforums.com/android-developers/116833-c2dm-android-2-2-emulator.html
I am currently playing around with C2DM service and I am wondering if it is possible to test device-side C2DM application on Android 2.2 emulator? My current problem is that when my application sends registration intent to C2DM server, Logcat says: Unable to start service Intent { act=com.google.android.c2dm.intent.REGISTER (has extras) }: not found The same happens when I try to run examples - JumpNote and Google Chrome to Phone Extension that were mentioned here. Any ideas?
Solved this issue myself. I have installed SDK Platform Android 2.2, but haven't noticed that for testing C2DM additionally Google APIs package is needed
C2DMのAPIパッケージってどこにあるのだろう。
C2DMは、2.2以上のAndroidが走っているデバイスが必要である。かつ、Android Marketアプリがインストールされていなければならない。
ユーザは、モバイル上で、Googleアカウントの設定をしておかなければならない。