Bluetooth на 2.0+

1

Я занимаюсь разработкой bluetooth для подключения к ПК. Я в основном использовал BTChatExample и изменил UUID на стандартный профиль SPP для ПК.

  • Попытка закрыть приложение bluetooth во время чтения блокировки, закрыв BluetoothSocket, вы оставите стек Bluetooth в непригодном для использования состоянии. Это можно устранить, отключив и включив bluetooth и перезапустив приложение. При проверке logcat вы можете увидеть, что некоторые внутренние методы не работают, оставляя открытый порт. Любая информация об этом?

  • Прежде всего, существуют швы, которые могут отличаться от того, как bluetooth реализован на N1 и HTC Legend/Desire с обоими 2.1, знаете ли вы что-нибудь об этом?

  • Подключение не на 100% надежное, иногда я получаю предупреждение ~PortSystemContext init: FAILED. Это оставляет непригодным Bluetooth-устройство, и требуется перезапуск.

  • Правильно ли я полагаю, что SPP является единственным профилем, поддерживаемым для использования с API? Об этом говорят документы в BluetoothAdapter.

Мне бы хотелось обсудить проблемы с bluetooth с разработчиком и устранить эти ошибки, чтобы Android мог иметь хорошую надлежащую поддержку Bluetooth, которой он заслуживает.

Теги:

3 ответа

2

Закрытие сокета в одном потоке во время чтения блокировки обязательно должно привести к тому, что чтение будет возвращено (путем выброса IOException) и не должно оставлять стек в "плохом состоянии". Это поведение на Droid и Nexus.

Я говорил прямо с оригинальным плакатом, и он наблюдал эту проблему на HTC Legend и HTC Desire. Похоже, что они неправильно реализуют API. Я поднимаю вопрос с ними.

Вы правы, что SPP/RFCOMM является единственным профилем, который предназначен для использования с API. SPP/RFCOMM получает потоковое сокет, который достаточно хорош для многих случаев использования.

В настоящее время я рекомендую разработку BT на Nexus One/Motorola Droid, которые считаются "справочными" реализациями API Bluetooth.

1

Могу ли я предположить, что вы не выполняете блокировку вызовов read(), если только вы не проверили, что данные готовы к чтению, используя inputstream.available(), который возвращает целое число, указывающее, сколько байтов ожидает во входном буфере.

    long timeouttime = gettimeinseconds() + 2;
    String response = "";

    while (gettimeinseconds() < timeouttime) {
      if (inputstream.available() > 0)
          response = response + inputstream.read();
      } else {
          Thread.sleep(100); // sleep to slow down the while() loop. 
      }
    }
return response;

Это просто псевдокод и его упрощение. Суть в том, что мы не выполняем блокирующие вызовы (read()), если мы не уверены, что они вернутся немедленно без задержки.

Кроме того, я рекомендую использовать BufferedInputStream вместо стандартного InputStream.

0

Кто-нибудь может решить эту проблему?

Я пробую следующий код:

// Keep listening to the InputStream while connected
while (!isInterrupted)
{
    try
    {
        //Clear buffer
        buffer = new byte[1024];

        // Read from the InputStream
        if (mmInStream != null && mmInStream.available() > 0)
        {
            if (isInterrupted)
                break;

            bytes = mmInStream.read(buffer);

            // Send the obtained bytes to the UI Activity
            mHandler.obtainMessage(Act_Main.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
        }
        else
        {
            try
            {
                synchronized (this)
                {
                    this.wait(100);
                }

                if (isInterrupted)
                    break;
            }
            catch(InterruptedException ex)
            {
                Log.e(TAG, "WAIT_EXCEPTION:"+ ex.getMessage());
            }
        }
    }
    catch(Exception ex)
    {
        Log.e(TAG, "disconnected", ex);
        connectionLost();
        break;
    }
}

И я изменил isInterrupted логическое значение в методе cancel(). Вот мой метод stop():

/**
 * Stop all threads
 */
public synchronized void stop()
{
    isStop = true ;

    if (D)
        Log.d(TAG, "stop");

    if(mConnectThread != null)
    {
        mConnectThread.cancel();
        mConnectThread = null;
    }

    if(mConnectedThread != null)
    {
        mConnectedThread.cancel();
        mConnectedThread = null;
    }

    setState(STATE_NONE);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню