在 Android 11 上,如何在不实际点击通知的情况下从通知更新启动 Activity

Posted

技术标签:

【中文标题】在 Android 11 上,如何在不实际点击通知的情况下从通知更新启动 Activity【英文标题】:On Android 11 how do I start an Activity from a notification update WITHOUT actually tapping on the notification 【发布时间】:2021-11-21 11:08:37 【问题描述】:

我的应用程序 (Xamarin.android) 作为前台服务运行。因此,该服务有一个我更新的永久通知。该应用程序从支持蓝牙的医疗设备接收数据。当通讯到达我的应用程序时,我会使用计数器更新通知(在我的例子中是患者事件)。

如果我点击通知,我的应用程序在那里启动得很好,但是,对于某些传入的蓝牙数据包,我需要实际启动(或前台)我的活动,这需要在用户不点击通知的情况下发生。注意:我只希望这在设备解锁、屏幕打开且我的应用不在前台时才能工作。

我的代码过去运行得很好,所以我怀疑它的谷歌对 Android 10 和 11 的更改已经停止了这个工作,但它仍然可以完成吗?

我当前的代码如下所示

非常感谢

卡伦

/// <summary>
/// Assuming that the phone is not locked, and the screen is on, this brings the application to the foreground. It is used, for instance
/// where a patient event is inititiated while the user is viewing another app. The app is brought to the foreground by simply launching (or re-launching)
/// Main Activity
 /// </summary>
    public void BringToForeground()
    
        var context = (Activity)MainApplication.ActivityContext;
        KeyguardManager keyguardManager = (KeyguardManager)context.GetSystemService(Context.KeyguardService);
        DisplayManager  displayManager  = (DisplayManager)context.GetSystemService(Context.DisplayService);

        var displayOn = false;
        foreach (var display in displayManager.GetDisplays())
        
            if (display.State == DisplayState.On)
                displayOn = true;
        

        if (!displayOn || keyguardManager.IsKeyguardLocked)
            return;

        //Check if we are already foregrounded, if so, return, nothing more to do
        var proteusAppProcess = new ActivityManager.RunningAppProcessInfo();
        ActivityManager.GetMyMemoryState(proteusAppProcess);
        if (proteusAppProcess.Importance == Importance.Foreground)
            return;

        //Not foregrounded so re-launch intent - since this APP is SingleTop, this will replace any existing activity
        Intent resultIntent = new Intent(StaticDefs.Com_Spacelabs_EclipsePatientApp_Android_SwitchScreenIntent);
        resultIntent.PutExtra(PageId.PageIdStringIdent, (int)PageId.RequestedPageId.PatientEventListScreen);
        resultIntent.SetFlags(ActivityFlags.NoHistory | ActivityFlags.NewTask | ActivityFlags.SingleTop);
        context.StartActivity(resultIntent);
    

【问题讨论】:

【参考方案1】:

好吧,我想我可以回答我自己的问题 - 这是由于 Android 10 re 的变化,谁可以以编程方式启动前台活动。

为了使上述代码正常工作,我需要请求 SYSTEM_ALERT_WINDOW 权限,然后手动访问(或以编程方式打开)我的应用的 Android 设置页面并启用“出现在顶部”选项。

这样做之后,我的活动就像以前一样开始。

不幸的是,鉴于这是一款医疗应用程序,可能由老年人使用,期望人们手动重新配置该应用程序是不现实的,所以我将忍受点击通知来启动活动。即使我的应用程序作为前台服务运行,似乎也需要 SYSTEM_ALERT_WINDOW 权限 - 前台服务可以绕过 Android 9 后台执行限制!

卡伦

【讨论】:

以上是关于在 Android 11 上,如何在不实际点击通知的情况下从通知更新启动 Activity的主要内容,如果未能解决你的问题,请参考以下文章

在Android中打开Activity而不点击通知

收到 FCM 通知时如何在不点击通知的情况下打开(启动)应用程序

如何在不点击通知的情况下从通知中获取数据(firebase 云消息传递和本机反应)

如何在不创建通知的情况下将图标添加到 Android 状态栏?

当应用程序处于状态后台或被杀死时,如何在不点击通知的情况下存储 iOS 远程通知?

如何在不与 MainActivity 交互的情况下从通知中打开片段页面?