【问题标题】:how to run location tracking service after screen is off?屏幕关闭后如何运行位置跟踪服务?
【发布时间】:2019-07-08 05:41:59
【问题描述】:

屏幕关闭时无法更新位置。

屏幕关闭后如何运行位置跟踪服务?

我开始使用服务

val serviceClass = ControlLocationService::class.java
val intent = Intent(activity, serviceClass)
activity?.startService(intent)

在 onLocationChanged 方法中,我尝试使用 Log.e() 但屏幕关闭时不会在 logcat 中显示纬度和经度

class ControlLocationService : Service() {

    lateinit var locationRequest: LocationRequest
    lateinit var fusedLocationProviderClient: FusedLocationProviderClient
    private lateinit var locationCallback:LocationCallback

    override fun onBind(intent: Intent): IBinder? {
        throw UnsupportedOperationException("Not yet implemented")
    }

    @SuppressLint("InvalidWakeLockTag")
    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        //service is started
        updateLocation()
        return START_STICKY
    }

    @SuppressLint("MissingPermission")
    private fun updateLocation() {
        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult?) {
                onLocationChanged(locationResult!!.lastLocation)
            }
        }
        buildLocationRequest()
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
    }

    private fun onLocationChanged(location: Location) {
        Log.e("...", location.latitude.toString()+location.longitude.toString())
    }

    private fun buildLocationRequest() {
        locationRequest = LocationRequest()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 3000
        locationRequest.fastestInterval = 1000
        //locationRequest.smallestDisplacement = 1f
    }


}

帮我介绍一下关屏时的服务管理。 谢谢。

【问题讨论】:

    标签: android kotlin service location


    【解决方案1】:

    你需要一个唤醒锁,我也会让你的服务前台。这将使 android 不太可能杀死您的应用程序或服务。实际上根据Background Location Limits,它并没有说你需要一个唤醒锁——只有前台服务。通过让您的应用程序在后台连续运行,您将使其快速耗尽您的用户电池 - 这很糟糕。考虑使用被动位置更新,这些可能在一小时内发生几次 - 这可能不是您所追求的。

    您可能还想了解doze mode,它使所有非白名单应用程序在屏幕关闭模式下忽略唤醒锁。

    添加唤醒锁:

    val mgr = service.getSystemService(Context.POWER_SERVICE) as PowerManager
    val wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myAppName:MyWakeLock")
    wakeLock.acquire()
    

    onDestroy:

    wakeLock.release()
    

    使用以下代码将通知添加到通知栏并制作服务前台。您应该在您的onStartCommand 中添加addServiceNotification(this)

    fun addServiceNotification(service: Service) {
        val mgr = NotificationManagerCompat.from(service)
        val title = "Caption"
        val text = "Location"
    
        if (Build.VERSION.SDK_INT >= 26) {
            val notificationManager = service.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            if (notificationManager != null) {
                var mChannel: NotificationChannel? = notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID)
                if (mChannel == null) {
                    mChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID, "myAppName", NotificationManager.IMPORTANCE_LOW)
                    notificationManager.createNotificationChannel(mChannel)
                }
            }
    
            val notification = NotificationCompat.Builder(service, NOTIFICATION_CHANNEL_ID)
                    .setSmallIcon(R.drawable.app_icon)
                    .setTicker(title)
                    .setWhen(System.currentTimeMillis())
                    .setContentTitle(title)
                    .setContentText(text)
                    .setOnlyAlertOnce(true)
                    .setOngoing(true)
                    .build()
    
            service.startForeground(LOCATION_NOTIFICATION_ID, notification)
            mgr.cancel(LOCATION_NOTIFICATION_ID)
            mgr.notify(LOCATION_NOTIFICATION_ID, notification)
        }
    }
    
    // remove notification for location service
    fun removeServiceNotification(service: Service) {
      val notificationManager = service.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
      notificationManager?.cancel(LOCATION_NOTIFICATION_ID)
    }
    
    companion object {
        val LOCATION_NOTIFICATION_ID = 1001
        val NOTIFICATION_CHANNEL_ID = "myAppName"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 2018-10-31
      • 2016-10-05
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多