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

FCM高优先级消息触发启动Activity在华为/LG设备特定场景失效问题

解决华为/LG设备Doze/口袋模式下FCM无法启动AlarmActivity的问题

嘿,我之前也踩过华为和LG这类定制系统在Doze或口袋模式下限制后台Activity启动的坑,给你几个针对性的解决方案,应该能让你的AlarmActivity像系统闹钟/来电一样正常弹出:

1. 确保FCM消息是高优先级

首先要保证你的FCM payload明确设置了高优先级,Doze模式下只有高优先级消息能突破限制触发后续逻辑:

  • 用Firebase控制台发送时,选择「高优先级」
  • API调用时,在请求体中添加:
"priority": "high"

2. 用新的PowerManager API替代废弃的WakeLock

虽然SCREEN_BRIGHT_WAKE_LOCK被废弃,但我们可以用新方式获取唤醒锁,确保启动Activity前唤醒设备。修改你的FirebaseMessagingService:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // 获取PowerManager并创建唤醒锁
    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
            PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
            "MyApp:AlarmWakeLockTag");
    // 持有10秒足够完成Activity启动,避免长时间持有浪费资源
    wakeLock.acquire(10 * 1000);

    Intent dialogIntent = new Intent(getBaseContext(), AlarmActivity.class);
    dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    dialogIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    // 移除无用的FLAG_RECEIVER_FOREGROUND(这个是给广播接收器用的)
    getApplication().startActivity(dialogIntent);

    // 释放唤醒锁
    wakeLock.release();
}

3. 更新AlarmActivity的屏幕唤醒逻辑(适配Android 10+)

旧的WindowManager flags在Android 10及以上系统被部分废弃,改用官方推荐方法,同时处理华为口袋模式的锁屏限制:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Android 10+ 推荐用这些方法替代旧的Window Flags
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        setShowWhenLocked(true);
        setTurnScreenOn(true);
    } else {
        getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    }

    // 处理华为口袋模式下的锁屏问题,尝试解锁Keyguard
    KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        keyguardManager.requestDismissKeyguard(this, null);
    }

    setContentView(R.layout.activity_alarm);
    // ... 你的其他业务逻辑
}

4. 申请必要权限并豁免电池优化

定制系统的电池优化会严格限制后台行为,必须申请权限并引导用户开启豁免:

第一步:在AndroidManifest.xml添加权限

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

第二步:引导用户开启电池优化豁免

在App首次启动或收到FCM消息前,检查并申请豁免:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    if (!powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
        Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }
}

5. 华为/LG特殊系统权限引导

华为的「自启动管理」和LG的「后台限制」会额外拦截后台启动,代码无法自动获取权限,必须在App里添加引导页面,告诉用户:

  • 华为:设置 > 应用和服务 > 应用启动管理 > 找到你的App > 关闭「自动管理」,开启「允许自启动」「允许后台活动」
  • LG:设置 > 电池 > 电池优化 > 找到你的App > 设置为「不优化」

这些步骤组合起来,就能让你的AlarmActivity像系统闹钟或来电一样,在Doze模式、口袋模式下正常点亮屏幕并启动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:33:48