Cloud to Device Messaging(C2DM)をサポートするAndroid用アプリケーションを作成しています





読者の皆さん、Habrahabrこんにちは!



この投稿では、GoogleのC2DMサービスに注意を払い、このサービスのサポートをAndroidアプリケーションに実装する方法を伝えたいと思います。 C2DMは、Androidデバイスにインストールされたアプリケーションにメッセージを送信するためのAPIを提供する特別なサービスです。 このサービスの使用は、必要に応じて、システムに登録されているが現在アクティブではないユーザーアプリケーションにメッセージを送信するために不可欠な方法です。



C2DMはAndroidプラットフォームの基本的な機能の1つですが、RuNetにはC2DMに関する情報がほとんどありません。 この状況を変えようとする試みは、この投稿のタスクの1つです。



簡単に、簡単なクライアントアプリケーションとサーバーアプリケーションを作成する方法、いくつかの「落とし穴」を示す方法、およびサンプルコードへのリンクを提供します。



クラウドからデバイスへのメッセージング



しかし、今のところ、少しの理論。 上で書いたように、C2DMはユーザーアプリケーションからAndroidアプリケーションへのメッセージ配信サービスです 。詳細についてはこちらをご覧ください 。 つまり これは、Appleの観点から言えば、プッシュ通知の一種です。 インタラクションの一般的なスキームは、インターネットにある次の図に示されています。

3つの主要部分が図から見えます:

  1. C2DMサービス。 メッセージを配信するためのGoogleのクラウド。 デバイスおよび認証の登録/再登録だけでなく。
  2. クライアント部分。 メッセージを受け入れるAndroidアプリケーション。
  3. サーバー部分。 メッセージを送信するクライアントアプリケーション(Googleの用語では「サードパーティサーバー」)。
メッセージパッシングプロセスの詳細は、上記で引用したリンクで記述されていますが、簡単に言うと、次のもので構成されています。

  1. AndroidアプリケーションはC2DMに登録されているため、メッセージを受信する準備ができたことを通知し、 登録IDを受け取ります 。 登録IDは、サーバー部分が受信者にメッセージを送信できることを知っている、デバイスの一意の識別子です。 登録時には、Googleアカウントの名前を指定する必要がありますが、これについては後でクライアント側について検討するときに記述します。
  2. アプリケーションは、サーバーの登録IDを送信して、メッセージを送信できるユーザーを認識します。
  3. サーバー部分は、C2DMに登録するときにAndroidアプリケーションと同じアカウントを使用してGoogleサーバーで認証され、 認証トークンを受け取ります。 Googleのサービスでの承認と認証の詳細については、 こちらをご覧ください
  4. 登録IDと認証トークンを知っているサーバーは、Androidアプリケーションにメッセージを送信します。
これで、開発に直接行くことができます。 クライアント側(Androidアプリケーション)から始めましょう。



クライアント部



C2DM Androidを使用するには、デバイスが次の要件を満たしている必要があります。

  1. Android 2.2以降のバージョンである必要があります。 以前のバージョンでは、C2DMはサポートされていません!
  2. 動作中のGoogleアカウントが必要です。 Androidマーケットをお持ちの場合は、お持ちです。
すべてが完了したら、アプリケーションの作成に進むことができます。 このために、Eclipse + Android SDKを使用します。 TextViewで最も単純な「Hello、World」を作成できます。 アプリケーションを作成する手順については説明しません。たとえば、 ここここなど、それについて多くのことが書かれています 。 次のようなものが得られるはずです。





注:Android 2.2がない場合は、エミュレーターを使用できますが、標準のSDKプラットフォームではなく、Google API(API 8以上)を使用する必要があります。 標準SDKでのGoogleアカウントのサポートはありません。



アプリケーションを作成したら、パッケージ名(パッケージ名)を指定する必要がある特別なサイトに登録する必要があります。最も重要なのは、メッセージの送信に使用されるGoogleのメールアカウントです。 登録時にクライアントで、認証時にサーバーで使用するのはこのメールです。 確認メールを送信する必要があります。この手紙の後、指定されたアカウントを使用してC2DMを操作できます。



