1

my app is advertising and scanning using ble in android.it needs to do it in a loop of maybe 1 hour every day (probably less),but now ,for the testing I'm trying to make it work even more. after some time I realized that it can't run eternally without having bugs. I'm getting error numbers 2 and 4 (one for advertise and one for scan). before I can see the errors in the log ,there is always a line like:

01-26 19:59:09.509 D/BluetoothLeScanner: onClientRegistered() - status=133 clientIf=21

the number near clientIf is getting bigger all the time ,till the error,so my guess is that the scanner/advertiser is collecting data about the scanned/advertised devices. I saw some options for solutions,like waiting some time between the actions or making mBluetoothGatt.close(); the waiting didnt help,and my app is not using the gatt (I'm not making any pairing inside the app),so I thought maybe i'll initialize BluetoothLeScanner/BluetoothLeAdvertiser again, but it didn't prevent the number near clientIf to raise and of course the error occured again. does anyone have any Idea how can I "zero" the number near clientIf ,or of course other way to prevent the errors from happening ? thanks ! the most relative question I read was this:

Android stops finding BLE devices: onClientRegistered() - status=133 clientIf=0

edit: here I will add the code of the ble. this is the scan code:

public class StDataCentralBle {
    private static final String TAG = ScannerFragment.class.getSimpleName();
    private static final long SCAN_PERIOD = 15000;
    private BluetoothAdapter mBluetoothAdapter;
    public BluetoothLeScanner mBluetoothLeScanner;
    private ScanCallback mScanCallback;
    private Vector<String> ScanResultArray;//intended to replace the adapter
    private Context context;

private Handler mHandler;
//todo open this:
public StDataCentralBle(Context context){
    this.context=context;


public void setBluetoothAdapter(BluetoothAdapter btAdapter) {
    this.mBluetoothAdapter = btAdapter;
    mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
public void startScanning() {
    if (mScanCallback == null && mBluetoothAdapter!=null && mBluetoothAdapter.isEnabled()) {
        Log.d(TAG, "Starting Scanning");

        // Will stop the scanning after a set time.
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.v("ble_process","BT state is: "+mBluetoothAdapter.getScanMode());
                stopScanning();
            }
        }, SCAN_PERIOD);

        // Kick off a new scan.
        mScanCallback = new SampleScanCallback();
        mBluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), mScanCallback);

        Toast.makeText(context, "started scan", Toast.LENGTH_SHORT).show();
    } else {
        Log.v("ble_process","didnt start scan");

    }
}

/**
 * Stop scanning for BLE Advertisements.
 */
public void stopScanning() {
    // Stop the scan, wipe the callback.
    if(mBluetoothLeScanner!=null && mBluetoothAdapter.isEnabled() && mBluetoothAdapter.getState()==21) {
        mBluetoothLeScanner.stopScan(mScanCallback);
        Log.v("ble_process", "stopping scanning");
    }
    mScanCallback = null;
    if(mBluetoothAdapter!=null)
        mBluetoothLeScanner=mBluetoothAdapter.getBluetoothLeScanner();
    Toast.makeText(context, "stoped scan", Toast.LENGTH_SHORT).show();
}
/**
 * Return a List of {@link ScanFilter} objects to filter by Service UUID.
 */
private List<ScanFilter> buildScanFilters() {
    List<ScanFilter> scanFilters = new ArrayList<>();

    ScanFilter.Builder builder = new ScanFilter.Builder();
    // Comment out the below line to see all BLE devices around you
    builder.setServiceUuid(Constants.Service_UUID);
    scanFilters.add(builder.build());

    return scanFilters;
}

/**
 * Return a {@link ScanSettings} object set to use low power (to preserve battery life).
 */
private ScanSettings buildScanSettings() {
    ScanSettings.Builder builder = new ScanSettings.Builder();
    builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
    return builder.build();
}

/**
 * Custom ScanCallback object - adds to adapter on success, displays error on failure.
 */
