8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

push通知をトリガとしてAndroidに処理を実行させる

Posted at

記事の趣旨

前の記事でサーバから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クラスによるもの.今回は説明を省略する)

Screenshot_20200628-150346.png
図1 データ受信後のアプリの表示.

一通りやりたいことは確認できたので,今回の調査は一旦これで終わり.

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?