Невозможно принять входящее соединение Bluetooth в Android - PullRequest
0 голосов
/ 14 декабря 2011

Может быть, похоже на тему без ответа здесь , но у нас есть приложение для Android (протестировано на нескольких телефонах и на нескольких версиях Android 2.1+), которое должно прослушивать и принимать подключения от удаленного устройства Bluetooth.Удаленное устройство представляет собой цифровое перо, но главное в том, что перо соединяется с телефоном, а затем отправляет данные через SPP, который использует OBEX, который использует RFComm, так что все должно быть в порядке.

В настоящее времяПриложение работает, позволяя устройству Android получать полезную нагрузку OBEX, а затем заставлять приложение искать в папке bluetooth, чтобы получить полезную нагрузку, но мы хотим, чтобы приложение могло напрямую общаться с удаленным устройством. Имейте в виду, что пульт дистанционного управления подключается к телефону Android, телефон не подключается к перу.

Наш тестовый код основан на примере приложения BluetoothChat, доступном в примерах Android, но по существуadapter.listenUsingRfcommWithServiceRecord никогда не вызывается, и лучшее, что мы видим в журналах Motorola Defy + DDMS:

INFO/BtOppRfcommListener(2577): Accepted connectoin from 00:07:CF:55:94:FB
INFO/BtOpp Service(2577): Start Obex Server
DEBUG/Obex ServerSession(2577): java.io.IOException: Software caused connection abort

Похоже, что это соединение принято Android, но недоступнок заявке.Используемый UUID - это тот же UUID, который использовался в версии JME того же приложения и был предоставлен поставщиком ручки.

Ответы [ 2 ]

1 голос
/ 27 июня 2013

В нашем случае единственное найденное нами решение, которое могло бы надежно принимать данные Bluetooth OPP с удаленного устройства, заключалось в использовании «скрытого» Android API. Если вы проверяете исходный код Android, то будут определены дополнительные методы, аннотированные @hide, что исключает их из экспортированного jar-файла Android и документов API.

Следует избегать использования этих методов, если это возможно, и не обязательно быть совместимыми с версиями Android.

Есть два способа включить их в ваш код:

  1. использовать отражение
  2. включает дополнительный JAR-файл разработки во время компиляции, который предоставляет эти методы, но убедитесь, что этот JAR-файл не включен в ваше приложение.

Мы выбрали № 1, так как наши требования были минимальными.

Доступ к методу

Class<?>[] args = new Class[] { int.class };
Method listenMethod = BluetoothAdapter.class.getMethod(listenMethod, args);

Где имя метода является одним из (в порядке предпочтения) listenUsingEncryptedRfcommOn, listenUsingRfcommOn или listenUsingUnencrytptedRfcommOn

Создать сокет сервера

BluetoothAdapter target = *your adapter, probably the default one*;
BluetoothServerSocket sock = (BluetoothServerSocket) (listenMethod.invoke(target, new Object[] { channel }));

Где в нашем случае канал OPP равен 12

Fin

Если вам удастся получить обратно BluetoothServerSocket (обработка исключений пропущена, ваш пробег может отличаться, рекомендуется усмотрение пользователя, гарантия не предоставляется и т. Д. И т. Д.), Вы должны иметь возможность использовать его для прослушивания входящих данных OPP.

1 голос
/ 28 декабря 2011

Самая распространенная ошибка, которую мы, разработчики Android, делаем при копировании кода приложения BluetoothChat, заключается в том, что мы не следим за ходом этого приложения.

Распространенные ошибки при реализации этого кода, такие как «Ошибка обнаружения службы», «Прерывание соединения из-за программного обеспечения», «Соединение прервано узлом», «Невозможно запустить обнаружение службы», «Потеряно соединение» является результатом пренебрежения поток.

Я столкнулся со всеми этими проблемами при внедрении кода BluetoothChat в моем приложении, и решение было исправить поток.

Например, в моем случае:

        OnCreate:

            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        OnStart:

        if(this.mChatService == null)
                this.mChatService = new BluetoothChatService(this, mHandler);

        OnResume:
        if ((mChatService != null) &&  (mBluetoothAdapter.isEnabled())) {
    // Only if the state is STATE_NONE, do we know that we haven't started already
            if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
                        // Start the Bluetooth chat services
                        mChatService.start();
                    }
                }
        OnDestroy:
        if(mTransferService != null) mTransferService.stop();

   onActivityResult:
    case REQUEST_CONNECT_DEVICE:
    // When DeviceListActivity returns with a device to connect
    if (resultCode == Activity.RESULT_OK) {
    if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
            // Start the Bluetooth chat services
            mChatService.start();
            }
    if(mChatService .getState() != BluetoothChatService.STATE_CONNECTED){
    String address = data.getExtras().getString(ViewContactList.EXTRA_DEVICE_ADDRESS);
        // Get the BLuetoothDevice object
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        device = mBluetoothAdapter.getRemoteDevice(address);
        // Attempt to connect to the device
        mChatService.connect(device);
        }
        else{
        if(messageString.length() > 0)
        MyCurrentActivity.this.sendMessage(messageString);
        }

Проще говоря, реализуйте код таким образом, чтобы оба устройства находились в mState = STATE_LISTEN, прежде чем вы вызовете

mChatService.connect(device);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...