Issue
I am statically registering Broadcast Receiver for BTLE connection/disconnection events to detect when my bluetooth headphones connects/disconnects with my Android phone. I also want to record the current location of my phone to update to a server when the OnReceive event for bluetooth is triggered. I am using FusedLocationProviderClient
to get current location with fine, coarse and background location permissions declared in the manifest, but the location received is always null. How do I get the correct current location? Here's my code:
AndroidManifest.xml - permissions and static receiver
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<receiver android:name=".BtBroadcastReceiver" android:exported="true">
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>
</receiver>
BtBroadcastReceiver.kt
class BtBroadcastReceiver : BroadcastReceiver() {
private var locationCallback: LocationCallback? = null
private var locationRequest: LocationRequest? = null
private lateinit var fusedLocationClient: FusedLocationProviderClient
private var currentLocation: Location? = null
override fun onReceive(context: Context, intent: Intent) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
val action = intent.action
val bluetoothDevice: BluetoothDevice
when (action) {
BluetoothDevice.ACTION_ACL_CONNECTED -> {
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)!!
updateDeviceLocation(context, bluetoothDevice.name)
}
BluetoothDevice.ACTION_ACL_DISCONNECTED -> {
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)!!
updateDeviceLocation(context, bluetoothDevice.name)
}
}
}
private fun updateDeviceLocation(context: Context, name: String) {
fusedLocationClient.lastLocation
.addOnSuccessListener { location->
if (location != null) {
currentLocation = location
// Save location of device to Shared Preferences
}
}
}
Solution
fusedLocationClient.lastLocation
can return null location if no recent location fix exists. Using the below code to get current location works as it gets fresh location:
fusedLocationClient.getCurrentLocation(LocationRequest.PRIORITY_HIGH_ACCURACY, object : CancellationToken() {
override fun onCanceledRequested(p0: OnTokenCanceledListener) = CancellationTokenSource().token
override fun isCancellationRequested() = false
})
.addOnSuccessListener { location: Location? ->
//Update location in shared preferences
}
Make sure to use the latest location package in gradle based on this post
implementation "com.google.android.gms:play-services-location:17.1.0"
Answered By - Apoorva Nataraja
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.