当应用程序处于后台时,带有 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 未收到位置更新的主要内容,如果未能解决你的问题,请参考以下文章