2010年9月20日月曜日

Android Cloud to Device Message - C2DM - 3

Android アプリ側を作る

 ● AndroidManifext.xml の設定

  ・ 必要な permission

    ・メッセージを登録・受信 (<uses-permission>)
      com.google.android.c2dm.permission.RECEIVE

    ・インターネットの使用 (<uses-permission>)
      android.permission.INTERNET

    ・他のアプリのメッセージ登録・受信防止
     (<permission>, <uses-permission>)
      applicationPackage + ".permission.C2D_MESSAGE

    ・Broadcast receiver (<receiver>, <intent-filter>)
       (この Intent の <category> は applicationPackage)
      com.google.android.c2dm.intent.RECEIVE
      com.google.android.c2dm.intent.REGISTRATION

    ・C2DMフレームワークだけがメッセージを送れるようにする
      (<receiver>)
      com.google.android.c2dm.permission.SEND

    ・C2DMがうまく走らないような環境では、
     アプリがインストールされないようにする (<uses-sdk>)
      android:minSdkVersion="8"

    ・端末に設定されているアカウントを取得 (<uses-permission>)
      android.permission.GET_ACCOUNTS

    ・ PowerManager WakeLocksの使用を許可
      (<uses-permission>)
      android.permission.WAKE_LOCK

    ・CREDENTIALS を使う (<uses-permission>)
      android.permission.USE_CREDENTIALS
   
Sample

<manifest package="com.example.myapp" ...>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<uses-permission android:name="android.permission.INTERNET" />

<permission android:name="com.example.myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.example.myapp.permission.C2D_MESSAGE" />

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />


<receiver android:name=".C2DMReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.myapp" />
</intent-filter>

<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.myapp" />
</intent-filter>
</receiver>


   ChromeToPhone のソースをみたら、MainActivity.java は

    android:launchMode="singleTop"

   になってた

   あとは、c2dm パッケージを使っていて、そのために若干マニフェスト
   の書き方が変わっていた。
   詳しくは ChromeToPhone のソースを見てください。
   chrometophone - Project Hosting on Google Code


 ● メッセージ登録用の Intent の発行

  ・Intent : com.google.android.c2dm.intent.REGISTER
  ・extras1 : Sender ID
  ・extras2 : Application ID


Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
// Application ID (boilerplate)
registrationIntent.putExtra("app",PendingIntent.getBroadcast(this, 0, new Intent(), 0);
// Sender ID
registrationIntent.putExtra("sender", SenderID);
startService(registrationIntent);

  ChromeToPhone Sample では
    registrationIntent.setPackage("com.google.android.gsf");
  も入ってた。


 ● メッセージ登録解除の Intent の発行


Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");
unregIntent.putExtra("app",PendingIntent.getBroadcast(this, 0, new Intent(), 0));
startService(unregIntent);

  ChromeToPhone Sample では
    registrationIntent.setPackage("com.google.android.gsf");
  も入ってた。


 ● メッセージ登録結果の処理

  ・REGISTRATION Intent は、登録が完了しなかった場合には、
   エラー・パラメータを生成する
    → アプリはメッセージ登録を再試行すべき
      (1秒後、2秒後、4秒後、8秒後、16秒後…といった、
       exponential back offで)

  ・REGISTRATION Intent エラー

    ・SERVICE_NOT_AVAILABLE
      デバイスが、レスポンスを読むことが出来ないか、
      サーバから500/503が返った時
        → アプリは、exponential back offのスタイルで
          再試行しなければならない

    ・ACCOUNT_MISSING
      デバイス上に、Google Account がない
 
    ・AUTHENTICATION_FAILED
      パスワードが違っている

    ・TOO_MANY_REGISTRATIONS
      ユーザが、あまりに多くのアプリを登録している
        → ユーザに他のいくつかのアプリの
          アンインストールを要求する

    ・INVALID_SENDER
      Senderのアカウントが認識できない

    ・PHONE_REGISTRATION_ERROR
      Googleへの電話の登録が正しくない
        =この電話は現在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) {
// 登録に失敗したら、後で再試行する
}
else if (intent.getStringExtra("unregistered") != null) {
// 登録が解除されたら、新しいメッセージは拒否する
}
else if (registration != null) {
// アプリケーション・サーバにregistration IDを送る
// これは、別スレッドで行われるべき
// これが終わってはじめて登録作業は終了
}
}


ChromeToPhone だと、Retry 用の Intent の処理も入ってた

 } else if (intent.getAction().equals("com.google.android.c2dm.intent.RETRY")) {
  C2DMessaging.register(context, senderId);
 }


 

0 件のコメント:

コメントを投稿