##AndroidのPush通知を試してみよう
AndroidのPush通知って難しそうなイメージがありますよね。最近はFirebaseなどのmBaaSがあるので比較的簡単になってきました。しかし本来どのようにPush通知を送るのか、Firebaseなどではなく自分のサーバーからPush通知をどのような方法で出したらいいのか分からない方がいると思います。そこで今回はPush通知の出し方を簡単に紹介したいと思います。
##この記事について
##対象者
- Push通知の仕組みを知りたい
- 普段モバイルアプリを開発している
- サーバーはあまり得意ではない
- Firebaseもいいが、いつかは自分のサーバーやmBaaS以外のサーバーからPush通知を送りたい
Push通知の大体の仕組み
- Firebaseから固有IDを振ってもらう
- そのIDをサーバー管理者に伝える
- サーバーがFirebaseに対して、このIDに通知を出してくれとお願いする
- FirebaseがAndroid端末にPush通知を発行する
##今からやるならGCMではなくFCMを使おう
こちらにも書いてありますが、これからのPush通知はGCMではなくFCMを使用することを強く推奨しています。
今後のGCMについて
2019年4月11日にGCMは使えなくなるみたいなので、GCMを使っている人は移行しましょう。
GCM APIを使用するプロジェクトをご利用の場合は、2019年4月11日より前にクライアントとサーバーのコードをFCMを使うように変更する必要があります。既存のGCMトークンはFCMで引き続き使用でき、既存のユーザーに送信する機能は失われません。
if you have projects that are still using the GCM APIs, you will need to update your client and server code to use FCM before April 11, 2019. Your existing GCM tokens will continue to work with FCM so you won’t lose the ability to send to your existing users.
実装の流れ
- Firebaseの導入
- Androidプロジェクトのコードを準備
- アプリを実行してInstanceIDを取得する
- PostmanでFCMサーバーにデータを投げる
Firebase導入
- 新規プロジェクトの作成
- google-services.jsonをダウンロード
新規プロジェクトの作成
Firebaseにログイン
コンソールに行くと「新規プロジェクトの作成」と「Googleプロジェクトをインポート」がある。
既にGoogle Maps APIやGAEなどを使用しており、同じプロジェクトにFirebaseを入れたい人はインポートを選ぶ。
新規プロジェクトを作成した後は、[AndroidアプリにFirebaseを追加]を選択
すると以下のような画面がでてきます。
必要な情報を入力しましょう。
デバッグ用のkeystoreは以下のようなコードで取得可能です。
keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore
keytool -exportcert -list -v \
-alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore
google-services.json のインポート
アプリを作成すると、google-services.jsonが生成され自動的にダウンロードされます。
こちらのファイルをAndroidプロジェクトのappの配下に入れましょう。
Androidプロジェクトのコードを準備
プロジェクトレベルのbuild.gradleに以下を追加
buildscript {
dependencies {
// ここに追加
classpath 'com.google.gms:google-services:3.0.0'
}
}
アプリレベルのbuild.gradleに以下を追加
dependencies {
compile "com.google.firebase:firebase-messaging:10.2.4"
}
// ファイルの一番下に追加
apply plugin: 'com.google.gms.google-services'
※ apply plugin: 'com.google.gms.google-services'
はファイルの一番下に設置してください。
Push通知に使用するIDを取得するためのMyInstanceIDListenerServiceクラスを作成
こちらのIDはPush通知に使用するのでサーバー管理者に送信する。しかし今回はサーバーを使用しないのでサーバー管理者にIDを送信する処理は省略する。
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
public class MyInstanceIDListenerService extends FirebaseInstanceIdService {
private static final String TAG = MyInstanceIDListenerService.class.getSimpleName();
@Override
public void onTokenRefresh() {
//ここで取得したInstanceIDをサーバー管理者に伝える
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
}
}
AndroidManifestにMyInstanceIDListenerServiceを追加
<application>
<service
android:name=".MyInstanceIDListenerService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<application/>
Push通知を受け取るレシーバークラスを作成
ここで受け取った内容を通知する処理も追加します。
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import java.util.Map;
public class MyFcmListenerService extends FirebaseMessagingService {
private final static String TAG = MyFcmListenerService.class.getSimpleName();
@Override
public void onMessageReceived(RemoteMessage message){
String from = message.getFrom();
Map data = message.getData();
Log.d(TAG, "from:" + from);
Log.d(TAG, "data:" + data.toString());
String msg = data.get("data").toString();
sendNotification(msg);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0 , intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Push通知のタイトル")
.setSubText("Push通知のサブタイトル")
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build());
}
}
AndroidManifestにMyFcmListenerServiceを追加
<application>
<service
android:name=".MyFcmListenerService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<application/>
Push通知を購読or解除
最後にこちらのメソッドを実行すればPush通知の購読or解除が可能です。
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.google.firebase.messaging.FirebaseMessaging;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Push通知の購読開始
FirebaseMessaging.getInstance().subscribeToTopic("mytopic");
//購読解除
FirebaseMessaging.getInstance().unsubscribeFromTopic("mytopic");
}
}
アプリを実行してInstanceIDを取得する
アプリを実行してInstanceIDを取得しそのIDをメモしておいてください。
LogcatにIDが表示されるはずです。
MyInstanceIDListenerService: Refreshed token: xxxxxxxxxxxxxxxxxxxxx
Postmanに必要情報を入力する
本来はサーバーからPush通知を送信しますが、今回は手動で送信したいと思います。送信にはHTTPリクエストを簡単作れる、GoogleChromeExtensionの Postman を使いたいと思います。
Postmanについてはこちらを参照ください。
サーバーキーを取得しよう
Firebaseコンソールのクラウドメッセージングという項目からサーバーキーをメモしておいてください。
PostmanからPush通知!!
Postmanに必要情報を入れる
1.Postmanのリクエスト方法を「Post」にする
2.URLに https://fcm.googleapis.com/fcm/send
を入力
3.HeadersのKeyに Authorization
とContent-Type
を追加
4.HeadersのValueにkey=サーバーキー
とapplication/json
を入力
※サーバーキーは先ほどFirebaseのコンソールで取得したものを入れてください。
5.BodyのrawにJson形式のテキストを作ってください。
6.idに先ほどLogcatで取得したトークンを入れてください。
Push通知を送信する
ここまで入力が終えたら終了です。Sendボタンを押してPush通知を試してみてください。以下の様にAndroidに通知が表示されれば成功です。
※送信時点でエラーが起きるとPostmanにエラーが返ってきます。
Push通知の大体の仕組みを見ていただきました。あとはPostmanでやっている処理をサーバーに実装するだけでサーバーからPush通知を作成することができます。Push通知を活用して1ランク上の開発にトライしてみてください。