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

时间:2019-07-08 05:41:59

标签: android kotlin service location

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

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

我使用开始服务

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
    }


}

帮我介绍关闭屏幕时的服务管理。 谢谢。

1 个答案:

答案 0 :(得分:0)

您将需要唤醒锁,而我也将成为您的服务前景。这将使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()

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

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"
}