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

Android:如何通过静默推送通知直接唤起应用

问题分析与解决方案

你当前的代码仅实现了带跳转的通知创建,但缺少自动唤起应用到前台的核心逻辑,同时未处理屏幕唤醒、后台启动限制等关键环节,以下是具体修复方案:

一、核心遗漏点

  • 未主动启动Activity,仅依赖通知点击触发跳转
  • 未处理屏幕关闭时的唤醒与解锁逻辑
  • 未适配Android 10+的后台启动限制
  • 通知未设置最高优先级,可能导致通知延迟或不弹出

二、完整修复步骤

1. 添加必要权限到AndroidManifest.xml

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<!-- Android 10+ 后台启动Activity所需权限 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- 避免应用被系统休眠,确保推送能及时处理 -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

2. 修改MyFirebaseMessagingService代码

import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.PowerManager;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if (remoteMessage.getData().size() > 0) {
            // 先唤醒屏幕,确保用户能看到唤起的应用
            wakeUpAndUnlockScreen();
            // 直接启动应用到前台
            launchAppToForeground();
            // 同时创建通知(可选,留存呼叫记录)
            sendNotification(remoteMessage);
        }
    }

    private void wakeUpAndUnlockScreen() {
        // 唤醒屏幕
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        if (powerManager != null && !powerManager.isInteractive()) {
            PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
                    PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE,
                    "DoctorCall:WakeLock"
            );
            wakeLock.acquire(10000); // 持有10秒足够完成应用唤起
            wakeLock.release();
        }

        // 解锁屏幕(适配不同Android版本)
        KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
        if (keyguardManager != null && keyguardManager.isKeyguardLocked()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                keyguardManager.requestDismissKeyguard(null, null);
            } else {
                // 旧版本解锁逻辑,需DISABLE_KEYGUARD权限
                Intent intent = new Intent(this, MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            }
        }
    }

    private void launchAppToForeground() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
                | Intent.FLAG_ACTIVITY_CLEAR_TOP 
                | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        
        // Android 10+ 后台启动适配
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
        }
        
        startActivity(intent);
    }

    private void sendNotification(RemoteMessage remoteMessage) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 
                0, 
                intent, 
                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE
        );

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "doctor_call_channel")
                .setSmallIcon(R.drawable.notification_icon)
                .setContentTitle(remoteMessage.getData().get("title"))
                .setContentText(remoteMessage.getData().get("message"))
                .setAutoCancel(true)
                .setPriority(NotificationCompat.PRIORITY_HIGH) // 高优先级确保通知强制弹出
                .setContentIntent(pendingIntent);

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.notify(1, builder.build());
    }
}

3. 关键适配说明

  • 推送类型要求:必须发送数据消息(而非通知消息),因为通知消息在应用后台时由系统直接处理,不会触发onMessageReceived,只有数据消息能确保执行自定义唤起逻辑。
  • 国产ROM适配:小米、华为等厂商有独立的后台管控机制,需要引导用户将应用加入「后台运行白名单」、开启「自启动权限」,并关闭「电池优化」。
  • 权限申请:REQUEST_IGNORE_BATTERY_OPTIMIZATIONS和SYSTEM_ALERT_WINDOW需要在应用内主动引导用户授权,否则后台唤起逻辑可能失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:01:00