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
  1. <manifest package="com.example.myapp" ...>  
  2.   <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />  
  3.   
  4.   <uses-permission android:name="android.permission.INTERNET" />  
  5.   
  6.   <permission android:name="com.example.myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />  
  7.   <uses-permission android:name="com.example.myapp.permission.C2D_MESSAGE" />  
  8.   
  9.   <uses-permission android:name="android.permission.WAKE_LOCK" />  
  10.   <uses-permission android:name="android.permission.GET_ACCOUNTS" />  
  11.   <uses-permission android:name="android.permission.USE_CREDENTIALS" />  
  12.   
  13.   
  14.   <receiver android:name=".C2DMReceiver" android:permission="com.google.android.c2dm.permission.SEND">  
  15.     <intent-filter>  
  16.       <action android:name="com.google.android.c2dm.intent.RECEIVE" />  
  17.       <category android:name="com.example.myapp" />  
  18.     </intent-filter>  
  19.   
  20.     <intent-filter>  
  21.        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />  
  22.        <category android:name="com.example.myapp" />  
  23.     </intent-filter>  
  24.   </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

  1. Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");  
  2. // Application ID (boilerplate)  
  3. registrationIntent.putExtra("app",PendingIntent.getBroadcast(this0new Intent(), 0);  
  4. // Sender ID  
  5. registrationIntent.putExtra("sender", SenderID);  
  6. startService(registrationIntent);  

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


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

  1. Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");  
  2. unregIntent.putExtra("app",PendingIntent.getBroadcast(this0new Intent(), 0));  
  3. 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をサポートしていない

  1. public void onReceive(Context context, Intent intent) {  
  2.   if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) {  
  3.       handleRegistration(context, intent);  
  4.   }   
  5.   else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {  
  6.       handleMessage(context, intent);  
  7.   }  
  8. }  
  9.   
  10. private void handleRegistration(Context context, Intent intent) {  
  11.   String registration = intent.getStringExtra("registration_id");  
  12.     
  13.   if (intent.getStringExtra("error") != null) {  
  14.       // 登録に失敗したら、後で再試行する  
  15.   }   
  16.   else if (intent.getStringExtra("unregistered") != null) {  
  17.       // 登録が解除されたら、新しいメッセージは拒否する  
  18.   }   
  19.   else if (registration != null) {  
  20.       // アプリケーション・サーバにregistration IDを送る  
  21.       // これは、別スレッドで行われるべき  
  22.       // これが終わってはじめて登録作業は終了  
  23.   }  
  24. }  


ChromeToPhone だと、Retry 用の Intent の処理も入ってた
  1. else if (intent.getAction().equals("com.google.android.c2dm.intent.RETRY")) {  
  2.  C2DMessaging.register(context, senderId);  
  3. }  


 

0 件のコメント:

コメントを投稿