▼Androidメモ▼

Google Cloud Messaging



Google Cloud Messaging(GCM)を利用するプログラムを作成する。



送信者IDとAPI keyの取得
  1. Google APIs Console pageを開き、Googleアカウントでログイン。
  2. 「Create project...」ボタンを押す。
  3. 左端リストの「Service」をクリック。
  4. 「Google Cloud Messaging for Android」をONにする。
  5. 左端リストの「API Access」をクリック。
  6. 「Create」ボタンを押す。
  7. 「Key for server apps」が追加されているので、API keyをメモし、post.phpの「$apikey」に指定。
  8. Google APIs Console pageにログインした時にURLに表示される数値(「#project:XXXXXXXXXXXX:access」のXXXXXXXXXXXX)をメモし、コード内のSENDER_IDに代入。
登録IDの取得と通知の実行
  1. GCMを実行すると、登録IDが表示されるのでメモし、post.phpの「$regId」に指定。
    実際にはHTTP通信で、アプリから自作サーバーに通知して保存。
  2. post.phpの実行。

アプリのソースコード
GCMEx.java
package net.npaka.gcmex;

import com.google.android.gcm.GCMRegistrar;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.TextView;

//Google Cloud Messaging
public class GCMEx extends Activity {
//定数
public final static String
SENDER_ID="送信者IDをココに記述", //送信者ID
EXTRA_MESSAGE="message", //メッセージ引数
SHOW_MESSAGE="net.npaka.gcmex.SHOW_MESSAGE";//メッセージ表示アクション

//UI
private TextView textView;
private Handler handler=new Handler();

//アクティビティ起動時に呼ばれる
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
requestWindowFeature(Window.FEATURE_NO_TITLE);

//端末とマニフェストのチェック
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);

//レイアウトの生成
LinearLayout layout=new LinearLayout(this);
layout.setBackgroundColor(Color.WHITE);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);

//テキストビューの生成
textView=new TextView(this);
textView.setTextSize(16.0f);
textView.setTextColor(Color.BLACK);
layout.addView(textView);

//メッセージレシーバーの登録
registerReceiver(messageReceiver,
new IntentFilter(SHOW_MESSAGE));

//登録IDの取得
final String regId=GCMRegistrar.getRegistrationId(this);
showMessage(this,"登録ID> "+regId);

//アプリ登録の開始
if (regId.equals("")) {
showMessage(this,"アプリ登録");
GCMRegistrar.register(this,SENDER_ID);
}
//端末登録
else if (!GCMRegistrar.isRegisteredOnServer(this)) {
handler.post(new Runnable(){public void run(){
//端末登録
boolean registered=register(GCMEx.this,regId);

//端末登録に失敗した時は、アプリ登録解除
if (!registered) {
showMessage(GCMEx.this,"アプリ登録解除");
GCMRegistrar.unregister(GCMEx.this);
}
}});
}
}

//アクティビティ破棄時に呼ばれる
@Override
protected void onDestroy() {
//メッセージレシーバーの解除
unregisterReceiver(messageReceiver);

//GCMRegisterの破棄
GCMRegistrar.onDestroy(this);
super.onDestroy();
}

//GCM管理サーバに端末登録
public static boolean register(Context context,String regId) {
showMessage(context,"端末登録");
//<<自作GCM管理サーバで端末登録する処理をココに記述>>

//端末登録を指定
GCMRegistrar.setRegisteredOnServer(context,true);
return true;
}

//GCM管理サーバから端末登録解除
public static void unregister(Context context,String regId) {
showMessage(context,"端末登録解除");
//<<自作GCM管理サーバで端末登録解除する処理をココに記述>>

//端末登録解除を指定
GCMRegistrar.setRegisteredOnServer(context,false);
}

//メッセージの表示
public static void showMessage(Context context,String message) {
Intent intent=new Intent(SHOW_MESSAGE);
intent.putExtra(EXTRA_MESSAGE,message);
context.sendBroadcast(intent);
}

