带返回堆栈的推送通知(待处理意图,Kotlin)

发布于 2025-01-20 06:40:13 字数 5416 浏览 3 评论 0原文

我面临着将启动 URL 从一个活动传递到另一个活动而不为我的 MainActivity 创建新意图的问题。

我有一个 webview,它与 OneSignal 推送通知一起使用。我想修改分组通知内容。

如果有办法获得我想要的结果(修改 OneSignal 的通知组布局)那就太棒了。我将简单地使用 One Signal 默认操作,这对我来说是最好的解决方案。

如果我必须以这种方式实现它: https://developer.android.com/training/notify-user/group

问题是,当我启动 MainActivity 的新子活动时,我不使用“StartActivity / StartActivityForResults”函数。 这是 OSRemoteNotificationReceivedHandler(OneSignal 类)的扩展 它在我的 MainActivity 类之外。

    class NotificationServiceExtension : OSRemoteNotificationReceivedHandler {
    @RequiresApi(Build.VERSION_CODES.N)
    override fun remoteNotificationReceived(
        context: Context,
        notificationReceivedEvent: OSNotificationReceivedEvent
    ) {
        val notification = notificationReceivedEvent.notification
        val bigText = Html.fromHtml(notification.body, FROM_HTML_MODE_LEGACY).toString()
        var smallText = Html.fromHtml(notification.additionalData["cleantitle"] as String, FROM_HTML_MODE_LEGACY).toString()
        val summaryStatistics = Html.fromHtml(notification.additionalData["setSummaryText"] as String, FROM_HTML_MODE_LEGACY).toString()

        if (smallText == "test") {
            smallText = Html.fromHtml(notification.additionalData["smalltitle"] as String, FROM_HTML_MODE_LEGACY).toString()
        }
        else{
            val name = Html.fromHtml(notification.additionalData["text"] as String, FROM_HTML_MODE_LEGACY).toString()
            smallText += " from $name"
        }

        val smallContent = RemoteViews("com.webviewapp.mywebviewapp", R.layout.small_layout_notification)
        val sum = RemoteViews("com.webviewapp.mywebviewapp", R.layout.summary_layout_notification)
        val bigContent = RemoteViews("com.webviewapp.mywebviewapp", R.layout.large_notification_layout)

        bigContent.setTextViewText(R.id.notification_title, smallText)
        bigContent.setTextViewText(R.id.notification_content, bigText)
        smallContent.setTextViewText(R.id.notification_title, smallText)
        sum.setTextViewText(R.id.notification_title, summaryStatistics)
        notificationReceivedEvent.complete(null)


        var bp: Bitmap? = null
        try {
            bp =Picasso.get().load(notification.largeIcon).get()
            smallContent.setImageViewBitmap(R.id.noti_pic, bp)
            bigContent.setImageViewBitmap(R.id.noti_pic, bp)

        }
        catch(e:Exception){
            print(e)
        }

        try {
            val fid = notification.additionalData["fid"] as String
            notificationId = fid.toInt()

        }
        catch(e:java.lang.Exception){
            notificationId += Date().time.toInt()
        }

        val notificationOpenActivity = Intent(context.applicationContext, MainActivity::class.java)
            .putExtra("launchURL", notification.additionalData["pushURL"] as String)
            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)


        val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(context.applicationContext).run {
            // Add the intent, which inflates the back stack
            addNextIntentWithParentStack(notificationOpenActivity)

            // Get the PendingIntent containing the entire back stack
            getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT)
        }


        val receivedNotification = NotificationCompat.Builder(context.applicationContext, NOTIFICATION_GROUP)
            .setSmallIcon(R.drawable.myIcon)
            .setColor(ContextCompat.getColor(context.applicationContext,R.color.blue_primary))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setStyle(NotificationCompat.DecoratedCustomViewStyle()) // to expand button
            .setAutoCancel(true)
            .setVibrate(longArrayOf(500, 500, 500))
            .setCustomBigContentView(bigContent)
            .setCustomContentView(smallContent)
            .setCustomHeadsUpContentView(sum)
            .setChannelId(NOTIFICATION_CHANNEL)
            .setGroup(NOTIFICATION_GROUP)
            .setGroupSummary(false)
            .setContentIntent(resultPendingIntent)
            .build()


        val summary = NotificationCompat.Builder(context.applicationContext, NOTIFICATION_GROUP)
            .setSmallIcon(R.drawable.myIcon)
            .setColor(ContextCompat.getColor(context.applicationContext,R.color.blue_primary))
            //.setContentTitle(summaryStatistics.toString())
            .setContentTitle(summaryStatistics)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setStyle(NotificationCompat.InboxStyle()
                .setBigContentTitle(summaryStatistics)
                .addLine(summaryStatistics)
                .setSummaryText(summaryStatistics))
            .setAutoCancel(true)
            .setChannelId(NOTIFICATION_CHANNEL)
            .setGroup(NOTIFICATION_GROUP)
            .setGroupSummary(true)
            .build()

        NotificationManagerCompat.from(context.applicationContext).apply {
            notify(notificationId, receivedNotification)
            notify(SUMMARY_ID, summary)
        }


    }
}

