Сканирование Android BLE Beacon на разных моделях телефонов

Я пишу Android-приложение для поиска и обнаружения IBeacons (это устройства BLE) и их ранжирование (в зависимости от значения RSSI). Я использую пример кода из https://developer.android.com/guide/topics/connectivity./bluetooth-le.html

Но этот код работает по-разному на моих устройствах Android (Samsung Galaxy S3 и LG G3).

На моем S3 обратный вызов «onLeScan» многократно увеличивается в цикле (около 5 в секунду) и каждый раз дает мне разные значения RSSI в зависимости от диапазона.

Но на моем LG G3 обратный вызов «onLeScan» возникает только один раз, когда я запускаю сканирование. поэтому, если я хочу получить новые значения RSSI, мне нужно перезапустить сканирование. И я думаю, что это не очень хорошо.

Я не знаю, то ли это что-то не так с драйвером LG G3, или я должен проверить некоторые настройки Android. Может ли кто-нибудь сказать мне что-нибудь об этом?

Вот мой код:

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

person Иван Зверев    schedule 27.10.2014    source источник
comment
Используете ли вы то же оборудование маяка в пляжном чехле? Что за модель маяка? Кроме того, какая версия Android установлена ​​на каждом устройстве?   -  person davidgyoung    schedule 27.10.2014
comment
Да, у меня всего 1 IBeacon Cc2541 (купил здесь: wellcorping.en.made-in-china.com/product/cSUnrYpPTuWE/) Версии Android: 4.4.2 для G3 и 4.3 для S3   -  person Иван Зверев    schedule 27.10.2014
comment
это известная разница из-за фильтрации Bluetooth. Различные устройства/бренды реализуют сканирование BLE на Android по-разному. stackoverflow.com/ вопросы/19502853/. Я не уверен, что вы можете сделать что-нибудь, чтобы это исправить.   -  person benka    schedule 27.10.2014
comment
Это плохо. поэтому мне приходится перезапускать сканирование каждый раз, когда мне нужны новые значения RSSI. (   -  person Иван Зверев    schedule 27.10.2014


Ответы (2)


К сожалению, вам нужно остановить и перезапустить сканирование, чтобы получить дополнительные обратные вызовы. Именно так это реализовано в Android Beacon Library, которая останавливает сканирование каждые 1,1 секунды, а затем сразу перезапускается. Это позволяет получить один обратный вызов за цикл в случаях, когда операционная система не выполняет обратный вызов для каждого объявления.

Неясно, как именно это зависит от устройства и версии операционной системы. На Nexus 4 с Android 4.3 поведение при сканировании рекламных объявлений BLE с подключением отличалось от объявлений BLE без подключения. Подключаемые рекламные объявления вызывают только один обратный вызов объявления за цикл сканирования, тогда как неподключаемые объявления получают несколько обратных вызовов за цикл сканирования. Это поведение может отличаться на других устройствах и версиях ОС, поэтому циклирование необходимо для широкой совместимости.

На устройствах Nexus 5 с Android 5.0 новые API сканирования всегда возвращают несколько обратных вызовов для каждого объявления BLE с одного устройства, независимо от того, можно ли подключить объявление или нет. Однако устройства Nexus 4 с Android 5.0 по-прежнему получают только один обратный вызов рекламы для подключаемых рекламных объявлений, пока сканирование не будет остановлено и перезапущено. Похоже, это реализовано на уровне драйвера, поэтому для каждого образа ПЗУ это может быть разным.

person davidgyoung    schedule 27.10.2014

См. этот ответ. Спецификация BLE говорит, что вам необходимо получать отчет по каждой рекламе, если только вы не перезапустите сканирование. Так что некоторые телефоны делают, а некоторые нет. Вы не можете полагаться на это.

Идиотский поступок, на мой взгляд.

person Timmmm    schedule 28.03.2015