いまだにgcm.jarを使っていると、少し前から、警告のような通知を受信するようになりました。
そこで最新版で実装しようとしたのですが、日本語情報があまりなかったので、実装ついでにまとめました。
なお、サーバー側は担当者でないので、curlでのテストまでにとどめます。
1. 前提条件
AndroidStudio 1.5+ (Gradle Plugin 1.3+)
GooglePlayServices 8.3+
2. Google Developer Consoleでプロジェクトを設定する
Android Developer Consoleじゃないので要注意。
2.1. 新プロジェクトの作成
(1) Google Developer Consoleへいってサインインする。
(2) 「Google APIを利用する」をクリック
(3) 任意のプロジェクト名を入力し、その他の内容を確認して、「作成」ボタンをクリック
一番下の利用規約に同意を意味する「はい」を選択しないと作成ボタンが押せるようになりません。
クリック後、プロジェクトが作成されるまで少し待つ。
2.2. GCM APIを有効にする
(1) 「Mobile API」下にある「Cloud Messaging for Android」をクリック
(2) 「APIを有効にする」をクリック
(3) 「認証情報に進む」をクリック
※表示されない場合はすでにある認証情報を参照すること(プロジェクト画面の左側にあります)
(4) 「認証情報を追加」をクリック
(5) 「APIキー」をクリック
(6) 必要なキーの種類をクリック
- 「サーバーキー」はサーバーからメッセージを送信する場合に必要。
- 「Androidキー」「iOSキー」は、端末からもメッセージを送れるようにする場合に必要(?)
- 複数必要な場合は、(4)~(7)を繰り返す
(7) 任意の名前を付けて保存
(8) 表示されたAPIキーをコピーして保存しておく
プロジェクト画面の左側からも確認出来ます。
3. Androidプロジェクトを設定する
3.1. configurationファイルをダウンロードする
(1) ここの**「Get a configuration file」**項目下にある以下のボタンをクリックする
https://developers.google.com/cloud-messaging/android/client
(2) AppNameからプロジェクト名を選ぶ
(3) パッケージ名を入力する
※このパッケージ名は後から変更出来ません(多分)。前もってプロジェクトは作成しておきましょう。
(4) サポートが必要であれば、「Share your Google Mobile Developer Services data...」のチェックボックスにチェックを入れ、日本を選択する
(5) 「Choose and configure services arrow_forward」ボタンをクリック
(6) 「ENABLE GOOGLE CLOUD MESSAGING」ボタンをクリック
SenderIDをメモしておく。
※Google Developer Consoleの「ホーム」-「ダッシュボード」の「プロジェクト番号」で後から参照可。
(7) 「Generate configuration files」ボタンをクリック
(8) 「Download google-services.json」をクリックして、ファイルをダウンロードする
(9) (8)でダウンロードしたgoogle-services.jsonファイルを以下に配置する
(プロジェクトフォルダ)/app/google-services.json
※アプリフォルダ名を変更している場合は、「app」を適宜読み替えること
3.2. build.gradleに依存関係を記述する
(1) project/build.gradleを編集する
dependencies{
....
classpath 'com.google.gms:google-services:1.5.0-beta2'
}
(2) app/build.gradleに依存関係を記述する
apply plugin: 'com.google.gms.google-services'
....
dependencies{
....
compile "com.google.android.gms:play-services-gcm:8.3.0"
}
3.3. ApplicationManifest.xmlを編集する
・パーミッション関連を追記(重複に注意)
・receiverの記述(クラス名の変更不可)
・serviceの記述(3つともクラス名は任意に変更可能)
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="<your-package-name>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="<your-package-name>.permission.C2D_MESSAGE" />
<application ...>
<receiver
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.gcm" />
</intent-filter>
<!-- 4.4以前をサポートする場合は以下が必要 -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
</intent-filter>
</receiver>
<service
android:name="com.example.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name="com.example.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<service android:name="com.example.gcm.RegistrationIntentService"/>
</application>
**<your-package-name>**の箇所は自分のアプリのパッケージ名に変更する。
**com.example.**の部分も任意で変更する。
4. javaコードの実装
4.1. GcmListenerServiceクラスを実装
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService ";
@Override
public void onMessageReceived(String from, Bundle data) {
// TODO
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
}
}
4.2. InstanceIDListenerServiceクラスを実装
public class MyInstanceIDListenerService extends InstanceIDListenerService {
@Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
4.3. RegistrationIntentServiceクラスを実装
private static final String TAG = "Registration service";
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public RegistrationIntentService() {
super("Registration service");
}
@Override
protected void onHandleIntent(Intent intent) {
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Log.d(TAG, ":token=" + token);
//
registerGcmId(token);
} catch (IOException e) {
Log.d(TAG, ":IO Exception " + e.getMessage());
}
}
protected void registerGcmId(String token){
// TODO このトークンをPush送信用サーバーに送信する
}
ここで撮れたトークンIDを後述のcurlでの送信テストでも使います。
4.4. 起動時の処理を実装
public void onCreate(...){
// GooglePlayServiceがあれば、PUSHを登録
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
private boolean checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.d(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
5. 送信テスト
curlを使います。Windowsの人は頑張って入れて下さい。
$ curl --header "Authorization: key=サーバーAPIキー" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send -d "{\"registration_ids\":[\"デバイストークンID\"],\"data\":{\"message\":\"Hello\"}}"
サーバーAPIキーとデバイストークンIDを自分の物に置き換えて下さい。
※連続して何度も送っていると、制限が入るようで、時間が異様にかかることがあります。
6. 参考ページなど