而且通知效果如我所愿。问题是,如果我没有从父活动创建子活动,如何将额外参数从子活动传递到其父活动?我只是想将它的 URL 加载到我的 webview 中,但也保留返回堆栈。 另外,如果我不使用该子项,如何确保不会创建多个 MainActivity?

提前致谢。

I'm facing a problem with passing the launch URL from one activity to another, without creating a new Intent for my MainActivity.

I have a webview, which is work with OneSignal push notifications. I wanted to modify the grouping notifications content.

If there's a way to get the result I want (modifying notifications group layout for OneSignal) That would be awesome. I'll simply use the One Signal default action and that would be the best solution for me.

If I have to implement it on that way:
https://developer.android.com/training/notify-user/group

The problem is, when I start a new child activity of the MainActivity, I don't use the "StartActivity / StartActivityForResults" functions.
This is the extension of OSRemoteNotificationReceivedHandler (OneSignal class)
It's outside of my MainActivity class.

    class NotificationServiceExtension : OSRemoteNotificationReceivedHandler {
    @RequiresApi(Build.VERSION_CODES.N)
    override fun remoteNotificationReceived(
        context: Context,
        notificationReceivedEvent: OSNotificationReceivedEvent
    ) {
        val notification = notificationReceivedEvent.notification
        val bigText = Html.fromHtml(notification.body, FROM_HTML_MODE_LEGACY).toString()
        var smallText = Html.fromHtml(notification.additionalData["cleantitle"] as String, FROM_HTML_MODE_LEGACY).toString()
        val summaryStatistics = Html.fromHtml(notification.additionalData["setSummaryText"] as String, FROM_HTML_MODE_LEGACY).toString()

        if (smallText == "test") {
            smallText = Html.fromHtml(notification.additionalData["smalltitle"] as String, FROM_HTML_MODE_LEGACY).toString()
        }
        else{
            val name = Html.fromHtml(notification.additionalData["text"] as String, FROM_HTML_MODE_LEGACY).toString()
            smallText += " from $name"
        }

        val smallContent = RemoteViews("com.webviewapp.mywebviewapp", R.layout.small_layout_notification)
        val sum = RemoteViews("com.webviewapp.mywebviewapp", R.layout.summary_layout_notification)
        val bigContent = RemoteViews("com.webviewapp.mywebviewapp", R.layout.large_notification_layout)

        bigContent.setTextViewText(R.id.notification_title, smallText)
        bigContent.setTextViewText(R.id.notification_content, bigText)
        smallContent.setTextViewText(R.id.notification_title, smallText)
        sum.setTextViewText(R.id.notification_title, summaryStatistics)
        notificationReceivedEvent.complete(null)


        var bp: Bitmap? = null
        try {
            bp =Picasso.get().load(notification.largeIcon).get()
            smallContent.setImageViewBitmap(R.id.noti_pic, bp)
            bigContent.setImageViewBitmap(R.id.noti_pic, bp)

        }
        catch(e:Exception){
            print(e)
        }

        try {
            val fid = notification.additionalData["fid"] as String
            notificationId = fid.toInt()

        }
        catch(e:java.lang.Exception){
            notificationId += Date().time.toInt()
        }

        val notificationOpenActivity = Intent(context.applicationContext, MainActivity::class.java)
            .putExtra("launchURL", notification.additionalData["pushURL"] as String)
            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)


        val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(context.applicationContext).run {
            // Add the intent, which inflates the back stack
            addNextIntentWithParentStack(notificationOpenActivity)

            // Get the PendingIntent containing the entire back stack
            getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT)
        }


        val receivedNotification = NotificationCompat.Builder(context.applicationContext, NOTIFICATION_GROUP)
            .setSmallIcon(R.drawable.myIcon)
            .setColor(ContextCompat.getColor(context.applicationContext,R.color.blue_primary))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setStyle(NotificationCompat.DecoratedCustomViewStyle()) // to expand button
            .setAutoCancel(true)
            .setVibrate(longArrayOf(500, 500, 500))
            .setCustomBigContentView(bigContent)
            .setCustomContentView(smallContent)
            .setCustomHeadsUpContentView(sum)
            .setChannelId(NOTIFICATION_CHANNEL)
            .setGroup(NOTIFICATION_GROUP)
            .setGroupSummary(false)
            .setContentIntent(resultPendingIntent)
            .build()


        val summary = NotificationCompat.Builder(context.applicationContext, NOTIFICATION_GROUP)
            .setSmallIcon(R.drawable.myIcon)
            .setColor(ContextCompat.getColor(context.applicationContext,R.color.blue_primary))
            //.setContentTitle(summaryStatistics.toString())
            .setContentTitle(summaryStatistics)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setStyle(NotificationCompat.InboxStyle()
                .setBigContentTitle(summaryStatistics)
                .addLine(summaryStatistics)
                .setSummaryText(summaryStatistics))
            .setAutoCancel(true)
            .setChannelId(NOTIFICATION_CHANNEL)
            .setGroup(NOTIFICATION_GROUP)
            .setGroupSummary(true)
            .build()

        NotificationManagerCompat.from(context.applicationContext).apply {
            notify(notificationId, receivedNotification)
            notify(SUMMARY_ID, summary)
        }


    }
}

