Android Bluetooth не может подключиться - PullRequest
5 голосов
/ 13 марта 2010

У меня проблема с подключением устройств в Android. Если я зайду в настройки и свяжу их вручную, я смогу подключить их, используя следующий код:

Сервер

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.connect);

    Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    startActivityForResult(discoverableIntent, REQUEST_ENABLE_BT);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if(requestCode == REQUEST_ENABLE_BT)
    {
        if(resultCode == RESULT_CANCELED)
        {
            new AlertDialog.Builder(this)
            .setTitle(R.string.error)
            .setMessage(R.string.bluetooth_unavailable)
            .setPositiveButton(android.R.string.ok, AndroidUtils.DismissListener)
            .create()
            .show();
        }
        else
        {
            mServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("Moo Productions Bluetooth Server", mUUID);
            mState = State.ACCEPTING;
            BluetoothSocket socket = mServerSocket.accept();
            mServerSocket.close();
            connected(socket);
        }
    }
}

Клиент

Set<BluetoothDevice> pairedDevices = mAdapter.getBondedDevices();
BluetoothSocket socket = null;

// Search the list of paired devices for the right one
for(BluetoothDevice device : pairedDevices)
{
    try
    {
        mState = State.SEARCHING;
        socket = device.createRfcommSocketToServiceRecord(mUUID);
        mState = State.CONNECTING;
        socket.connect();
        connected(socket);
        break;
    }
    catch (IOException e)
    {
        socket = null;
        continue;
    }
}

Но если устройства еще не были сопряжены, они выходят из foreach без подключения к действительному сокету. В этом случае я начинаю открывать.

// If that didn't work, discover
if(socket == null)
{
    mState = State.SEARCHING;
    mReceiver = new SocketReceiver();
    mContext.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
    mAdapter.startDiscovery();
}

// ... Later ...

private class SocketReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if(BluetoothDevice.ACTION_FOUND.equals(intent.getAction()))
        {
            try
            {
                // Get the device and try to open a socket
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                BluetoothSocket socket = device.createRfcommSocketToServiceRecord(mUUID);
                mState = State.CONNECTING;
                socket.connect();

                // This is our boy, so stop looking
                mAdapter.cancelDiscovery();
                mContext.unregisterReceiver(mReceiver);

                connected(socket);
            }
            catch (IOException ioe)
            {
                ioe.printStackTrace();
            }
        }
    }
}

Но оно никогда не найдет другое устройство. Я никогда не получаю диалоговое окно сопряжения, и когда я прохожу, я вижу, что он обнаруживает правильное устройство, но ему не удается подключиться с этим исключением java.io.IOException: Service discovery failed. Есть идеи, что мне не хватает?

Ответы [ 2 ]

3 голосов
/ 16 марта 2010

Ваш клиент никогда не обнаружит сервер, если сервер фактически не обнаруживаем. Комментарий вашего кода сервера говорит: «Убедитесь, что устройство доступно для обнаружения», но прослушивание через сокет не означает, что устройство можно обнаружить. Вы можете сделать сервер доступным для обнаружения, позвонив по номеру:

Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);

Это Намерение, потому что система должна активировать обнаружение и только с одобрения пользователя (поэтому откроется диалоговое окно с запросом обнаружения в течение 300 секунд) Только в течение этого 300-секундного периода сервер будет фактически доступен для обнаружения. В течение этого времени ваш клиентский код должен нормально работать, и вы получите запросы на сопряжение.

Все это подробно описано в руководстве разработчика Android: http://developer.android.com/guide/topics/wireless/bluetooth.html

0 голосов
/ 04 июля 2013

Не знаю, по-прежнему ли это актуально, но я сделал это так, и это сработало:

if (BluetoothDevice.ACTION_FOUND.equals(action)) {
  discoveredDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
}

if (discoveredDeviceName.equals("your_device_name")) { 
  mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
}

Кроме того, я попытался бы отменить обнаружение раньше:

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