Test Device: Samsung M33 5G. OS: Android 13. Issue: Wen I init the BLuetoothLEScanner using native android classes, it doesn't return any scan result in registered scancallback. I have tested my code on other android version apart from 13. and my code wotks without any problem. Just in Android 13 it has problem. I have given all the required permissions like "Find nearby devices", "Access_fine_Location", "Access_coarse_location", etc... So it is not the problem related to permissions.
Apart from this When I use 3rd party library like altbeacon, and just init its beacon manager and leave it be running in the app in some other class, my Scanners starts replying to registered callback. I don't understand how this happens and how does altbacon library triggers OS so that OS starts returning to all the scancallbacks registered in any BluethoothLEScanner running in App.
My BluethoothLEScanner runs in different thread then the thread in which altbeacon's beaconmanger is initialized.
here is my Code for BluetoothLLEScanner.
public class BLEScanner {
private BluetoothLeScanner Scanner;
private BleAdapter adapter;
private Timer RemoveTimer;
private Context ctx;
private Handler mHandler = new Handler(Looper.getMainLooper());
private Timer mTimer;
private boolean isSortingScheduled = false;
public BLEScanner(Context mctx, BleAdapter ade) throws Exception {
ctx = mctx;
adapter = ade;
ResumeScanning();
}
public void PauseScanning() {
try {
if (Scanner != null) {
Scanner.stopScan(mScanCallback);
Scanner = null;
}
} catch (SecurityException ex) {
Log.e("BLEScanner", ex.getMessage());
}
}
public void ResumeScanning() throws Exception {
final BluetoothManager bluetoothManager =
(BluetoothManager) ctx.getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter adepter = BluetoothAdapter.getDefaultAdapter();
if (adepter != null) {
Scanner = null;
Scanner = adepter.getBluetoothLeScanner();
if (Scanner != null) {
try {
//create filer
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
ArrayList<ScanFilter> filters = new ArrayList<ScanFilter>();
ScanFilter filter1 = new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString("XXXXXXXX-0000-1000-8000-0080XXXXXXXX")).build();
filters.add(filter1);
Scanner.startScan(filters, settings, mScanCallback);
if (RemoveTimer != null) {
RemoveTimer.cancel();
RemoveTimer = null;
}
RemoveTimer = new Timer();
RemoveTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
adapter.Remove();
}
}, 500, 500);
} catch (SecurityException ex) {
Log.d("Scanner", ex.getMessage());
}
}
} else {
throw new Exception();
}
}
public ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
try {
if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
BluetoothDevice dev = result.getDevice();
String address = dev.getAddress();
for (BLEModel m : adapter.SynList) {
if (m.getAddress().equalsIgnoreCase(address)) {
m.updateDevice(result);
startOrScheduleSortingTask();
return;
}
}
BLEModel model = new BLEModel();
model.updateDevice(result);
if (Globals.isAccessCardAPPDevice(model.getType())) {
adapter.SynList.add(model);
Collections.sort(adapter.SynList, (model1, model2) -> {
double distance1 = model1.getDistance();
double distance2 = model2.getDistance();
return Double.compare(distance1, distance2);
});
adapter.notifyDataSetChanged();
} else
model = null;
} else //if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST)
{
Log.d("Scanner", String.valueOf(callbackType));
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
private void startOrScheduleSortingTask() {
if (!isSortingScheduled) {
// Perform sorting on the main thread immediately
performSortingTask();
// Schedule the sorting task to run repeatedly every 500 milliseconds
mHandler.postDelayed(sortingRunnable, 500);
isSortingScheduled = true;
}
}
private Runnable sortingRunnable = new Runnable() {
@Override
public void run() {
// Perform sorting on the main thread
performSortingTask();
// Schedule the next sorting task after 500 milliseconds
mHandler.postDelayed(this, 500);
}
};
private void performSortingTask() {
Collections.sort(adapter.SynList, (model1, model2) -> {
double distance1 = model1.getDistance();
double distance2 = model2.getDistance();
return Double.compare(distance1, distance2);
});
adapter.notifyDataSetChanged();
}
}
I have tried using 3rd party library like altbeacon, and my scanner starts receiving callbacks even if it is not tied with altbeacon library in any ways.