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

Android 13(API>26)解锁/重启后启动服务方案咨询

Android 13 设备解锁后自动执行任务的实现方案

方案一:动态注册解锁广播 + 开机广播触发初始化

该方案解决了API 26+无法在Manifest中注册隐式广播的限制,同时通过开机广播确保设备重启后能重新注册解锁广播,无需用户手动启动应用。

步骤1:声明必要权限

在AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- 启动前台服务需添加以下权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Android 13+ 通知权限 -->

步骤2:Manifest注册开机广播接收器

ACTION_BOOT_COMPLETED是API 26后少数允许在Manifest中注册的广播之一:

<receiver
    android:name=".BootCompletedReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <!-- 适配部分厂商快速开机逻辑 -->
    </intent-filter>
</receiver>

步骤3:实现开机广播接收器,动态注册解锁广播

收到开机广播后,立即注册ACTION_USER_PRESENT(设备解锁广播):

class BootCompletedReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (Intent.ACTION_BOOT_COMPLETED == intent.action || 
            "android.intent.action.QUICKBOOT_POWERON" == intent.action) {
            // 注册设备解锁广播
            val userPresentReceiver = UserPresentReceiver()
            val filter = IntentFilter(Intent.ACTION_USER_PRESENT)
            context.registerReceiver(userPresentReceiver, filter, Context.RECEIVER_EXPORTED)
            
            // 可选:开机完成后直接执行一次任务
            scheduleTask(context)
        }
    }
}

步骤4:实现解锁广播接收器,触发任务/服务

用户解锁设备时,触发任务执行逻辑:

class UserPresentReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (Intent.ACTION_USER_PRESENT == intent.action) {
            // 启动前台服务执行任务(或调度WorkManager)
            startForegroundService(context)
        }
    }

    private fun startForegroundService(context: Context) {
        val serviceIntent = Intent(context, TaskService::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(serviceIntent)
        } else {
            context.startService(serviceIntent)
        }
    }
}

步骤5:实现前台服务,执行任务后自动销毁

任务完成后立即停止服务,避免持续耗电:

class TaskService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 创建前台通知(Android 8+ 强制要求)
        val notification = NotificationCompat.Builder(this, "task_channel")
            .setContentTitle("执行任务中")
            .setContentText("正在完成指定操作")
            .setSmallIcon(R.drawable.ic_notification)
            .build()
        
        // 创建通知渠道(Android 8+ 必须)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "task_channel",
                "任务执行通知",
                NotificationManager.IMPORTANCE_LOW
            )
            getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
        }

        startForeground(1, notification)

        // 执行具体任务逻辑
        executeTask()

        // 任务完成后停止服务
        stopForeground(STOP_FOREGROUND_REMOVE)
        stopSelf()

        return START_NOT_STICKY
    }

    private fun executeTask() {
        // 替换为你的实际任务代码,如数据同步、文件处理等
        Thread.sleep(3000) // 模拟任务耗时
    }

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

方案二:WorkManager + 触发式任务调度

若不想依赖应用进程存活,可使用WorkManager调度任务,通过广播触发执行,系统会自动处理进程拉起逻辑。

步骤1:实现Worker类

class TaskWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        // 执行任务逻辑
        executeTask()
        return Result.success()
    }

    private fun executeTask() {
        // 具体任务代码
        Thread.sleep(3000)
    }
}

步骤2:在解锁广播中调度任务

修改UserPresentReceiver的onReceive方法,替换为WorkManager调度逻辑:

private fun scheduleTask(context: Context) {
    val constraints = Constraints.Builder()
        .setRequiresDeviceIdle(false)
        .setRequiresCharging(false)
        .build()

    val workRequest = OneTimeWorkRequestBuilder<TaskWorker>()
        .setConstraints(constraints)
        .build()

    WorkManager.getInstance(context).enqueue(workRequest)
}

关键注意事项

  • Android 13+ 通知权限:前台服务需要POST_NOTIFICATIONS权限,需在代码中主动申请用户授权。
  • 进程存活限制:动态注册的广播依赖应用进程,若进程被系统杀死,广播会失效,开机广播会在设备重启后重新注册。
  • 电池优化与厂商限制:部分国产厂商后台管控严格,需引导用户开启应用的「自启动权限」并加入电池优化白名单,确保广播正常接收。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:38:12