关闭应用程序时,如何在Android 12及更高版本中获得位置?

发布于 2025-01-30 08:30:34 字数 3922 浏览 5 评论 0原文

当使用Workmanager关闭应用程序时,我正在尝试在Android 12中找到位置。但是问题是,它工作了几分钟,并被操作系统杀死。我无法确定为什么会发生这种情况。

解决方案是什么?

用代码更新的问题

Workmanager

class LocationWorker(
    private val context: Context,
    private val workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters) {

    private val NOTIFICATION_ID = 10

    private var mRandomNumber = 0
    private var mIsRandomGeneratorOn = false

    private val MIN = 0
    private val MAX = 100

    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override suspend fun doWork(): Result {
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
        setForeground(createForeGroundInfo())
        getLocation()
        return Result.success()
    }

    private fun createForeGroundInfo(): ForegroundInfo {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel()
        }

        val notification =
            NotificationCompat.Builder(applicationContext, NOTIFICATION_ID.toString())
                .setContentTitle("Location Sharing")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setSmallIcon(R.drawable.ic_location)
                .setOngoing(true)
                .build()

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ForegroundInfo(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION)
        } else {
            ForegroundInfo(NOTIFICATION_ID, notification)
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun createChannel() {
        val channelName = "location_sharing"
        val channel = NotificationChannel(
            NOTIFICATION_ID.toString(),
            channelName,
            NotificationManager.IMPORTANCE_DEFAULT
        )
        val manager =
            (context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
        manager.createNotificationChannel(channel)
    }

    private fun getLocation() {
        val locationRequest: LocationRequest = LocationRequest.create().apply {
            interval = 3000
            fastestInterval = 1500
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            maxWaitTime = 2000
        }

        val locationCallback: LocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                val locationList = locationResult.locations
                if (locationList.isNotEmpty()) {
                    val location = locationList.last()
                    Log.d("ServiceDemo", location.latitude.toString()+ " " + System.currentTimeMillis())
                }
            }
        }

        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

            Toast.makeText(applicationContext, "Permission required", Toast.LENGTH_LONG).show()
            return
        }else{
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
        }
    }
}

MainActivity

otreate方法

val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.CONNECTED)
       .build()

workManager = WorkManager.getInstance(applicationContext)

workRequest = PeriodicWorkRequestBuilder<LocationWorker>(15, TimeUnit.MINUTES)
       .setConstraints(constraints)
       .build()
workManager!!.enqueueUniquePeriodicWork("Testing WorkManager", ExistingPeriodicWorkPolicy.REPLACE, workRequest as PeriodicWorkRequest)

我想知道WhatsApp分享位置是如何共享的,因为它不要求用户将电池模式更改为无限制。

I am trying to get location in android 12 when app is closed using WorkManager. But the issue is, it work for few minutes and get killed by the OS. I am unable to find out why this is happening.

What could be the solution for this?

Question updated with code

WorkManager

class LocationWorker(
    private val context: Context,
    private val workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters) {

    private val NOTIFICATION_ID = 10

    private var mRandomNumber = 0
    private var mIsRandomGeneratorOn = false

    private val MIN = 0
    private val MAX = 100

    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override suspend fun doWork(): Result {
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
        setForeground(createForeGroundInfo())
        getLocation()
        return Result.success()
    }

    private fun createForeGroundInfo(): ForegroundInfo {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel()
        }

        val notification =
            NotificationCompat.Builder(applicationContext, NOTIFICATION_ID.toString())
                .setContentTitle("Location Sharing")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setSmallIcon(R.drawable.ic_location)
                .setOngoing(true)
                .build()

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ForegroundInfo(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION)
        } else {
            ForegroundInfo(NOTIFICATION_ID, notification)
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun createChannel() {
        val channelName = "location_sharing"
        val channel = NotificationChannel(
            NOTIFICATION_ID.toString(),
            channelName,
            NotificationManager.IMPORTANCE_DEFAULT
        )
        val manager =
            (context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
        manager.createNotificationChannel(channel)
    }

    private fun getLocation() {
        val locationRequest: LocationRequest = LocationRequest.create().apply {
            interval = 3000
            fastestInterval = 1500
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            maxWaitTime = 2000
        }

        val locationCallback: LocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                val locationList = locationResult.locations
                if (locationList.isNotEmpty()) {
                    val location = locationList.last()
                    Log.d("ServiceDemo", location.latitude.toString()+ " " + System.currentTimeMillis())
                }
            }
        }

        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

            Toast.makeText(applicationContext, "Permission required", Toast.LENGTH_LONG).show()
            return
        }else{
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
        }
    }
}

MainActivity

onCreate method

val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.CONNECTED)
       .build()

workManager = WorkManager.getInstance(applicationContext)

workRequest = PeriodicWorkRequestBuilder<LocationWorker>(15, TimeUnit.MINUTES)
       .setConstraints(constraints)
       .build()
workManager!!.enqueueUniquePeriodicWork("Testing WorkManager", ExistingPeriodicWorkPolicy.REPLACE, workRequest as PeriodicWorkRequest)

I wonder how WhatsApp share location because it doesn't ask user to change the battery mode to unrestricted.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文