Update from Android 10 above I think you need ACCESS_BACKGROUND_LOCATION permissions. So if this code doesn't work on newest android versions is for this problem. ACCESS_BACKGROUND_LOCATION is subjected to strict policy on Google Play store so instead of adding this permission you can use a ForegroundService with this option setted on the manifest declaration:
android:foregroundServiceType="location"
Using this option you won't need ACCESS_BACKGROUND_LOCATION permission to do the scan.
*** SOLVED ***
Solution: on Android >= 8 (or 6, i don't remember the version now) you need the permission to access the location and the GPS enabled to see the BLE devices.
Ok I found the solution... I was already giving all permissions like "BLUETOOTH_ADMIN", "BLUETOOTH", "ACCESS_COARSE_LOCATION" in manifest and also I was already checking all permission in my MainActivity. But I don't know why I found that if I manually add the permission "Access to my location" the scan Callback start working. So now I'm going to implement the permission request inside my MainActivity before that I start the service. That's weird because I didn't get the same problem in the other application in which I do the BLE scan inside the MainActivity; my other app in which I scan inside the MainActivity didn't request this specific permission, it only need "BLUETOOTH" & "BLUETOOTH_ADMIN" permissions. So looks like that the "Access to my location" is needed only if the scan is going to work in background.
( I tryed it in my device "Huawei P8 Lite" with Android version "8.0.0")
***********
I already tryed the "BluetoothLeScanner" inside an activity and I didn't find any problem during the scan. But now that I have moved my Scan Operation inside a service I have find some problem.
This is my service:
public class BLEService extends Service {
private static final int SCAN_TIME_MILLIS = 5000;
private static final String MY_MAC = "00:15:85:10:85:3C";
private Handler mHandler;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mScanner;
private ScanCallback mScanCallback;
private BluetoothGatt mBluetoothGatt;
private BluetoothGattCallback mGattCallback;
private int mTxpower;
@Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
initAll();
startScan();
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void startScan(){
mScanner.startScan(mScanCallback);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
stopScan();
}
}, SCAN_TIME_MILLIS);
}
private void stopScan(){
mScanner.stopScan(mScanCallback);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
startScan();
}
}, SCAN_TIME_MILLIS);
}
private void initAll(){
initBluetoothAdapter();
initBluetoothLeScanner();
initBluetoothScanCallback();
initGattCallback();
}
private void initBluetoothAdapter(){
final BluetoothManager bluetoothManager = (BluetoothManager) getBaseContext().getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mBluetoothAdapter.startDiscovery();
}
private void initBluetoothLeScanner(){
mScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
private void initBluetoothScanCallback(){
mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
}
};
}
private void initGattCallback(){
mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
}
};
}
}
When I use the method "startScan()" if I look the logs I can see that the Scanner was registered right:
I/BluetoothAdapter: getBluetoothLeScanner
D/BluetoothAdapter: isLeEnabled(): ON
D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=7 mScannerId=0
So it looks like the Scan starts right, but if I try to debug the callback of the scan it never reach my breakpoints. Can anybody help me please?
Thank you :D