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
相关产品推荐
相关产品推荐

