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

Android 11及以上版本如何设置应用开机自动启动?

Android 11+ 开机后发送通知的解决方案

从Android 11开始,系统对BOOT_COMPLETED广播接收器的触发条件做了严格限制:只有用户手动启动过至少一次的应用,或者应用持有特定权限(如前台服务权限),才能接收到该广播。如果应用从未被用户打开过,即使注册了广播接收器也无法触发。以下是几种可行的解决方案:

方案一:使用WorkManager实现(推荐)

WorkManager是Jetpack官方推荐的后台任务调度组件,支持设备重启后自动重新调度任务,且符合Android 11+的权限规范。

  1. 添加依赖
    在build.gradle(app)中引入WorkManager依赖:
implementation "androidx.work:work-runtime:2.8.1"
  1. 创建Worker类处理通知逻辑
class BootNotificationWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        sendBootNotification(applicationContext)
        return Result.success()
    }

    private fun sendBootNotification(context: Context) {
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        
        // 创建通知渠道(Android O及以上必填)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "BOOT_NOTIFY_CHANNEL",
                "开机通知",
                NotificationManager.IMPORTANCE_DEFAULT
            ).apply {
                description = "设备开机后触发的通知"
            }
            notificationManager.createNotificationChannel(channel)
        }

        // 点击通知打开应用
        val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
        val pendingIntent = PendingIntent.getActivity(
            context,
            0,
            launchIntent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        // 构建并发送通知
        val notification = NotificationCompat.Builder(context, "BOOT_NOTIFY_CHANNEL")
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle("设备已开机")
            .setContentText("你的应用已检测到开机完成")
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()

        notificationManager.notify(1001, notification)
    }
}
  1. 在应用启动时注册任务
    在MainActivity的onCreate方法中,注册一个设备重启后自动触发的WorkManager任务:
val constraints = Constraints.Builder()
    .setRequiresDeviceIdle(false)
    .setRequiresCharging(false)
    .build()

val bootWorkRequest = OneTimeWorkRequestBuilder<BootNotificationWorker>()
    .setConstraints(constraints)
    .setInitialDelay(10, TimeUnit.SECONDS) // 延迟10秒,确保系统初始化完成
    .addTag("BOOT_NOTIFY_TASK")
    .build()

// 确保任务唯一,避免重复调度
WorkManager.getInstance(this).enqueueUniqueWork(
    "UNIQUE_BOOT_NOTIFY_WORK",
    ExistingWorkPolicy.REPLACE,
    bootWorkRequest
)

方案二:保留BOOT_COMPLETED广播接收器(需满足权限条件)

如果坚持使用广播接收器,必须满足以下前提:用户手动打开过应用至少一次,部分国产ROM还需开启「自动启动」权限。

  1. 注册广播接收器与权限
    在AndroidManifest.xml中添加:
<!-- 声明权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<!-- 注册广播接收器 -->
<receiver
    android:name=".BootCompletedReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <!-- 适配快速开机 -->
    </intent-filter>
</receiver>
  1. 实现广播接收器逻辑
class BootCompletedReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (Intent.ACTION_BOOT_COMPLETED == intent.action || Intent.ACTION_QUICKBOOT_POWERON == intent.action) {
            // 调用发送通知的方法(同方案一中的sendBootNotification)
            sendBootNotification(context)
        }
    }

    private fun sendBootNotification(context: Context) {
        // 同方案一的通知构建逻辑
    }
}

方案三:前台服务结合START_STICKY(不推荐,耗电)

仅适用于需要开机后立即执行任务的场景,会在状态栏显示前台通知,影响用户体验。

  1. 添加权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  1. 广播接收器启动前台服务
class BootCompletedReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
            val serviceIntent = Intent(context, BootForegroundService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(serviceIntent)
            } else {
                context.startService(serviceIntent)
            }
        }
    }
}
  1. 实现前台服务
class BootForegroundService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 创建前台通知
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "FOREGROUND_BOOT_CHANNEL",
                "开机服务",
                NotificationManager.IMPORTANCE_LOW
            )
            notificationManager.createNotificationChannel(channel)
        }

        val foregroundNotification = NotificationCompat.Builder(this, "FOREGROUND_BOOT_CHANNEL")
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle("应用运行中")
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()

        startForeground(1002, foregroundNotification)
        
        // 发送开机通知
        sendBootNotification(this)
        
        // 任务完成后停止前台服务
        stopForeground(STOP_FOREGROUND_REMOVE)
        stopSelf()

        return START_STICKY
    }

    private fun sendBootNotification(context: Context) {
        // 同方案一的通知构建逻辑
    }

    override fun onBind(intent: Intent): IBinder? = null
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:50:28