0

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.

Spectra
  • 1
  • 2
  • By 'permissions like "Find nearby devices"' do you mean `BLUETOOTH_SCAN`? What is your `compileSdk` and `targetSdk`? – Ricky Mo Jun 20 '23 at 05:39
  • You may also implement `onBatchScanResults` in the `ScanCallback` to see if it is getting call instead. Unless you have special handling requirement for batching, you can always implement both `onBatchScanResults` and `onScanResult`, then redirect the batched result to `onScanResult`, just in case. Since you will never know if a particular device model is messing up. – Ricky Mo Jun 20 '23 at 05:44
  • How do you request runtime permissions? Please show that part too. – Kozmotronik Jun 20 '23 at 05:49
  • 1. compileSdk and targetSdk : 33 – Spectra Jun 20 '23 at 06:07
  • private static final String[] BLE_PERMISSIONS = new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT }; public static void requestBlePermissions(Activity activity, int requestCode) { ActivityCompat.requestPermissions(activity, BLE_PERMISSIONS, requestCode); } – Spectra Jun 20 '23 at 06:16
  • Does this exact code with that exact scan filter work to get scan callbacks on pre-Android 13 devices? Any difference in behavior when your app is in the foreground vs. the background? When used in conjunction with the Android Beacon Library and you start getting results, what type of beacon advertisement does the library detect? – davidgyoung Jun 20 '23 at 12:34
  • Two other things to check on permissions: (1) Please show your **merged** AndroidManifest.xml permission declarations -- other libraries can alter your manifest. (2) Double check Settings -> Apps -> Your app -> Permissions and check that you have precise (not coarse) Location Always and Bluetooth granted. – davidgyoung Jun 20 '23 at 12:38
  • this is my merged manifest file permissions: – Spectra Jun 21 '23 at 05:01
  • In background scanning when app is closed then only this thing happened mScanCallback not initialized. – Spectra Jun 21 '23 at 07:40

0 Answers0