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

Android前台服务锁屏模式检测:无需Kastri库实现方案咨询

Android锁屏/亮屏检测与Service前台状态控制(无Kastri库依赖)

核心思路

通过动态注册系统广播接收器监听屏幕熄灭(ACTION_SCREEN_OFF)和亮屏(ACTION_SCREEN_ON)事件,在事件回调中触发Service的startForeground()和stopForeground()方法,确保位置传感器在锁屏/亮屏状态下持续运行。


1. 实现屏幕状态广播接收器

创建一个继承自BroadcastReceiver的类,专门处理屏幕状态变化:

class ScreenStateReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        intent?.action?.let { action ->
            val serviceIntent = Intent(context, LocationService::class.java)
            when (action) {
                Intent.ACTION_SCREEN_OFF -> {
                    // 锁屏时触发前台服务启动
                    serviceIntent.putExtra("COMMAND", "START_FOREGROUND")
                    context?.startService(serviceIntent)
                }
                Intent.ACTION_SCREEN_ON -> {
                    // 亮屏时退出前台状态
                    serviceIntent.putExtra("COMMAND", "STOP_FOREGROUND")
                    context?.startService(serviceIntent)
                }
            }
        }
    }
}

2. 实现带前台状态控制的Service

在Service中处理前台服务的启动与停止逻辑,同时创建适配Android 8.0+的通知渠道:

class LocationService : Service() {
    private lateinit var screenReceiver: ScreenStateReceiver
    private val NOTIFICATION_ID = 1001
    private val CHANNEL_ID = "LOCATION_SERVICE_CHANNEL"

    override fun onCreate() {
        super.onCreate()
        // 创建通知渠道(Android O及以上必需)
        createNotificationChannel()
        // 动态注册屏幕状态接收器
        screenReceiver = ScreenStateReceiver()
        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_SCREEN_OFF)
            addAction(Intent.ACTION_SCREEN_ON)
        }
        registerReceiver(screenReceiver, filter)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        intent?.getStringExtra("COMMAND")?.let { command ->
            when (command) {
                "START_FOREGROUND" -> {
                    val notification = createForegroundNotification()
                    startForeground(NOTIFICATION_ID, notification)
                    // 此处添加位置传感器启动逻辑
                }
                "STOP_FOREGROUND" -> {
                    // 参数true:移除通知;false:保留通知但退出前台状态
                    stopForeground(true)
                    // 位置传感器可继续运行,无需停止
                }
            }
        }
        return START_STICKY
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "位置服务",
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "保持位置传感器持续运行"
            }
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun createForegroundNotification(): Notification {
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            Intent(this, MainActivity::class.java),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("位置服务运行中")
            .setContentText("屏幕已锁定,服务保持活跃")
            .setSmallIcon(R.drawable.ic_notification)
            .setContentIntent(pendingIntent)
            .build()
    }

    override fun onDestroy() {
        super.onDestroy()
        // 注销接收器,避免内存泄漏
        unregisterReceiver(screenReceiver)
    }

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

3. 启动Service并适配配置

  • 在AndroidManifest.xml中声明Service:
<service
    android:name=".LocationService"
    android:foregroundServiceType="location" /> <!-- Android 12+ 需指定前台服务类型 -->
  • 在Activity中启动Service(适配Android 8.0+):
// 启动服务
val serviceIntent = Intent(this, LocationService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(serviceIntent)
} else {
    startService(serviceIntent)
}

关键注意事项

  • Android 8.0及以上,静态注册广播接收器无法监听屏幕状态事件,必须动态注册(在Service或Activity生命周期内完成注册/注销)。
  • 调用startForeground()必须传入有效通知,否则会抛出异常;通知渠道需提前创建。
  • Android 12+需在Service声明中添加android:foregroundServiceType="location",确保位置权限正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:55:47