detect bluetooth Le devices in Android

2019-03-16 08:44发布

问题:

I'm a beginner in android app development. I've tried reading the documentation but am getting nowhere (functions in Android's tutorial such as StartLeScan() have been deprecated, etc...)

Is there a simple function that returns a list of bluetooth devices ?

something like getDevices() -> (list of devices) ?

Thank you

回答1:

basically it depends on which android version you are targeting. since the api has changed a bit in lollipop (21).

in your activity, get the bluetooth adapter

BluetoothManager bm = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE)
BluetoothAdapter mBluetoothAdapter = bm.getAdapter();

// Ensures Bluetooth is available on the device and it is enabled. If not, 
// displays a dialog requesting user permission to enable Bluetooth. 
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { 
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

then you should check which android version you are targeting

int apiVersion = android.os.Build.VERSION.SDK_INT;
if (apiVersion > android.os.Build.VERSION_CODES.KITKAT){
 BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner();
 // scan for devices
 scanner.startScan(new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            // get the discovered device as you wish
            // this will trigger each time a new device is found

            BluetoothDevice device = result.getDevice();
        }
    });
} else {
    // targetting kitkat or bellow
    mBluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            // get the discovered device as you wish

        }
    });

// rest of your code that will run **before** callback is triggered since it's asynchronous

dont forget to add permissions in your manifest

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>


回答2:

if you are using api level less than 21 then you will find that StartLeScan has been deprecated, In android lollipop StartLeScan() has introduced with new scan settings feature. You can use below code to scan BLE devices.

ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();
scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
scanSettings = scanSettingsBuilder.build();

BluetoothScanCallback mScanCallback = new BluetoothScanCallback();
mBluetoothUtils.getBluetoothAdapter().getBluetoothLeScanner()
                .startScan(scanFilters, scanSettings, mScanCallback);


回答3:

I also thought this problem for few hours and I found out the answer by searching the Official doc.
You need to know 3 class and method ScanCallback,BluetoothLeScanner,ScanResult
//my level is so low that I cannot post the link....
You can see in the android developer web ,the web page would show Added in API level 21" on the right side.

Here is my code , modified from these project

//declare    
private BluetoothLeScanner mBluetoothLeScanner;  
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

//start and stop scan
mBluetoothLeScanner.startScan(mScanCallback);
mBluetoothLeScanner.stopScan(mScanCallback);

//Scan call back function
private ScanCallback mScanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
         super.onScanResult(callbackType, result);
         mLeDeviceListAdapter.addDevice(result.getDevice());
         mLeDeviceListAdapter.notifyDataSetChanged();
    }
};

my grandle:

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "com.polkapolka.bluetooth.le"
        minSdkVersion 21
        targetSdkVersion 22
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

These code works well on my phone,which is API 21 Hope it help you.



回答4:

I had been playing with BLE scan for a while until I got the simplest solution from Nordic library.

Add a line to your build.gradle:

dependencies {
  ....
  compile 'no.nordicsemi.android.support.v18:scanner:1.0.0'
}

And use BluetoothLeScannerCompat:

import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat;

...
BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
scaner.startScan(new ScanCallback { ...});

And the library does all job.