You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin Android的OneSignal HandleNotificationOpened中启动Intent

解决Android后台状态下OneSignal通知点击启动指定Intent的问题

你遇到的核心问题在于:应用后台时,依赖静态全局变量+OnResume触发跳转的逻辑不可靠——静态变量可能被系统内存回收,且后台点击通知时SplashActivity的OnResume未必会触发。下面是针对性的解决方案:

1. 核心优化思路

  • 移除静态全局变量,直接在HandleNotificationOpened回调内处理Intent启动,避免状态丢失
  • 将回调改为非静态方法,使用可靠的Activity上下文启动页面
  • 给Intent添加必要的Flags,确保后台场景下能正确唤起目标Activity

2. 调整后的完整代码示例

public class SplashActivity : Activity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        OneSignal.Current.StartInit("mykey")
            .InFocusDisplaying(OSInFocusDisplayOption.None)
            .HandleNotificationOpened(HandleNotificationOpened) // 绑定非静态回调方法
            .EndInit();
        OneSignal.Current.IdsAvailable(IdsAvailable);
        base.OnCreate(savedInstanceState);
    }

    protected override void OnResume()
    {
        base.OnResume();
        // 仅处理应用正常启动的场景,不再依赖全局变量
        if (Intent?.GetStringExtra("act") == null)
        {
            StartActivity(new Intent(this, typeof(MainActivity)));
        }
    }

    // 改为非静态方法,直接使用当前Activity上下文
    private void HandleNotificationOpened(OSNotificationOpenedResult result)
    {
        OSNotificationPayload payload = result.notification.payload;
        Dictionary<string, object> additionalData = payload.additionalData;

        if (additionalData != null && additionalData.ContainsKey("act"))
        {
            string act = additionalData["act"].ToString();
            Intent targetIntent = act switch
            {
                "1" => new Intent(this, typeof(ProfileActivity)),
                "2" => new Intent(this, typeof(NotificationsActivity)),
                _ => new Intent(this, typeof(MainActivity))
            };

            // 关键Flags:确保后台能启动Activity,且避免重复创建实例
            targetIntent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
            targetIntent.PutExtra("act", act); // 可选:传递参数给目标页面

            StartActivity(targetIntent);
            Finish(); // 关闭启动页,避免返回时回到这里
        }
        else
        {
            StartActivity(new Intent(this, typeof(MainActivity)));
            Finish();
        }
    }

    private void IdsAvailable(string userID, string pushToken)
    {
        // 你的原有逻辑
    }
}

3. 关键细节说明

  • Intent Flags作用:
    • ActivityFlags.NewTask:解决后台线程启动Activity的权限问题
    • ActivityFlags.ClearTop:清空目标Activity之上的栈内页面,将目标页带到前台,避免重复创建实例
  • 非静态回调:直接使用SplashActivity的上下文,比静态变量+延迟触发的逻辑更可靠
  • 移除全局变量:直接从推送附加数据中获取参数,避免系统回收导致的状态丢失

这样修改后,无论应用处于前台、后台还是关闭状态,点击通知都能直接启动指定的Intent,完美适配你的需求。

内容的提问来源于stack exchange,提问作者Adeptus Mechanicus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:27:14