private class SampleScanCallback extends ScanCallback {
    @Override
    public void onBatchScanResults(List<ScanResult> results) {
        super.onBatchScanResults(results);

        for (ScanResult result : results) {

        }

    }

    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        Log.v("onscanResult","onscanRes");
        Toast.makeText(context.getApplicationContext(), "scan resulted ! ", Toast.LENGTH_SHORT).show();
        //get the data from advertise:
        byte[] Service_Data_bytes=result.getScanRecord().getServiceData(Constants.Service_UUID);
        if(Service_Data_bytes!=null) {
            String Service_Data = new String(Service_Data_bytes);
            Log.v("scanRes:", Service_Data);

            createNewcross(result);
        }
    }
    public void createNewcross(ScanResult scanResult){
        Log.v("createNewcross ", "new cross " );
        byte[] Service_Data_bytes=scanResult.getScanRecord().getServiceData(Constants.Service_UUID);//gilad
        String Service_Data = new String(Service_Data_bytes);


        String other_user=Service_Data ;

    }

    @Override
    public void onScanFailed(int errorCode) {
        super.onScanFailed(errorCode);
        Log.v("ble_process","scan_failed_error_code: "+errorCode);
        Toast.makeText(context.getApplicationContext(), "scan failed! ", Toast.LENGTH_SHORT).show();

        }


    }

}
}

this is the code that operate the scanning:

public void start_central_ble(Context context){//scaning service
    Log.v("ble_process","start_central_ble");
    if (mBluetoothAdapter.isEnabled())
        central.setBluetoothAdapter(mBluetoothAdapter);
    central.startScanning();
}

the timer that operates it:

private class StartCentralTask extends TimerTask {
    Context ServiceContext;

    private StartCentralTask(Context context) {
        ServiceContext = context;
    }

    @Override
    public void run() {
        // run on another thread
        mHandler.post(new Runnable() {
            @Override
            public void run() {

                start_central_ble(ServiceContext);

            }
        });
    }
}
Community
  • 1
  • 1
Gilad Levinson
  • 234
  • 2
  • 12
  • What android device and os version do you have? The only thing you must make sure to do is to call close on BluetoothGatt objects, stop started scans and stop advertising once you are finished since every object takes up one slot. – Emil Jan 26 '17 at 20:31
  • moto g 1st gen. android 5.1 (or maybe 5.2) . I close the scans and advertise quite a lot. how can I close the BluetoothGatt ? I don't even use it . – Gilad Levinson Jan 26 '17 at 21:09
  • I've got a Moto G (3rd gen), running Android 5.1.1. I tried to start a BLE scanner and as soon as I got av advertisement packet, I stopped scan and started a new BLE scanner. That did not increase the clientIf used for the next object. Same thing with BLE advertiser, starting and stopping works fine and it doesn't increase the clientIf each time. Could you post the code you use? – Emil Jan 27 '17 at 21:20
  • I added some code for your request. hope it will help . – Gilad Levinson Jan 28 '17 at 13:39
  • The only possible problems I see in that code is if you start a new scan before the previous one has been stopped. Then you will cancel the wrong scan in the timeout. Is that possibly the cause? Did you have some code for advertising also? Advertisers and scanners are allocated from the same pool of GATT clients. – Emil Jan 28 '17 at 14:34
  • few things I wanted to understand from your comment: can the BT make more than 1 scan simultaneously ? if yes, how can I make sure I stop the correct scan ? – Gilad Levinson Jan 28 '17 at 23:55
  • by the way,I noticed now that my android is 5.1. as I understood, there is a memory leak problem in this version that was solved in version 5.1.1. maybe it affects the ble too ? – Gilad Levinson Jan 29 '17 at 23:26
  • No idea about memory leak. Where did you see that? Anyway, the BLE hardware can only do one scan, but Android's BLE implementation multiplexes many scanner objects onto one real scan. You must make sure you cancel the correct SampleScanCallback in your timeout handler to cancel the correct scan, since the variable mScanCallback may change. – Emil Jan 30 '17 at 00:16
  • Emil,thanks for your answer ! it helped me solve the problem of clientif getting bigger,but the problem of ble errors after a while didn't end. guess I'll try to get a device with newer android ,as I can understand from here : http://stackoverflow.com/questions/32656938/bluetooth-le-advertising-fails-when-started-and-stopped-cyclically – Gilad Levinson Feb 14 '17 at 11:41

0 Answers0