2017년 7월 8일 토요일

Android BLE Beacon scanning on different phone models


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;
}

--
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.

--
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.

--

댓글 1개: