在 Fragment 中获取 FCM Notification 的意图数据,无需点击通知
Get intent data from FCM Notification in Fragment without clicking on the notification
当我的应用程序收到带有数据负载的通知时,它会到达系统托盘,我可以单击通知以在我的启动器 activity 中接收数据,然后我可以将其传递到我的 Fragment :
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Notification data
val user2 = intent?.extras?.getString("user2")
val intent = Intent(this, HomeActivity::class.java)
intent.putExtra("user2", user2)
startActivity(intent)
return finish()
但是,如果收到通知并且用户在未单击通知的情况下打开应用程序,它会绕过 MainActivity
并直接转到片段。这意味着我无法从通知中拦截意图数据。
还有其他方法可以从我的 Fragment 访问通知数据吗?
一个解决方案是根据您的要求将数据存储在共享首选项或 sqlite 数据库中,在 onMessageReceived 中,如果您想要 onMessageRecieved 而不管应用程序是在前台还是后台,那么而不是发送 notification message too user always send data message 到user 和 show 使用 NotificationBuilder 而不是默认的 FCM 通知显示通知,这样您将始终在本地持久性中拥有数据。
override fun onMessageReceived(remoteMessage: RemoteMessage) {
val sp = applicationContext.getSharedPreferences("NOTIFICATION_SHARED_PREFERENCE",Context.MODE_PRIVATE)
val editor = sp.edit()
editor.putString("data",remoteMessage.data.toString())
editor.commit()
val pendingIntent:PendingIntent = PendingIntent.getActivity(this,Random().nextInt(),intent,0)
showNotification(remoteMessage.data["title"]!!,remoteMessage.data["body"]!!,pendingIntent)
}
private fun showNotification(title:String,description: String,pendingIntent: PendingIntent){
val icon = R.drawable.ic_notification
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(icon)
.setContentTitle(title)
.setContentText(description)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setGroup(GROUP_KEY_PUSH_MESSAGES)
.setContentIntent(pendingIntent)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setAutoCancel(true)
.build()
NotificationManagerCompat.from(applicationContext).apply {
notify(Random().nextInt(),notification)
}
}
并且您可以使用以下方法直接在片段中访问数据,无需将数据从 activity.
传递到片段
val sp = applicationContext.getSharedPreferences("NOTIFICATION_SHARED_PREFERENCE",Context.MODE_PRIVATE)
val type = object : TypeToken<HashMap<String,String>>() {}.type
val data:HashMap<String,String> = Gson().fromJson(sp.getString("data",""),type)
intent.putExtra("user2",data["user2"])//use the prefered key
当我的应用程序收到带有数据负载的通知时,它会到达系统托盘,我可以单击通知以在我的启动器 activity 中接收数据,然后我可以将其传递到我的 Fragment :
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Notification data
val user2 = intent?.extras?.getString("user2")
val intent = Intent(this, HomeActivity::class.java)
intent.putExtra("user2", user2)
startActivity(intent)
return finish()
但是,如果收到通知并且用户在未单击通知的情况下打开应用程序,它会绕过 MainActivity
并直接转到片段。这意味着我无法从通知中拦截意图数据。
还有其他方法可以从我的 Fragment 访问通知数据吗?
一个解决方案是根据您的要求将数据存储在共享首选项或 sqlite 数据库中,在 onMessageReceived 中,如果您想要 onMessageRecieved 而不管应用程序是在前台还是后台,那么而不是发送 notification message too user always send data message 到user 和 show 使用 NotificationBuilder 而不是默认的 FCM 通知显示通知,这样您将始终在本地持久性中拥有数据。
override fun onMessageReceived(remoteMessage: RemoteMessage) {
val sp = applicationContext.getSharedPreferences("NOTIFICATION_SHARED_PREFERENCE",Context.MODE_PRIVATE)
val editor = sp.edit()
editor.putString("data",remoteMessage.data.toString())
editor.commit()
val pendingIntent:PendingIntent = PendingIntent.getActivity(this,Random().nextInt(),intent,0)
showNotification(remoteMessage.data["title"]!!,remoteMessage.data["body"]!!,pendingIntent)
}
private fun showNotification(title:String,description: String,pendingIntent: PendingIntent){
val icon = R.drawable.ic_notification
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(icon)
.setContentTitle(title)
.setContentText(description)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setGroup(GROUP_KEY_PUSH_MESSAGES)
.setContentIntent(pendingIntent)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setAutoCancel(true)
.build()
NotificationManagerCompat.from(applicationContext).apply {
notify(Random().nextInt(),notification)
}
}
并且您可以使用以下方法直接在片段中访问数据,无需将数据从 activity.
传递到片段
val sp = applicationContext.getSharedPreferences("NOTIFICATION_SHARED_PREFERENCE",Context.MODE_PRIVATE)
val type = object : TypeToken<HashMap<String,String>>() {}.type
val data:HashMap<String,String> = Gson().fromJson(sp.getString("data",""),type)
intent.putExtra("user2",data["user2"])//use the prefered key