I am developing a demo app to scan Blutooth Le devices. But startLeScan() returns null. and I am not getting any device name. I have tried using normal scan it shows up fine. I am adding my snippet here
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mTxtInfo.setText("Stopped Scanning.");
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mTxtInfo.setText("Started Scanning...");
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mTxtInfo.setText("Stopped Scanning.");
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
This is my function to start Le scan.
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mTxtInfo.setText("Detected devices: " + device.getName());
Toast.makeText(MainActivity.this,
"Detected devices: " + device.getName(),
Toast.LENGTH_LONG).show();
}
});
}
};
this is the callback. And its showing me
07-04 12:50:17.833: D/BluetoothAdapter(3564): startLeScan(): null
Would appreciate any help.
The Problem there is that you are trying to use
startLeScan(callback)
without setting the Uuid parameter. So the BluetoothAdapter code it's doing something like:
startLeScan(null, callback)
on the back and printing
"startLeScan:" + Uuid.
Which for you is null.
Related
I have faced with the issue using startScan method of BluetoothLeScanner a BLE device was found, but when I turned off BLE device my phone still shows this device as turned on !!
I have tried to use:
private ScanCallback mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
Log.i("ScanCallback", String.format("onScanResult(int callbackType[%d], ScanResult result)", callbackType));
final BluetoothDevice btDevice = result.getDevice();
if (btDevice == null){
Log.e("ScanCallback", "Could not get bluetooth device");
return;
}
final String macAddress = btDevice.getAddress();
if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
// NOTE: I've never got here
final BluetoothDevice outOfRangeDevice = mBtDevices.get(macAddress);
...
} else {
...
}
}
...
};
Guy, I have not found solution how to detect that BLE device is lost in other resources like (Android SDK reference, forums, stackoverflow and etc) (:
Any help will be appreciated !!
During googling and exploring the Android Documentations I have figured out how to detect if device is out of range. I would like to share my solution how I did it:
...
public void scanBLEDevices(final boolean enable) {
if(mLeScanner == null) {
Log.d(TAG, "Could not get LEScanner object");
throw new InternalError("Could not get LEScanner object");
}
if (enable) {
startLeScan();
} else {
stopLeScan(false);
}
}
private void startLeScan() {
Log.i(TAG, "startLeScan(BluetoothLeScanner mLeScanner)");
mScanning = true;
mInRangeBtDevices.clear();
if (mStartScanCallback != null) {
mHandler.removeCallbacks(mStartScanCallback);
}
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLeScanner.startScan(mScanFilters, mScanSettings, mScanCallback);
}
mStopScanCallback = new Runnable() {
#Override
public void run() {
stopLeScan(true);
}
};
mHandler.postDelayed(mStopScanCallback, SCAN_PERIOD);
}
private void stopLeScan(final boolean isContinueAfterPause) {
Log.i(TAG, "stopLeScan(BluetoothLeScanner mLeScanner)");
mScanning = false;
if (mStopScanCallback != null) {
mHandler.removeCallbacks(mStopScanCallback);
}
removeOutOfRangeDevices();
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLeScanner.stopScan(mScanCallback);
}
if (isContinueAfterPause) {
mStartScanCallback = new Runnable() {
#Override
public void run() {
startLeScan();
}
};
mHandler.postDelayed(mStartScanCallback, SCAN_PAUSE);
}
}
private void removeOutOfRangeDevices() {
final Set<String> outOfRangeDevices = new HashSet<>();
for (String btAddress : mBtDevices.keySet()) {
if (!mInRangeBtDevices.contains(btAddress)) {
outOfRangeDevices.add(btAddress);
}
}
for (String btAddress : outOfRangeDevices) {
final BluetoothDevice outOfRangeDevice = mBtDevices.get(btAddress);
mBtDevicesRSSI.remove(btAddress);
mBtDevices.remove(btAddress);
}
}
...
Explanation:
As you can see I have added on each scanning period mInRangeBtDevices collection that will keep all devices found during the current scanning.
When I stop scanning, I am also removing out of range device from previous lists that is not available anymore using one additional helper collection outOfRangeDevices
I think this example would be usefull and you will be able to integrate it in your own code
This one is looking good (JAVA):
As I understood, you need to implement startLeScan().
Find BLE devices
To find BLE devices, you use the startLeScan() method. This method takes a BluetoothAdapter.LeScanCallback as a parameter. You must implement this callback, because that is how scan results are returned. Because scanning is battery-intensive, you should observe the following guidelines:
As soon as you find the desired device, stop scanning.
Never scan on a loop, and set a time limit on your scan. A device that was previously available may have moved out of range, and continuing to scan drains the battery.
The following snippet shows how to start and stop a scan:
public class DeviceScanActivity extends ListActivity {
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
...
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
...
}
...}
Consider checking this tutorial as well.
Also this one.
I have a dialog that scans for BLE devices for 10 seconds. When I start my scan I enable a spinner at the footer of the list. When the scan is completed I'd like to remove that spinner. I'm trying to get this to work with the deprecated mBluetoothAdapter.stopLeScan(callback) function instead of the new startScan/stopScan functions as if the device isn't running version 21 or higher, you have to fallback to this method.
stopLeScan requires the same callback as startLeScan but I dont think I see the callback being made. I was hoping that it was a simple check to see if the BluetoohDevice was null, then the callback was made because the scan was stopped, but this didn't work.
With the old version of the SDK, how do you get when the scan has been stopped (either due to the proper device being found or the scan time completed)? I could pass another handler to the my scanLeDevice function, but that just seems silly as I'm already passing a callback.
Bluetooth scanner
public class BleDevice {
private final static String TAG = BleDevice.class.getSimpleName();
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
public BleDevice() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = new Handler();
}
public void scanLeDevice(final boolean enable, final BluetoothAdapter.LeScanCallback callback) {
if (enable == true && mScanning == false) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// Turn off scanning
scanLeDevice(false, callback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(callback);
Log.d(TAG, "Starting Bluetooth LE scan");
} else if(enable == false && mScanning == true) {
mScanning = false;
mBluetoothAdapter.stopLeScan(callback);
Log.d(TAG, "Stopped Bluetooth LE scan");
}
}
}
Callback in Dialog Box:
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
Log.d(TAG, device.getAddress() + " " + device.getName() + "");
if(device == null) {
Log.d(TAG, "Device is null? stop?");
} else {
btAdapter.add(device);
}
}
};
In mBluetoothAdapter.stopLeScan(callback); the callback is just used to identify which scan is to be stopped and it's not supposed to trigger any method in the callback. It's a synchronous operation.
And the BluetoothAdapter.LeScanCallback class doesn't even have any methods beyond the onLeScan() which just receives the results.
So, you can define your own method to be triggered when the scan is stopped by you:
...
} else if(enable == false && mScanning == true) {
mScanning = false;
mBluetoothAdapter.stopLeScan(callback);
Log.d(TAG, "Stopped Bluetooth LE scan");
onScanStopped(); // <--- Remove the spinner here.
}
I'm not aware of any automatic timeout for startLeScan(), so as far as I know it should only stop by calling stopLeScan(). And onLeScan() being triggered doesn't stop the scan either.
I'm developing an app that have to connect with a BLE device, in my code I want to use the new Scan and ScanCallback for BLE implemented from API 21 (Android 5) but I have to maintain the compatibility with Android 4.3 and above.
So I wrote the code, for example, in this way:
if (Build.VERSION.SDK_INT >= 21) {
mLEScanner.startScan(filters, settings, mScanCallback);
} else {
btAdapter.startLeScan(leScanCallback);
}
And I have defined the 2 callbacks, one for API 21 and above and one for API 18 to 20:
//API 21
private ScanCallback mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice btDevice = result.getDevice();
connectToDevice(btDevice);
}
public void connectToDevice(BluetoothDevice device) {
if (mGatt == null) {
mGatt = device.connectGatt(context, false, btleGattCallback);
if (Build.VERSION.SDK_INT < 21) {
btAdapter.stopLeScan(leScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}
};
//API 18 to 20
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
btAdapter.stopLeScan(leScanCallback);
runOnUiThread(new Runnable() {
#Override
public void run() {
mBluetoothGatt = device.connectGatt(context, false, btleGattCallback);
}
});
}
};
I also added the annotation
#TargetApi(21)
but when I launch the App on Android 4.x it crashes immediately reporting the error that the class ScanCallback cannot be found (the one intended to be used only with Android 5 and above).
How can I solve this?
Thank you very much.
Daniele.
After reading several posts I did the following. Just in case, here is the documentation of Android about BluetoothLe
First
Create two methods one scanLeDevice21 and scanLeDevice18. On scanLeDevice21 add the annotation #RequiresApi(21) that says:
Denotes that the annotated element should only be called on the given API level or higher.
This is similar in purpose to the older #TargetApi annotation, but more clearly expresses that this is a requirement on the caller, rather than being used to "suppress" warnings within the method that exceed the minSdkVersion.
Second
Implement each method, here's my code.
#RequiresApi(21)
private void scanLeDevice21(final boolean enable) {
ScanCallback mLeScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
BluetoothDevice bluetoothDevice = result.getDevice();
if (!bluetoothDeviceList.contains(bluetoothDevice)) {
Log.d("DEVICE", bluetoothDevice.getName() + "[" + bluetoothDevice.getAddress() + "]");
bluetoothDeviceArrayAdapter.add(bluetoothDevice);
bluetoothDeviceArrayAdapter.notifyDataSetChanged();
}
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
}
#Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
}
};
final BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(() -> {
mScanning = false;
swipeRefreshLayout.setRefreshing(false);
bluetoothLeScanner.stopScan(mLeScanCallback);
}, SCAN_PERIOD);
mScanning = true;
bluetoothLeScanner.startScan(mLeScanCallback);
} else {
mScanning = false;
bluetoothLeScanner.stopScan(mLeScanCallback);
}
}
/**
* Scan BLE devices on Android API 18 to 20
*
* #param enable Enable scan
*/
private void scanLeDevice18(boolean enable) {
BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice bluetoothDevice, int rssi,
byte[] scanRecord) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
bluetoothDeviceArrayAdapter.add(bluetoothDevice);
bluetoothDeviceArrayAdapter.notifyDataSetChanged();
}
});
}
};
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(() -> {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
Third
Every time you need to scan devices you surround your code asking which version you are. For instance, I have a RefreshLayout to display the list of devices. Here's the result:
/**
* Refresh listener
*/
private void refreshScan() {
if (!hasFineLocationPermissions()) {
swipeRefreshLayout.setRefreshing(false);
//Up to marshmallow you need location permissions to scan bluetooth devices, this method is not here since is up to you to implement it and it is out of scope of this question.
requestFineLocationPermission();
} else {
swipeRefreshLayout.setRefreshing(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scanLeDevice21(true);
} else {
scanLeDevice18(true);
}
}
}
And that's it.
Forget about extending, subclassing classes you don't really need like ulusoyca answer.
Create AbstractBluetoothLe class and IBleScanCallback interface. IBleScanCallback interface is a Marker Interface. In other saying, an interface with no methods. You can also add methods to interface if you need. These methods will do the same functionality for all type of scanCallbacks i.e. getListOfFoundBleDevices(), clearListOfFoundBleDevices() etc.
Create BluetootLeLollipop, and BluetoothLeJellyBean classes which extend AbstractBluetoothLe class. Create also BluetootLeMarshmallow class which extends BluetootLeLollipopclass. AbstractBluetoothLe class has protected field mIBleScanCallback which is an IBleScanCallback object.
Create BleScanCallbackBase class which implements IBleScanCallback.
Create LollipopScanCallback class which extends ScanCallback class and implements IBleScanCallback interface. .This class has a protected field scanCallback which will be instantiated as BleScanCallbackBase object. Create also MarshmallowScanCallback class which extends LollipopScanCallback class.
Create JellyBeanScanCallback class which extends BleScanCallbackBase and implements BluetoothAdapter.LeScanCallback
In BleScanCallbackBase override the method: onScanCallback(...)
In LollipoScanCallback override onScanResult(int callbackType, ScanResult result) and inside this method call the method onScanCallback(...) of the scanCallback object.
In JellyBeanScanCallback override onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) and inside this method call onScanCallback(...)
Finally, do whatever needs to be done when a device is found in onScanCallback(...)method of BleScanCallbackBase class.
In short, read about composition over inheritance- I know this is not an answer to your question but this is a neat way of what you want to achieve in the end. Here is the class diagram:
Your code is crashing because it is creating anonymous inner class. Hence at run time it doesn't find that sCanCallback class.
Try below way and share the outcome. Before you try this, make sure you comment the callback(ScanCallback).
if (Build.VERSION.SDK_INT >= 21) {
mLEScanner.startScan(filters, settings, new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice btDevice = result.getDevice();
connectToDevice(btDevice);
}
public void connectToDevice(BluetoothDevice device) {
if (mGatt == null) {
mGatt = device.connectGatt(context, false, btleGattCallback);
if (Build.VERSION.SDK_INT < 21) {
btAdapter.stopLeScan(leScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}
};
} else {
btAdapter.startLeScan(leScanCallback);
}
I would like to share my idea to overcome this crash on devices below API 21. The ScanCallback class has support from API 21. So when you write a code to implement ScanCallback in your scan code it will cause a crash on lover APIs. I have fixed it the following way:
I created one new abstract class which extending ScanCallback class as follows:
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public abstract class AppScanCallback extends ScanCallback {}
Now I am using this class instance in my BluetoothService class as follow:
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private AppScanCallback mScanCallback;
And using this variable as follow:
public void startBleScan() {
if (isEnabled()) {
if (Build.VERSION.SDK_INT < 21) {
_bluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner = _bluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.build();
filters = new ArrayList<>();
mScanCallback = new AppScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
if (Build.VERSION.SDK_INT >= 21) {
BluetoothDevice btDevice = result.getDevice();
onLeScanResult(btDevice, result.getScanRecord().getBytes());
}
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
#Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
mLEScanner.startScan(filters, settings, mScanCallback);
}
}
}
and to stop scan
public void stopBLEScan() {;
if (Build.VERSION.SDK_INT < 21) {
_bluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
Hope it will help you out.
I want to analysis the heart rate of a heart rate monitor. For that I want to save the last used device and compare it to the found devices. Because it takes a while to find devices, mDevice remains null. What do I have to do to update mDevice properly?
private ArrayList<BluetoothDevice> mDeviceList;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
private BluetoothDevice mDevice;
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
#Override
protected void onStart() {
super.onStart();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
// Initializes list view adapter.
mDeviceList = new ArrayList<BluetoothDevice>();
scanLeDevice(true);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
final String adress = prefs.getString(getString(R.string.device_address), "");
for(BluetoothDevice b : mDeviceList){
if(b.getAddress().equals(adress)){
mDevice = b;
}
}
if(mDevice != null)
Log.e(TAG, mDevice.getAddress());
}
taken from the google manual:
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!mDeviceList.contains(device)){
mDeviceList.add(device);
}
}
});
}
};
I hope these are enough information. If something is missing, feel free to ask
The scan is a background activity your trying to look at the results straight after you start it rather than waiting for it to finish. You may want to put your checking code into the onLeScan call-back directly and stopping the scan as soon as you see the device you want.
You could also try not doing the scan all together if you already have the details for the device just try going straight to connect. The details of if you need to scan before you connect are not at all clear from the documentation so you need to be prepared to experiment a bit as it's still all far too flaky.
Just move your code where you try to find the last device (everything in onStart() after SharedPreferences prefs...) to after you have already found devices, for example at the end of your runnable (after invalidateOptionsMenu();)
I am keep on getting the NoClassDefFoundError when my class is loaded.
The code is taken from BluetoothLeGatt project -
http://developer.android.com/samples/BluetoothLeGatt/project.html
My code:
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() { //java.lang.NoClassDefFoundError...
#Override
public void onLeScan(final BluetoothDevice device,
final int rssi, final byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
String msg= device.getAddress();
Log.d(TAG,msg);
addItems(msg);
}
});
}
};
Someone suggested that the error is because my device doesn't support BLE but I want to get rid of this error for any device. So if it doesn't support BLE feature then simply skip this error else continue with the call to this BluetoothAdapter.LeScanCallback.
NOTE:
See this my previous SO post for more clarification.
Putting the BLE feature check as the first line onCreate() doesn't stop the crash --
#Override
public void onCreate(Bundle savedInstanceState) {
if (!bleCheck()) {
Toast.makeText(getApplicationContext(), R.string.ble_not_supported,
Toast.LENGTH_SHORT).show();
finish();
}
//Rest of the code
//Call to BLE Scan on button click that causes error..
}
private boolean bleCheck() {
boolean result = false;
if (getPackageManager().
hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
result = true;
}
return result;
}
As BluetoothAdapter.LeScanCallback was Added in API level 18 ; Source, this code would need a API level check also. Here's how i have gone about this, not declared the callback as private but under the condition:
boolean apiJBorAbove = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2 ? true
: false;
boolean isBleAvailable = getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE) ? true : false;
// Use this check to determine whether BLE is supported on the device.
if (isBleAvailable && apiJBorAbove) {
// Initializes a Bluetooth adapter.
// For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.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()) {
startActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE));
}
BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device,
final int rssi, final byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
String msg= device.getAddress();
// Log.d(TAG,msg);
// addItems(msg);
}
});
}
};
}
The NoClassDefFoundError is due to the API , not on the basis of PackageManager.FEATURE_BLUETOOTH_LE.