AltBeacon / android-beacon-library

Allows Android apps to interact with BLE beacons
Apache License 2.0
2.83k stars 834 forks source link

Beacon Scan Result Behaviour #1146

Closed Spectra6170 closed 1 year ago

Spectra6170 commented 1 year ago

Hi @davidgyoung I am afraid that i could not explain my problem previously. In Short... On Android 13 (We are using Samsung galaxy m33 5g for testing), when I don't use beacon library and just native BluetoothLEScanner I don't get callback for it. but when I just initialize beacon library and leave it be, my native LEScanner gives me ScanResults. I want to know that what does beacon library do in background that Native LEScanner starts getting results. Now this is my basic problem. Apart from that, LEScanner stops getting advertisement results after some time, even if beacon library is still running.

davidgyoung commented 1 year ago

Ah, I suspect the problem is that your native scan does not have a ScanFilter set up. Samsung blocks scans with the screen off unless there is a ScanFilter. And while I have not tested this, I suspect that if two scans from the same app are started (one with a filter and one without) both scans will get callbacks.

See here:

https://developer.android.com/reference/android/bluetooth/le/ScanFilter

Spectra6170 commented 1 year ago

This is my Scanner class. On android 13 specifically when I used your library then my mScanCallback is getting called. when I remove your library (i.e. doesn't start beacon manager) , my mScanCallback doesn't getting called.. my class works in other mobile devices without using your library.

So my only question to you is that, what are you doing in your scanner class code so it works fluently and even my callback gets called, where as there is no relation between your library and my class. I am not using your library for getting results. just init beacon manger and leave it be.

Also can you point me to exact piece of code in your library where BLEScanner is getting init. so that I can go through it and understand the flow, perhaps change my class a bit and getting it worked.

public class BLEScanner {

private BluetoothLeScanner Scanner;
private BleAdapter adapter;
private Timer RemoveTimer;
private Timer RemoveTimerScanning;
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("xxxx-xxxx-xx")).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();

                boolean modelExists = false;
                for (BLEModel m : adapter.SynList) {
                    if (m.getAddress().equalsIgnoreCase(address)) {
                        m.updateDevice(result);
                        modelExists = true;
                        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();
}

}

davidgyoung commented 1 year ago

The logic the library uses to start scans is a bit complex but here it is: https://github.com/AltBeacon/android-beacon-library/blob/master/lib/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScannerForLollipop.java#L170

Debugging custom apps is outside the scope of this forum which is about the library itself. I will close this issue, but I am happy to help troubleshoot your app on StackOverflow.com if you want to open a question there.

Spectra6170 commented 1 year ago

Hii David, Please find a link I posted on Stackoverflow regarding android 13 BluetoothLe Scanner class .I hope you will come and help me on this issue.

https://stackoverflow.com/q/76511490/22100202

On Mon, 19 Jun 2023 at 20:26, David G. Young @.***> wrote:

The logic the library uses to start scans is a bit complex but here it is: https://github.com/AltBeacon/android-beacon-library/blob/master/lib/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScannerForLollipop.java#L170

Debugging custom apps is outside the scope of this forum which is about the library itself. I will close this issue, but I am happy to help troubleshoot your app on StackOverflow.com if you want to open a question there.

— Reply to this email directly, view it on GitHub https://github.com/AltBeacon/android-beacon-library/issues/1146#issuecomment-1597333794, or unsubscribe https://github.com/notifications/unsubscribe-auth/A5IWBAC3DYSUV32KRDCOCQDXMBSCBANCNFSM6AAAAAAZIW4PGY . You are receiving this because you authored the thread.Message ID: @.***>