GoogleのAPIを用いてAndroid端末へのPUSHとステータスバーへの通知の表示メモ
クライアント(Android)
AndroidでPUSH通知をするための準備はhttp://dev.classmethod.jp/smartphone/android/gcm/に書いてあります。
本当に参考になりました。
ここからは上のリンクからの変更点と追加点についてです。
Google Developers Consoleでの手順が多少変わっているので、そこについて説明します。
まず、https://console.developers.google.com/projectにアクセスし、既存のprojectか"CREATE PROJECT"を選択します。
projectを作成or選択してprojectのページを開きます。
ページ上部の"Project Number"は控えておきましょう。
そして、左側のサイドメニューの"APIs & auth" > "APIs" から"Google Cloud Messaging for Android"のSTATUSをONにします。
なお、公式のドキュメントはここです。
次に、"APIs & auth" > "Credentials"で"Public API access"の"CREATE NEW KEY"を選択し、新しくAPI keyを取得します。
表示されるダイアログでは"Server Key"を選択し、IPアドレスは0.0.0.0を入力します。
ここは必要があれば変更しましょう。
テスト用であれば0.0.0.0で問題ありません。多分。
GcmBroadcastReceiver.javaは上のリンクのものをそのまま利用させてもらいます。
次に、GcmIntentService.javaを通知のために書き換えます。
public class GcmIntentService extends IntentService {
private static final String TAG = GcmIntentService.class.getSimpleName();
private Notification notification;
private NotificationManager nm;
public GcmIntentService() {
super("GcmIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.v(TAG, "onHandleIntent");
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
Log.d(TAG, "messageType: " + messageType + ",body:" + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
Log.d(TAG,"messageType: " + messageType + ",body:" + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
Log.d(TAG,"messageType: " + messageType + ",body:" + extras.toString());
}
}
// ここまでhttp://dev.classmethod.jp/smartphone/android/gcm/のものとほぼ同じ
// extrasに、サーバーからのdataが入っている
// ここでは、すべて文字列として格納してある
Log.v(TAG, extras.toString());
int userId = Integer.parseInt(extras.getString("user_id"));
String text = extras.getString("text");
// 通知を開くとMainActivityが表示されるようにする
Intent i = new Intent(getApplicationContext(), MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
i.setType("notification");
i.putExtra("user_id", userId);
i.putExtra("text", text);
// 第4引数を0にすると、Intentのextrasだけ更新されず、通知のテキストは違うのにextrasだけ同じなため、
// Intent先のMainActivityでextrasを取得すると同じ値しかとれなくなる事態に
PendingIntent pi = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder notificationBuilder =
new Notification.Builder(getApplicationContext())
.setContentIntent(pi)
.setSmallIcon(R.drawable.icon_small)
.setTicker("通知がきました") // 通知が来た時にステータスバーに表示されるテキスト
.setContentTitle("通知のタイトル") // 通知バーを開いた時に表示されるタイトル
.setContentText("通知のテキスト") // タイトルの下に表示されるテキスト
.setWhen(System.currentTimeMillis()); // 通知が表示されるタイミング?
long[] vibrate_ptn = {0, 100, 300, 1000}; // 振動パターン(適当)
notification = notificationBuilder.build();
notification.vibrate = vibrate_ptn;
notification.defaults |= Notification.DEFAULT_LIGHTS; // デフォルトLED点滅パターンを設定
notification.flags = Notification.FLAG_ONGOING_EVENT;
// NotificationManagerのインスタンス取得
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(R.string.app_name, notification); // 設定したNotificationを通知する
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
nm.cancel(R.string.app_name);
}
}
続いて通知をタップした時の動作として起動されるMainActivityです。
大体上のリンクのものでいいですが、onCreate
に以下のコードを追加します。
// notification表示関係
Intent intent = getIntent();
String intentType = intent.getType();
if (intentType != null && intentType.equals("notification")) {
Log.v(TAG + " extras", intent.getExtras().toString());
// extrasからGcmIntentService.javaでいれたデータを取り出す
int user_id = intent.getIntExtra("user_id", 0);
String text = intent.getStringExtra("text");
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// ダイアログの表示
Toast.makeText(this, text, Toast.LENGTH_LONG);
}
registerInBackground()
によってLog catにregistrationIdが表示されるので、これを控えます。
アプリケーションとして実装するなら、このIDをサーバーに渡して保存するようにします。
サーバー(Python)
pythonからはrequests
を利用してGoogleへリクエストを送ります。
import requests
import json
def push_notificate(user_id, text):
'''エラーが出るとrにエラーメッセージが入る
これを呼び出せばAndroidに通知が行く
'''
gcm_url = 'https://android.googleapis.com/gcm/send'
# 上で控えたregistrationIdとAPI key
regid = REGID
key = "key=" + APIKEY
headers = {'content-type': 'application/json', 'Authorization': key}
# 渡すデータは適当です。
# dictのkeyはAndroidのextrasのkeyと合わせましょう
params = json.dumps(\
{'registration_ids': [regid], \
'data': {'id': user_id, 'text': text}})
r = requests.post(gcm_url, data=params, headers=headers)
print r.text
return
requests
でbasic認証をクリアするには引数にauth=(username, password)
を渡しますが、今回はheadersに入れて渡します。
これで大丈夫だと思います。