次に、「Hello、World!」アプリケーションの変更に進みます。 登録/登録解除、そしてもちろんメッセージの受信を担当するコードの実装が必要です。 初めて自分で書くのは本当に難しい すべてのニュアンスを考慮することは難しいため、 としてGoogle自体に親切に提供するコードを使用します。 クライアント側でC2DMを操作するための既成のクラスセットをsvn storageからダウンロードします。 そして、それらをプロジェクトの「 src \ com \ google \ android \ c2dm 」ディレクトリに追加します。 次のようになります。





次に、抽象クラスC2DMBaseReceiverのメソッドを実装する必要があります。このため、呼び出しをログに記録するだけでクラスC2DMReceiverを記述し、Mainの隣に配置します。 C2DMReceiverクラスのコンテンツ:

  1. パッケージ com.home.c2dmtest ;
  2. import com.google.android.c2dm.C2DMBaseReceiver ;
  3. import android.app.Notification ;
  4. import android.app.NotificationManager ;
  5. import android.app.PendingIntent ;
  6. import android.content.Context ;
  7. import android.content.Intent ;
  8. import android.util.Log ;
  9. パブリック クラス C2DMReceiver C2DMBaseReceiverを拡張します{
  10. パブリック C2DMReceiver {
  11. super "<yourmail> @ gmail.com" ;
  12. }
  13. @ オーバーライド
  14. public void onRegistered コンテキストコンテキスト、 文字列 registrationId {
  15. ログ w "onRegistered" 、registrationId ;
  16. }
  17. @ オーバーライド
  18. public void onUnregistered コンテキストコンテキスト {
  19. ログ w "onUnregistered""" ;
  20. }
  21. @ オーバーライド
  22. public void onError コンテキストコンテキスト、 文字列 errorId {
  23. ログ w "onError" 、errorId ;
  24. }
  25. @ オーバーライド
  26. protected void onMessage コンテキストコンテキスト、インテントインテント {
  27. ログ w "onMessage""" ;
  28. }
  29. }


しかし、アプリケーションはまだC2DMで動作する準備ができていません。 必要な権利が設定されておらず、BroadcastReceiverが登録されていません。 これを修正するには、AndroidManifest.xmlを変更する必要があります 。その方法については、 こちらをご覧ください 。 私の例では、ファイルは次のようになります。

  1. <?xml version = "1.0" encoding = "utf-8" ?>
  2. <マニフェスト xmlns:android = " schemas.android.com/apk/res/android"
  3. android:versionCode = "1"
  4. android:versionName = "1.0" package = "com.home.c2dmtest" >
  5. <アプリケーション
  6. android:debuggable = "true"
  7. android:label = "@ string / app_name" >
  8. <アクティビティ android:name = "Main"
  9. android:label = "@ string / app_name"
  10. android:theme = "@android:style / Theme.NoTitleBar" >
  11. <意図フィルター>
  12. <action android:name = "android.intent.action.MAIN" />
  13. <category android:name = "android.intent.category.LAUNCHER" />
  14. </ intent-filter >
  15. </アクティビティ>
  16. <service android:name = ".C2DMReceiver" />
  17. <受信機
  18. android:name = "com.google.android.c2dm.C2DMBroadcastReceiver"
  19. android:permission = "com.google.android.c2dm.permission.SEND" >
  20. <意図フィルター>
  21. <action android:name = "com.google.android.c2dm.intent.RECEIVE" />
  22. <category android:name = "com.home.c2dmtest" />
  23. </ intent-filter >
  24. <意図フィルター>
  25. <action android:name = "com.google.android.c2dm.intent.REGISTRATION" />
  26. <category android:name = "com.home.c2dmtest" />
  27. </ intent-filter >
  28. </受信機>
  29. </アプリケーション>
  30. <uses-sdk android:minSdkVersion = "8" />
  31. <許可
  32. android:name = "com.home.c2dmtest.permission.C2D_MESSAGE"
  33. android:protectionLevel = "signature" />
  34. <uses-permission android:name = "com.home.c2dmtest.permission.C2D_MESSAGE" />
  35. <uses-permission android:name = "com.google.android.c2dm.permission.RECEIVE" />
  36. <uses-permission android:name = "android.permission.INTERNET" />
  37. <uses-permission android:name = "android.permission.WAKE_LOCK" />
  38. </マニフェスト>


