当应用程序处于后台时,带有 PendingIntent 的 Android FusedLocationClient 未收到位置更新

Posted

技术标签:

【中文标题】当应用程序处于后台时,带有 PendingIntent 的 Android FusedLocationClient 未收到位置更新【英文标题】:Android FusedLocationClient with PendingIntent not receiving location update when app is in background 【发布时间】:2021-08-03 17:28:05 【问题描述】:

我正在使用 FusedLocationClient 和广播接收器在后台获取位置,我启用了后台位置背景权限和位置(精细和粗略)权限。我在前台应用程序时收到位置更新,但在后台移动应用程序时我没有收到任何更新。

androidManifest.xml

<receiver
        android:name=".LocationUpdatesBroadcastReceiver"
        android:exported="true"
        android:enabled="true">
        <intent-filter>
            <action android:name="com.test.gpstracking.LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES" />
        </intent-filter>
    </receiver>

LocationManager 类

class MyLocationManager 私有构造函数(private val context: Context)

// The Fused Location Provider provides access to location APIs.
private val fusedLocationClient: FusedLocationProviderClient =
    LocationServices.getFusedLocationProviderClient(context)
private val TAG = "MyLocationManager"

// Stores parameters for requests to the FusedLocationProviderApi.
private val locationRequest: LocationRequest = LocationRequest().apply 
    interval = TimeUnit.SECONDS.toMillis(4)
    fastestInterval = TimeUnit.SECONDS.toMillis(4)
    priority = LocationRequest.PRIORITY_HIGH_ACCURACY


/**
 * Creates default PendingIntent for location changes.
 *
 * Note: We use a BroadcastReceiver because on API level 26 and above (Oreo+), Android places
 * limits on Services.
 */
private val locationUpdatePendingIntent: PendingIntent by lazy 
    var intent = Intent(context, LocationUpdatesBroadcastReceiver::class.java)
    intent.action = LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES
    PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)


@Throws(SecurityException::class)
@MainThread
fun startLocationUpdates() 
    Log.d(TAG, "startLocationUpdates()")

    if (!context.hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) return

    try 
        Log.e(TAG, "receiving location updates")
        // If the PendingIntent is the same as the last request (which it always is), this
        // request will replace any requestLocationUpdates() called before.
        fusedLocationClient.requestLocationUpdates(locationRequest, locationUpdatePendingIntent)
     catch (permissionRevoked: SecurityException) 

        Log.e(TAG, "not receiving location updates")

        // Exception only occurs if the user revokes the FINE location permission before
        // requestLocationUpdates() is finished executing (very rare).
        Log.d(TAG, "Location permission revoked; details: $permissionRevoked")
        throw permissionRevoked
    



companion object 
    @Volatile
    private var INSTANCE: MyLocationManager? = null

    fun getInstance(context: Context): MyLocationManager 
        return INSTANCE ?: synchronized(this) 
            INSTANCE ?: MyLocationManager(context).also  INSTANCE = it 
        
    

我的广播接收器

 class LocationUpdatesBroadcastReceiver : BroadcastReceiver() 
private val TAG = "LocationUpdatesBroadcastReceiver"
override fun onReceive(context: Context, intent: Intent) 
    
    if (intent.action == ACTION_PROCESS_UPDATES) 

        // Checks for location availability changes.
        LocationAvailability.extractLocationAvailability(intent)?.let  locationAvailability ->
            if (!locationAvailability.isLocationAvailable) 
                Log.d(TAG, "Location services are no longer available!")
            
        

        LocationResult.extractResult(intent)?.let  locationResult ->
            locationResult.lastLocation
            val location = locationResult.lastLocation
            if (location != null) 
                Toast.makeText(context, location.toString(), Toast.LENGTH_SHORT).show()
                
                    
            
        
    

PS : 我正在关注来自 github 上 google repo 的 LocationUpdatesBackgroundKotlin 的 android 源代码 -> link

【问题讨论】:

【参考方案1】:

Android 不允许在 Android Oreo 之后使用任何类型的后台服务,查看此链接将指导您。 Access Location in Background

【讨论】:

以上是关于当应用程序处于后台时,带有 PendingIntent 的 Android FusedLocationClient 未收到位置更新的主要内容,如果未能解决你的问题,请参考以下文章

应用程序处于后台时状态栏下方的 IOS 文本

当应用程序在后台时,颤振通知是空白的

收到本地通知时无法播放音乐,当应用程序处于后台状态时

当应用程序处于后台或终止状态时,如何找到用户位置?

当应用程序处于后台时播放声音

当应用程序处于后台时,从推送通知中插入 coredata 记录