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

AlarmManager触发广播接收器后如何在应用不在前台时启动Activity

问题原因

Android 10(API 29)及以上系统新增了后台应用启动Activity的限制,即便是广播接收器正常触发,不在前台运行的应用默认也没有启动Activity的权限,这是系统为了减少非用户预期的界面跳转、优化使用体验做的限制。

解决方案

方案1:申请悬浮窗权限(最简单直接,适合闹钟类工具应用)

申请SYSTEM_ALERT_WINDOW权限后即可绕过后台启动Activity限制:

  1. 在AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- 跳转权限申请页需要的权限 -->
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
  1. 在应用首次启动时引导用户开启悬浮窗权限:
// 权限请求码自定义即可
private static final int REQ_OVERLAY_PERMISSION = 1001;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (!Settings.canDrawOverlays(this)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, REQ_OVERLAY_PERMISSION);
    }
}

方案2:使用全屏Intent配合通知(无需悬浮窗权限,适配系统规范)

如果不想申请悬浮窗权限,可以通过高优先级通知的全屏Intent实现后台唤起:

  1. 在AndroidManifest.xml中添加通知权限(Android 13及以上需要):
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
  1. 广播接收器onReceive中改为弹出通知,通过通知的意图跳转Activity:
@Override
public void onReceive(Context context, Intent intent) {
    Intent scheduledIntent = new Intent(context, MainActivity.class);
    scheduledIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            context,
            1002,
            scheduledIntent,
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT
    );

    String channelId = "alarm_channel";
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(channelId, "闹钟提醒", NotificationManager.IMPORTANCE_HIGH);
        notificationManager.createNotificationChannel(channel);
    }

    Notification notification = new NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("闹钟触发")
            .setContentText("点击打开应用")
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setCategory(NotificationCompat.CATEGORY_ALARM)
            .setContentIntent(pendingIntent)
            .setFullScreenIntent(pendingIntent, true) // 关键:全屏意图,后台会直接唤起Activity
            .setAutoCancel(true)
            .build();
    notificationManager.notify(1003, notification);
}

原有代码修复

你现有AlarmManager设置代码中PendingIntent的标记不符合Android 12及以上系统要求,需要修改标记位避免报错:

AlarmManager alarmManager=(AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent=new Intent(this,AlarmReceiver.class);
int flag = PendingIntent.FLAG_UPDATE_CURRENT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    // 不需要修改Intent内容用FLAG_IMMUTABLE,需要修改则用FLAG_MUTABLE
    flag |= PendingIntent.FLAG_IMMUTABLE;
}
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,1000,intent,flag);
// Android 12及以上需要申请精确闹钟权限才能使用setExactAndAllowWhileIdle
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,timeInMillis,pendingIntent);
} else {
    alarmManager.set(AlarmManager.RTC_WAKEUP,timeInMillis,pendingIntent);
}

如果需要定时在低功耗模式也能触发,还需要在Manifest中添加精确闹钟权限:

<uses-permission android:name="android.permission.REQUEST_SCHEDULE_EXACT_ALARM" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:15:03