注:C2DMを使用するために正しいandroid.permission.WAKE_LOCKは必要ありませんが、後で必要になります。このファイルを2回リストしないように、事前に追加することにしました。



これで、デバイスをC2DMに登録できます。そのために、OnCreateで次のコードを呼び出します。

C2DMessaging。 register this"<yourmail> @ gmail.com" ;


すべてがうまくいった場合、数秒後に新しいRegestration IDがC2DMReceiverクラスのonRegisteredメソッドに分類されます。 これが発生しない場合は、LogCatのログでエラーを確認する必要があります。



メソッドを呼び出すことで登録解除できます:

C2DMessaging。 登録解除 これ ;


現在の登録IDを取得:

文字列 ID = C2DMessaging。 getRegistrationId これ ;


登録IDはいつでも変更できます。 Googleは新しい意味を送信できるため、この状況に対処できる必要があります。 この例では、このためにすべてがすでに行われています;このメカニズムの実装は、クラスC2DMBaseReceiverのメソッドhandleRegistrationにあります。



最終的なプロジェクトは次のようになります。





ここで、プロジェクトをより視覚的にし、メッセージの処理を拡張する必要があります。 新しいメッセージが到着すると通知が表示され、選択されると、アプリケーションはサーバーによって指定されたテキストで開始されます。



OK、これのために、onMessageコードを次のように変更します。

  1. @ オーバーライド
  2. protected void onMessage コンテキストコンテキスト、Intent receiveIntent
  3. {
  4. 文字列データ= receiveIntent。 getStringExtra "message" ;
  5. if data = null
  6. {
  7. ログ w 「C2DMReceiver」 、データ ;
  8. Intent intent = new Intent this 、Main。Class ;
  9. 意図。 putExtra "メッセージ" 、データ ;
  10. NotificationManager mManager = NotificationManager
  11. getSystemService Context.NOTIFICATION_SERVICE ;
  12. Notification notification = new Notification android。R . Drawable。Ic_dialog_info
  13. 「私のC2DMメッセージ」システムcurrentTimeMillis ;
  14. 通知。 setLatestEventInfo コンテキスト、 「アプリ名」「C2DM通知」
  15. PendingIntent。 getActivity this。getBaseContext 0
  16. インテント、PendingIntent。 FLAG_CANCEL_CURRENT ;
  17. mManager。 通知 0 、通知 ;
  18. }
  19. }


messageは、サーバーが送信するメッセージの識別子です。 これを新しいIntentに追加して、後でMainで取得できるようにします。



Mainを変更して、送信されたメッセージを表示します。

  1. @ オーバーライド
  2. public void onCreate Bundle savedInstanceState {
  3. スーパーonCreate savedInstanceState ;
  4. TextView view = new TextView this ;
  5. 文字列メッセージ= getIntent getStringExtra "message" ;
  6. if メッセージ== null
  7. ビュー。 setText "Hello、World !!!" ;
  8. 他に
  9. ビュー。 setText "Your message:" + message ;
  10. setContentView ビュー ;
  11. 文字列 ID = C2DMessaging。 getRegistrationId これ ;
  12. if id == ""
  13. {
  14. C2DMessaging。 register this"<yourmail> @ gmail.com" ;
  15. }
  16. }


実際には、登録IDをサーバーやその他の小さなものに転送するためのメカニズムを作成する必要がありますが、 この例では、そこで停止し、サーバー上の登録IDをハードコードします。



サーバー側



最初のステップは、認証トークンを取得することです。 これはこのブログによく書かれています(他にも多くの有用な情報があります)。 一般に、例があり、すべてがロシア語であるため、繰り返しは行わず、受け取ったと想定します。



したがって、登録IDと認証トークンがあります。 小さい場合は、メッセージを伝える必要があります。 何らかの理由で、インターネットのこの部分に関する情報はほとんどありませんが、ここでは複雑なことは何もありません。