//メッセージレシーバー
private final BroadcastReceiver messageReceiver=new BroadcastReceiver() {
//受信時に呼ばれる
@Override
public void onReceive(Context context,Intent intent) {
String msg=intent.getExtras().getString(EXTRA_MESSAGE);
android.util.Log.e("debug",msg);
textView.append(msg+"\n");
}
};
}

GCMIntentService.java
package net.npaka.gcmex;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;

//GCMサーバからの情報を受信するサービス
public class GCMIntentService extends GCMBaseIntentService {

//コンストラクタ
public GCMIntentService() {
super(GCMEx.SENDER_ID);
}

//アプリ登録時に呼ばれる
@Override
protected void onRegistered(Context context,String regId) {
GCMEx.register(context,regId);
GCMEx.showMessage(context,"登録完了>"+regId);
}

//アプリ登録解除時に呼ばれる
@Override
protected void onUnregistered(Context context,String regId) {
//端末登録解除
if (GCMRegistrar.isRegisteredOnServer(context)) {
GCMEx.unregister(context,regId);
}
GCMEx.showMessage(context,"登録解除完了");
}

//メッセージ受信時に呼ばれる
@Override
protected void onMessage(Context context,Intent intent) {
String message=intent.getExtras().getString("message");
GCMEx.showMessage(context,message);
showNotification(context,R.drawable.ic_launcher,
"GCMからのメッセージ","GCMからのメッセージ",message,"");
}

//削除メッセージ通知時に呼ばれる
@Override
protected void onDeletedMessages(Context context,int total) {
String message="削除メッセージ>"+total;
GCMEx.showMessage(context,message);
showNotification(context,R.drawable.ic_launcher,
"GCMからのメッセージ","GCMからのメッセージ",message,"");
}

//エラー通知時に呼ばれる
@Override
public void onError(Context context,String errorId) {
GCMEx.showMessage(context,"エラー>"+errorId);
}

//再試行可能な登録エラー時に呼ばれる
@Override
protected boolean onRecoverableError(Context context,String errorId) {
GCMEx.showMessage(context,"再試行可能な登録エラー>"+errorId);
return super.onRecoverableError(context, errorId);
}

//ノティフィケーションの表示
private static void showNotification(Context context,
int iconId,String ticker,String title,String text,String info) {
//ノティフィケーションオブジェクトの生成
Notification.Builder builder=new Notification.Builder(context);
builder.setWhen(System.currentTimeMillis());
builder.setTicker(ticker);
builder.setContentTitle(title);
builder.setContentText(text);
builder.setContentInfo(info);
builder.setSmallIcon(iconId);
Intent intent=new Intent(context,GCMEx.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
builder.setContentIntent(PendingIntent.getActivity(
context,0,intent, PendingIntent.FLAG_ONE_SHOT));

//ノティフィケーションマネージャの取得
NotificationManager nm=(NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);

//ノティフィケーションのキャンセル
nm.cancel(0);

//ノティフィケーションの表示
nm.notify(0,builder.getNotification());
}
}

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.npaka.gcmex"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="13" android:targetSdkVersion="16"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="net.npaka.gcmex.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="net.npaka.gcmex.permission.C2D_MESSAGE" />
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".GCMEx"
android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="net.npaka.gcmex" />
</intent-filter>
</receiver>

<service android:name=".GCMIntentService" />
</application>

</manifest>

PHPのソースコード

post.php
<?php
require_once "HTTP/Request.php";

$regid = "登録IDをココに記述"; //登録ID
$apikey = "API keyをココに記述";//API Key

$rq = new HTTP_Request("https://android.googleapis.com/gcm/send");
$rq->setMethod(HTTP_REQUEST_METHOD_POST);
$rq->addHeader("Authorization", "key=".$apikey);
$rq->addPostData("registration_id", $regid);
$rq->addPostData("collapse_key", "1");
$rq->addPostData("data.message", $_POST['message']);

if (!PEAR::isError($rq->sendRequest())) {
print "\n" . $rq->getResponseBody();
} else {
print "\nError";
}

?>
<hr />
<input type="button" value="back" onclick="javascript:history.back();" />

−戻る−