And the notifications work good as I want. The problem is, How do I pass from the child activity the extra parameter to it's parent if I didn't create that child from the parent? I simply want to load it's URL into my webview, but also keep the back stack.
Also, how can I make sure I don't create multiple MainActivity if I won't use that child?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掩于岁月 2025-01-27 06:40:13

通知返回堆栈

Android 的文档页面 “从通知启动 Activity”涵盖“常规活动”建议下的返回堆栈用例。

定期活动

这是作为应用正常用户体验流程的一部分存在的活动。因此,当用户通过通知到达 Activity 时,新任务应包含完整的后退堆栈,允许他们按“后退”键并在应用程序层次结构中向上导航。

我发现您正在代码中已有的 TaskStackBuilder 上使用 addNextIntentWithParentStack 方法,因此看起来您可能已经关注过该页面。
然而,Google 的文档存在一个问题,即发送到 getPendingIntentrequestCode 应该是您的应用的唯一值。
示例:

   getPendingIntent(
      1234, // NOTE: Change this to a unique requestCode for your app
      PendingIntent.FLAG_UPDATE_CURRENT
   )

我已就此向 Google 提交了文档问题

最后,由于我在您的问题中没有看到这一点,请确保您已根据 Android 的 "定义应用的 Activity 层次结构"

OneSignal 详细信息

通知跟踪

请注意,调用 notificationReceivedEvent.complete(null) 表示 OneSignal 不会了解您使用 NotificationManagerCompat 显示的通知的任何信息。这会改变一些事情:

  • 点击计数不会发送到 OneSignal
  • 通知不会恢复。 (当应用程序“强制停止”、设备重新启动或应用程序更新时,通知会自动清理)

通知组

OneSignal 已经可以对代码中的分组和摘要进行分组和摘要。只需在仪表板上设置“群组密钥”,或android_group(如果您要发送)使用 REST API 的通知。

返回堆栈

OneSignal 不允许您控制返回堆栈,它只是始终恢复该应用程序并使返回堆栈不受影响。但是,您可以使用 com.onesignal.NotificationOpened.DEFAULT 在您的 AndroidManifest.xml 中,并使用您自己的 startActivity OneSignal.setNotificationOpenedHandler

Notification Back Stack

Android's documentation page "Start an Activity from a Notification" covers the back stack use case under the "Regular activity" suggestion.

Regular activity

This is an activity that exists as a part of your app's normal UX flow. So when the user arrives in the activity from the notification, the new task should include a complete back stack, allowing them to press Back and navigate up the app hierarchy.

I see you are using the addNextIntentWithParentStack method on TaskStackBuilder already in your code so looks like you may have already followed that page.
However there is one thing wrong with Google's docs here, the requestCode sent to getPendingIntent should be a unique value for your app.
Example:

   getPendingIntent(
      1234, // NOTE: Change this to a unique requestCode for your app
      PendingIntent.FLAG_UPDATE_CURRENT
   )

I have filed an docs issue with Google on this.

Lastly, since I didn't see this in your question make sure you have correctly added android:parentActivityName to your Activity in your AndroidManifest.xml per Android's "Define your app's Activity hierarchy"

OneSignal Details

Notification Tracking

Note that calling notificationReceivedEvent.complete(null) means OneSignal won't know anything about your notification you're displaying with NotificationManagerCompat. This changes a few things:

  • Click counts won't be sent to OneSignal
  • Notification won't be restored. (notifications are automatically cleaned when the app is "force stopped", device is rebooted, or app is updated)

Notification Groups

OneSignal can already do the grouping and summary you have in your code. Just set the "Group Key" on the dashboard, or android_group if you are sending the notification with the REST API.

Back stack

OneSignal doesn't allow you to control the back stack, it simply just always resumes that app and leaves the back stack un-effected. However you can disable this default behavior with com.onesignal.NotificationOpened.DEFAULT in your AndroidManifest.xml and use your own startActivity from the OneSignal.setNotificationOpenedHandler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文