記事の趣旨
前の記事でサーバからAndroidにpush通知できることを確認したので,最後にそれをトリガとして,Android側で処理を走らせる方法を確認する.
1. Android側の処理方法
こちらにまとめられているとおり,アプリがフォアグラウンドに存在する場合と,バックグラウンドに存在する場合とで,扱いが微妙に変わる.それぞれ以下に示す.
1.1 フォアグラウンドにいる場合:FirebaseMessagingService
アプリがフォアグラウンドにいる場合,com.google.firebase.messaging.FirebaseMessagingService
パッケージのFirebaseMessagingService
クラスを拡張することでメッセージを受信できる.2つ前の記事で言うところのMyFirebaseMessagingService.kt
がそれに該当する.以下ではこれをイジっていうことになる.
FirebaseMessagingService
クラスの仕様はこちらにリファレンスはまとめられている.いくつかのコールバックメソッドが用意されており,拡張クラスではこれらをoverrideしていくことになる.
-
onDeletedMessages()
:端末が長時間サーバにアクセスしないなど,何かしらの理由でメッセージが長期間放置された結果としてメッセージが削除されたとき. -
onDestroy()
:何も書いてないので不明.おそらくアプリをキルするときに走る. -
onMessageReceived(RemoteMessage message)
:メッセージを受信したとき. -
onMessageSent(String msgId)
:GCMのconnection serverへのメッセージ送信が成功したとき. -
onNewToken(String token)
:新しいトークンが生成されたとき. -
onSendError(String msgId, Exception exception)
:GCMのconnection serverへのメッセージ送信が失敗したとき.
1.2 バックグラウンドにいる場合:Intentの拡張部分
アプリがバックグラウンドにいる場合,通知はデバイスのシステムトレイに配信され、データ ペイロードはランチャー アクティビティのインテントの追加部分に配信されます。
と書いてある.色々確認したところintent.getExtras()
から取り出せば良い模様.
1.3 実装例
サーバから送信されるメッセージは前の記事とほぼ同様.ただしdata部のみ以下のように修正.
data={
'date': '20200628',
'message': 'これはテストメッセージです'
}
クライアント側のうちMyFirebaseMessagingService.kt
はこんな感じ.
class MyFirebaseMessagingService: FirebaseMessagingService() {
override fun onNewToken(token: String) {
Log.d(TAG, "Refreshed token: $token")
}
override fun onMessageReceived(p0: RemoteMessage) {
super.onMessageReceived(p0)
val date = p0.data["date"]!!.toInt()
val message = p0.data["message"]!!
val dao = NotificationsDAO(this)
dao.createNotification(MyNotification(-1, date, message)) //MySQLにデータを格納している(説明は省略)
}
}
そしてMainActivity.kt
は以下のとおり.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
super.onStart()
val dao = NotificationsDAO(this)
if (intent.getExtras() != null) {
val date = intent.getExtras().getString("date").toInt()
val message = intent.getExtras().getString("message")
dao.createNotification(MyNotification(-1, date, message)) //SQLiteにデータを格納している(説明は省略)
}
val messageList = dao.getAll() //SQLiteからデータを全件取得してきている(説明は省略)
val listView: ListView = findViewById(R.id.listView)
listView.adapter = MessageListAdapter(this, android.R.layout.simple_list_item_1, messageList.take(10))
}
}
この状態でサーバからリクエストを発出したところ,期待どおり通知が飛び,かつ図1のとおり,そのデータがAndroid側のSQLiteに格納されることを確認できた.(ListView
の表示が整形されているのはMessageListAdapter
クラスによるもの.今回は説明を省略する)
一通りやりたいことは確認できたので,今回の調査は一旦これで終わり.