简体   繁体   中英

How to get device location when a BTLE event triggers in broadcast receiver?

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
                }

            }    
        }

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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM