0

I am writing Android Application on finding and detecting IBeacons(These are BLE devices) and ranging them(depending on RSSI value) I use Sample code from https://developer.android.com/guide/topics/connectivity/bluetooth-le.html

But this Code works different on my android devices (Samsung Galaxy S3 and LG G3).

On my S3 the "onLeScan" callback rises many times in loop (about 5 per second) and give me different RSSI values every time depending on the range.

But on my LG G3 the "onLeScan" callback rises only once, when i start Scanning. so if i want to obtain new RSSI values, i need to restart scanning. And i think it is not very good.

I don't know whether it is something wrong with LG G3 driver, or i must check some android settings. Can any one tell me something about it?

Here is my Code:

public class Main2Activity extends Activity implements BluetoothAdapter.LeScanCallback {

private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

    /**/
    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        enableBtIntent.addFlags(enableBtIntent.FLAG_ACTIVITY_NEW_TASK);
        this.startActivity(enableBtIntent);

    }   
    scanLeDevice(true);
}

private void scanLeDevice(final boolean enable) {
    if (enable) {
        // Stops scanning after a pre-defined scan period.
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mScanning = false;
                mBluetoothAdapter.stopLeScan(Main2Activity.this);
            }
        }, 30000);

        mScanning = true;
        mBluetoothAdapter.startLeScan(Main2Activity.this);
    } else {
        mScanning = false;
        mBluetoothAdapter.stopLeScan(Main2Activity.this);
    }
}

ArrayList<String> datas = new ArrayList<String>();
@Override
public void onLeScan(BluetoothDevice arg0, int arg1, byte[] arg2) {
    // TODO Auto-generated method stub
    datas.add( arg2.toString() );
}



@Override
public boolean onOptionsItemSelected(MenuItem item) {
    return super.onOptionsItemSelected(item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return true;
}
  • Are you using the same beacon hardware in beach case? What beacon model is it? Also, what Android version is on each device? – davidgyoung Oct 27 '14 at 11:42
  • Yes, i got just 1 IBeacon Cc2541(bought here: http://wellcorping.en.made-in-china.com/product/cSUnrYpPTuWE/China-Cc2541-Ibeacon-with-Colorful-Housing.html) Android versions: 4.4.2 on G3, and 4.3 on S3 – Иван Зверев Oct 27 '14 at 11:49
  • this is a known difference due to Bluetooth filtering. Different devices / brands implement BLE scanning on android differently. http://stackoverflow.com/questions/19502853/android-4-3-ble-filtering-behaviour-of-startlescan. I'm not sure you can do anything to "fix" it. – benka Oct 27 '14 at 12:06
  • That's poor. so i have to restart scanning, every time i need new RSSI values.( – Иван Зверев Oct 27 '14 at 12:32

2 Answers2

2

Unfortunately, you need to stop and restart scanning to get additional callbacks. This is exactly how it is implemented in the Android Beacon Library, which stops scanning every 1.1 seconds and then immediately restarts. This makes it possible to get at one callback per cycle in cases where the operating system is not making a callback for every advertisement.

It is unclear exactly how this varies between devices and operating system versions. On the Nexus 4 with Android 4.3, scanning behavior was different for connectable BLE advertisements vs. non-connectable BLE advertisements. Connectable advertisements cause only one advertisement callback per scan cycle, whereas non-connectable advertisements receive multiple callbacks per scan cycle. This behavior may vary on other devices and OS versions, which is why cycling is necessary for wide compatibility.

On Nexus 5 devices with Android 5.0, the new scanning APIs always return multiple callbacks for each BLE advertisement from the same device, regardless of whether the advertisement is connectable or not. Nexus 4 devices with Android 5.0, however still only get one advertisement callback for connectable advertisements until the scan is stopped and restarted. This appears to be implemented at the driver level, so it is may be different for each ROM image.

davidgyoung
  • 59,109
  • 12
  • 105
  • 181
0

See this answer. The BLE spec says you don't have to get a report for each advertisment, unless you restart scanning. So some phones do and some don't. You can't rely on it.

An idiotic move in my opinion.

Community
  • 1
  • 1
Timmmm
  • 68,359
  • 51
  • 283
  • 367