Android – Using Bluetooth scanning for location accuracy in Marshmallow

androidandroid-bluetoothandroid-locationbluetooth-lowenergy

With Android 4.3, Android implemented the idea of always-on WiFi where, even if you had Wi-Fi toggled off, the device and apps could still scan for WiFi networks to improve the location's accuracy. Along with using network triangulation, it's another way of getting your current position as quickly as possible without having to rely too much on GPS signals.

Android M is taking the idea further, adding Bluetooth scanning to the equation. Under the Location settings on M, you'll find a Scanning option in the menu, where both Wifi and Bluetooth scanning can be toggled on and off. When enabled, Bluetooth scanning will presumably look for BLE devices like beacons to get a quicker location fix.

location setting on M

Image resized. Click to view in full size

This may be very useful in the future inside malls, airports, and various indoor or underground locations where the reach and dispersion of Bluetooth beacons can outweigh a slow or impossible GPS signal lock. And the fact that it's always on, accessible whenever apps need a location fix, will make it even handier than if you had to remember to manually turn on Bluetooth.

Can anyone help in providing some insights or sample code for scanning for beacons with BLE without the main Bluetooth settings turned on?

Best Answer

I figured it out.

We have to write a system application and use the

BluetoothAdapter.enableBLE()

method. This method is for special/system apps which use Bluetooth Low energy to scan for nearby devices which is mostly used for location accuracy.Even if the Bluetooth is turned off in the device settings. Then we can use

BluetoothAdapter.LeScanCallback

callback to get the device details.

Sample:

for calling the method:

mBluetoothAdapter.enableBLE())

for callback: private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {

            if( device == null ){

                System.out.println("-------onLeScan "+device);
            }

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mLeDeviceListAdapter.addDevice(device);
                    mLeDeviceListAdapter.notifyDataSetChanged();
                }
            });
        }
    };

Thanks

Related Topic