LoginSignup
46
42

More than 5 years have passed since last update.

GCM 2.0から3.0に移行した話(Androidとサーバー)

Posted at

今回移行する機会があったので、備忘録もかねて記しておきます。お気づきの点等あればご指摘いただけると幸いです。

2.0ベース実装は前任が担当で、自分にその経験があった訳でもないので、影響範囲の調査からスタートしました。
結論から言うと簡単でした。実装で言えば1人で2時間程度。

3.0では、TopicsやDevice Groupsといった2.0にはない送信方法もありますが、今回これらは使わず、以前からある普通の、registration ID単位での送信を使ってます。

Android側

ざっくり手順です。

  1. build.gradle等の設定
  2. 独自のBroadcastReceiver実装を廃止し、代わりにcom.google.android.gms.gcm.GcmReceiverに受信処理を委譲。
  3. IntentServiceを拡張していたクラスを、GcmListenerServiceの拡張クラスに置き換え。
  4. トークン更新にまつわるサービスを2つ実装(Googleドキュメントで言うMyInstanceIDListenerServiceとRegistrationIntentService)

実装

マニフェストはこんな感じになりました。

AndroidManifest.xml
         <!-- 上の1の部分 -->
         <receiver
-            android:name="com.example.android.service.GcmBroadcastReceiver"
android:name="com.example.android.service.GcmBroadcastReceiver"  +            android:name="com.google.android.gms.gcm.GcmReceiver"
 +            android:exported="true"
              android:permission="com.google.android.c2dm.permission.SEND" >
              <intent-filter>
                  <action android:name="com.google.android.c2dm.intent.RECEIVE" />
 -                <category android:name="com.example.android.permission.C2D_MESSAGE" />
 +                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
 +                <category android:name="com.example.android" />
              </intent-filter>
          </receiver>
          <!-- 同2の部分 -->
 -        <service android:name="com.example.android.service.GcmIntentService" />
 +        <service
 +            android:name="com.example.android.service.MyGcmListenerService"
 +            android:exported="false">
 +            <intent-filter>
 +                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
 +            </intent-filter>
 +        </service>
 +        <!-- 同3 -->
 +        <service
 +            android:name="com.example.android.service.MyInstanceIDListenerService"
 +            android:exported="false">
 +            <intent-filter>
 +                <action android:name="com.google.android.gms.iid.InstanceID"/>
 +            </intent-filter>
 +        </service>

以下、個別クラスの実装について書きます。

1. build.gradle周りの設定

基本、参照に記したGoogleドキュメントの通りに設定すればよいです。

プロジェクトルートのbulid.gradleにplay-servicesのclasspassを設定

classpath 'com.google.gms:google-services:1.5.0-beta2'

app/build.gradleに以下をそれぞれ設定

  • plugin。これは、playserivceにまつわるAndroid Studioの便利機能を有効にするためのものっぽいので、それらが不要なら付けなくてよさそうです(確認してない)。
apply plugin: 'com.google.gms.google-services'
  • play-serviceのライブラリの依存関係を記述。
dependencies {
  compile "com.google.android.gms:play-services:8.3.0"
}

2. 独自のBroadcastReceiverの廃止

GCM受信を担っていたBroadcastReceiverは削除します。
com.google.android.gms.gcm.GcmReceiverについては、アプリ側で必要な実装はありません。

3. IntentServiceを拡張していたクラスを、GcmListenerServiceの拡張クラスに置き換える

これまでは、2.で消し去ったBroadcastReceiverからIntentServiceを起動し、onHandleIntent()にてノーティフィケーションバーに通知を出すなどの処理をしていたと思いますが、この、onHandleIntent()の処理をまるごと、GcmListenerServiceのonMessageReceived()に移せばOKです。
変わるところと言えば、onHandleIntent()で渡ってきていたIntentの変わりに、onMessageReceived()ではBundleが渡ってくるので、IntentからBundleを抜き出す処理が無くなることぐらいです。

4. MyInstanceIDListenerServiceとRegistrationIntentServiceの実装

これはGoogleのサンプルを見るのが早いでしょう。

[MyInstanceIDListenerService]
https://github.com/googlesamples/google-services/blob/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart/MyInstanceIDListenerService.java
[RegistrationIntentService]
https://github.com/googlesamples/google-services/blob/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart/RegistrationIntentService.java

アプリ独自でRegistration IDを取得する実装を書く場合には、RegistrationIntentServiceから以下のように抜粋してくればよいでしょう。

Activityとか
import com.google.android.gms.iid.InstanceID;
import com.example.R;
...

    // SENDER_IDには自身のアプリのIDを入れる
    String senderId = context.getString(SENDER_ID);
    InstanceID insId = InstanceID.getInstance(context);
    if (enabled) {
        // GCM有効にする場合はこちら
        regId = insId.getToken(senderId, GoogleCloudMessaging.INSTANCE_ID_SCOPE);
    } else {
        // 無効にする場合はこちら
        insId.deleteToken(senderId, GoogleCloudMessaging.INSTANCE_ID_SCOPE);
    }

サーバー側

こちらはとてもらくちんでエンドポイントを3.0用のそれに変更するだけでした。
送信するデータ構造などは2.0から引き継げるようです。

-   my $url = 'https://android.googleapis.com/gcm/send'; # GCM 2.0
+   my $url = 'https://gcm-http.googleapis.com/gcm/send'; # GCM 3.0

参照

Googleのドキュメント。

46
42
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
42