从FCM通知中获取意图数据,在Fragment中无需点击通知。

huangapple go评论75阅读模式
英文:

Get intent data from FCM Notification in Fragment without clicking on the notification

问题

当我的应用程序收到带有数据有效负载的通知时,它会出现在系统托盘中,我可以点击通知以在我的启动器活动中接收数据,然后可以将其传递给我的片段:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {   
        // 通知数据
        val user2 = intent?.extras?.getString("user2")
        val intent = Intent(this, HomeActivity::class.java)
        intent.putExtra("user2", user2)
        startActivity(intent)
        finish()
    }
}

但是,如果通知通过并且用户在不点击通知的情况下打开应用程序,它会直接跳过MainActivity并直接进入片段。这意味着我无法拦截来自通知的意图数据。

是否有其他方法可以从我的片段中访问通知数据?

英文:

When my app receives a notification with a data payload, it arrives in the system tray and I can click the notification to receive the data in my launcher activity, which I can then pass on to my 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()

从FCM通知中获取意图数据,在Fragment中无需点击通知。

However, if a notification comes through and the user opens the app without clicking on the notification, it bypasses MainActivity and goes directly to the Fragment. This means I can't intercept the intent data from the notification.

Is there another way I can access the notification data from my Fragment?

答案1

得分: 1

以下是翻译好的部分:

一种解决方案是根据您的要求将数据存储在共享偏好或 SQLite 数据库中,在 onMessageReceived 中。如果您希望在应用程序处于前台或后台时都接收 onMessageReceived,那么不要始终向用户发送通知消息1,而是始终发送数据消息2 并使用 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)
    }
}

您可以直接在片段中使用以下方法访问数据,无需从活动传递数据给片段。

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"]) // 使用首选键
英文:

One solution is to store the data in shared preference or sqlite db depending on your requirment, in onMessageReceived, and if you want onMessageRecieved irrespective of app is in foreground or backgroun, then instead of sending notification message too user always send data message to user and show show notification using NotificationBuilder instead of default FCM notification, this way you'll always have data in local persistence.

override fun onMessageReceived(remoteMessage: RemoteMessage) {
        val sp = applicationContext.getSharedPreferences(&quot;NOTIFICATION_SHARED_PREFERENCE&quot;,Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.putString(&quot;data&quot;,remoteMessage.data.toString())
        editor.commit()

        val pendingIntent:PendingIntent = PendingIntent.getActivity(this,Random().nextInt(),intent,0)
        showNotification(remoteMessage.data[&quot;title&quot;]!!,remoteMessage.data[&quot;body&quot;]!!,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)
        }
    }

and you can access the data directly in fragment using following method, no need to pass data to fragment from activity.


            val sp = applicationContext.getSharedPreferences(&quot;NOTIFICATION_SHARED_PREFERENCE&quot;,Context.MODE_PRIVATE)
            val type = object : TypeToken&lt;HashMap&lt;String,String&gt;&gt;() {}.type
            val data:HashMap&lt;String,String&gt; = Gson().fromJson(sp.getString(&quot;data&quot;,&quot;&quot;),type)
            intent.putExtra(&quot;user2&quot;,data[&quot;user2&quot;])//use the prefered key
  

huangapple
  • 本文由 发表于 2020年1月3日 15:37:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/59574817.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定