Googleサーバーとの接続を確立し、 正しい形式でリクエストを作成する必要があります。 そしてそれだけです。 メッセージを送信する簡単な例を次のコードに示します。

  1. public boolean sendData
  2. 文字列 authToken、
  3. 文字列 registrationId、
  4. 文字列の崩壊、
  5. 文字列キー、
  6. 文字列
  7. IOExceptionを スローします {
  8. //登録IDを設定します
  9. StringBuilder postDataBuilder = new StringBuilder ;
  10. postDataBuilder。 append "registration_id"
  11. append "=" 追加 registrationId ;
  12. // collapse_keyを設定-折りたたみキーが同じ場合にメッセージをグループ化し、
  13. //たとえば、デバイスはオフになり、1つのメッセージのみが送信されます。
  14. //一度にすべてではありません。
  15. postDataBuilder。 append "&" append "collapse_key" append "="
  16. 追加 折りたたみ ;
  17. // <data。> <key> = <value>の形式で、送信された日付を追加します
  18. postDataBuilder。 append "&" append "data。" + key append "="
  19. append URLEncoder。encode value、 "UTF-8" ;
  20. バイト [ ] postData = postDataBuilder。 toString getBytes "UTF-8" ;
  21. URL url = 新しい URL " android.clients.google.com/c2dm/send" ;
  22. //接続を設定します
  23. //プロキシproxy = new Proxy(Proxy.Type.HTTP、new InetSocketAddress( "lazerboy.local"、8080));
  24. HttpsURLConnection conn = HttpsURLConnection url。 openConnection / *プロキシ* / ;
  25. conn。 setDoOutput true ;
  26. conn。 setHostnameVerifier this .new MyHostnameVerifier ;
  27. conn。 setRequestMethod "POST" ;
  28. conn。 setRequestProperty "Content-Type"
  29. "application / x-www-form-urlencoded; charset = UTF-8" ;
  30. conn。 setRequestProperty "Content-Length" 、Integer。toString postData。length ;
  31. conn。 setRequestProperty "Authorization""GoogleLogin auth =" + authToken ;
  32. OutputStream out = conn。 getOutputStream ;
  33. アウト。 書き込み postData ;
  34. アウト。 閉じる ;
  35. //応答コードを取得します。
  36. int responseCode = conn。 getResponseCode ;
  37. if responseCode == HttpServletResponse。SC_UNAUTHORIZED ||
  38. responseCode == HttpServletResponse。 SC_FORBIDDEN {
  39. システム アウトprintf 「無許可-トークンが必要」 ;
  40. falseを 返し ます
  41. }
  42. if responseCode == HttpServletResponse。SC_OK
  43. {
  44. システム アウトprintf "デバイスに送信されたデータ!" ;
  45. trueを 返し ます
  46. }
  47. システム アウトprintf "何か間違っている、応答メッセージ:" 、接続getResponseMessage ;
  48. falseを 返し ます
  49. }


ここでは、サーバーからのメッセージの処理という非常に重要な詳細が1つ欠落しています。 そのため、たとえば、認証トークンの有効期限が切れる状況は一切処理されません。 しかし、すぐに使用できるライブラリではなく、動作するアプリケーションの例を書きたかったのです。 さらに、必要なものはすべて、Googleのソースコード(たとえば、 こちら)にあります



コードが正常に機能する場合、ユーザーのデバイスの通知領域に通知が表示され、クリックすると、サーバーからのテキストでアプリケーションが起動します。 ほら、これはまさに私たちが達成したことです。



おわりに



AndroidベースのアプリケーションにC2DMサポートをそれほど頭痛なく固定できる方法を示しました。 クライアント側とサーバー側の両方で、このために必要なこと。 もちろん、「ホワイトスポット」はありましたが、繰り返しますが、主なタスクは、この投稿を読んでいる人がC2DMをサポートするアプリケーションの開発を容易にするためのアイデアを伝え、コード例を示すことでした。



便利なリンク

  1. Androidクラウドからデバイスへのメッセージング
  2. C2DMを使用するためにアカウントを登録する必要がある場所
  3. C2DMおよびAndroidに関するロシア語のブログ
  4. Googleのサンプル
  5. トピックに関する別のブログ
  6. C2DMの使用例



All Articles