Что запускает трансляцию BluetoothDevice.ACTION_ACL? - PullRequest
25 голосов
/ 02 марта 2012

Я хотел бы знать, какие события в удаленных физических устройствах вызывают ACTION_ACL_CONNECTED и ACTION_ACL_DISCONNECTED в прослушивающем устройстве. Результаты моего теста не имеют смысла. Я собрал несколько устройств в нескольких дециметрах друг от друга:

  • Galaxy Tab P7500 под управлением Android 3.1
  • телефон i5500 под управлением Android 2.2
  • ПК WinXP с USB-ключом Bluetooth
  • две гарнитуры с кнопками включения / выключения

Во-первых, я вручную соединяюсь со всеми устройствами из вкладки. Ни ПК, ни телефон не сопряжены с каким-либо другим устройством, кроме Tab. (Одна из гарнитур никак не может быть найдена на вкладке, но ее легко найти с телефона как вручную, так и программно). Затем у меня есть простое приложение для запуска обнаружения, которое слушает и отображает трансляции ACL. И вот что происходит (то же самое каждый раз, это соответствует в своем безумии):

  • startDiscovery() из вкладки со всеми включенными устройствами: - ПК является единственным найденным устройством
  • Отключить Bluetooth на ПК: - Нет реакции на вкладке
  • Включить Bluetooth на ПК: - Нет реакции на вкладке
  • Включите гарнитуру 1 раз: - ACTION_ACL_CONNECTED на вкладке
  • Отключение гарнитуры: - Нет реакции на вкладке
  • Снова включите гарнитуру: - ACTION_ACL_DISCONNECTED и ACTION_ACL_CONNECTED в быстрой последовательности на вкладке
  • Отключить Bluetooth на вкладке: - Нет реакции на вкладке
  • Включить Bluetooth на вкладке: - Гарнитура ACTION_ACL_CONNECTED на вкладке
  • startDiscovery() с телефона: - ПК является единственным устройством, обнаруженным телефон, хотя телефон сопряжен только с вкладкой, а не с ПК. В противном случае телефон реагирует только на гарнитуру, на которой никогда не реагирует на.

Что делать из этого беспорядка? Разве нельзя полагаться на устройство, вызывающее ACTION_ACL_CONNECT, даже если оно сопряжено и включается в пределах диапазона?

Вот методы BroadcastReceiver и действия onCreate, но я не ожидаю, что детали в этом коде будут иметь значение:

BroadcastReceiver intentReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (device != null) {
            name = device.getName();
        Log.v(TAG, "Device=" + device.getName());
        }
        else {
            name = "None";
        }

        if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
            text1.setText(name + " connected " + (checkCounter++));
            Log.v(TAG, "connected: " + device);
        }
        else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
            text2.setText(name + " disconnected " + (checkCounter++));
        Log.v(TAG, "disconnected: " + device);
        }
        else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            text3.setText( name + " found " + (checkCounter++));
        Log.v(TAG, "found: " + device + "");
        }
        else if (blueAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            text4.setText("Started " + (checkCounter++));
            Log.v(TAG, "Discovery started");
        }
        else if (blueAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            text4.setText("Finished " + (checkCounter++));
            Log.v(TAG, "Discovery finished");
        }
    }
};


public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.bluetoothlayout);

    text1 = (TextView)findViewById(R.id.textView1);
    text2 = (TextView)findViewById(R.id.textView2);
    text3 = (TextView)findViewById(R.id.textView3);
    text4 = (TextView)findViewById(R.id.textView4);

    BluetoothDevice mw600 =         blueAdapter.getRemoteDevice("58:17:0C:EB:C5:08");
    BluetoothDevice bt500 =         blueAdapter.getRemoteDevice("00:1D:43:00:C4:54");
    BluetoothDevice galaxyTab = blueAdapter.getRemoteDevice("00:07:AB:6A:96:7D");
    BluetoothDevice pcDongle =  blueAdapter.getRemoteDevice("00:15:83:4D:8B:57");

    intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
    intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
    intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    intentFilter.addAction(blueAdapter.ACTION_DISCOVERY_STARTED);
    intentFilter.addAction(blueAdapter.ACTION_DISCOVERY_FINISHED);
    if (!isReceiverRegistered) {
        registerReceiver(intentReceiver, intentFilter);
        isReceiverRegistered = true;
    }
    if (!blueAdapter.isEnabled()) {
        blueAdapter.enable();
    }
    blueAdapter.startDiscovery();
}

1 Ответ

16 голосов
/ 03 октября 2012

Я работаю с андроидами, которые действительно давно испортили BT,

вот что я могу вам сказать:

ACTION_ACL_CONNECTED отправляется всякий раз, когда установлено успешное соединение.Это так же просто, как и получается.

Теперь довольно раздражающая часть.

ACTION_ACL_DISCONNECTED отправляется всякий раз, когда соединение закрывается на уровне аппаратного обеспечения.КОГДА это происходит, это немного зависит от самого устройства.ЕСЛИ вы вручную отключаете / подключаете другое устройство, оно почему-то не отправляет сигнал «чувак, я ушел» дроиду, вместо этого через 20 секунд некоторые сторожевые устройства лают, и соединение закрывается, и намерение отправляется.

Теперь я попробовал это только с устройствами SPP, к которым я подключаюсь.Гарнитура afaik активно подключается сама по себе, потому что это не SPP.Таким образом, он автоматически подключается к вам, если вы находитесь в паре и в режиме прослушивания.Теперь я не знаю, что делает гарнитура, если вы "выключите ее".Может быть, он отключается должным образом или просто разрывает соединение, не попрощавшись.В последнем случае сторожевой таймер может отключиться со стороны дроида, что может занять от 0 до 20 секунд, не спрашивайте меня, почему, это просто мое наблюдение.

...