web-dev-qa-db-ja.com

AndroidでBluetoothを使用したサービス検出失敗の例外

現在、Bluetoothを介して機器に接続し、文字列コマンドを作成して文字列応答を受信する必要があるAndroidアプリケーションで作業しています。現在、TCP/IP over Wi-FiでBluetoothを実装しようとしていますが、いくつかの障害に直面しています。似たような例を見つけようとしてWebを検索し、運がありませんでした。Android開発者リソースの例:私の主な参照ポイントとしてのBluetoothチャット。

現在のコードは機能しているようです。その後、接続のポイントでService Discovery Failed例外をスローします。 DeviceListActivityクラスを使用して、接続するデバイスの検出と選択を行います。 anActivityResultを返し、Bluetoothクラスがそれを処理するのを待ってから、接続します。下のコードは、Bluetoothチャットアプリとほぼ同じです。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(!m_BluetoothAdapter.isEnabled())
    {
        m_BluetoothAdapter.enable();
    }
    switch (requestCode) {
        case REQUEST_CONNECT_DEVICE:
            // When DeviceListActivity returns with a device to connect
            if (resultCode == Activity.RESULT_OK) {
                // Get the device MAC address
                String address = data.getExtras()
                                     .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
                // Get the BLuetoothDevice object
                BluetoothDevice device = m_BluetoothAdapter.getRemoteDevice(address);
                // Attempt to connect to the device
                connect(device);
            }
            break;

        case REQUEST_ENABLE_BT:
            // When the request to enable Bluetooth returns
            if (resultCode == Activity.RESULT_OK) {
                // Bluetooth is now enabled, so set up a chat session
            }
            else {
                // User did not enable Bluetooth or an error occured

                Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_SHORT).show();
                finish();
            }
    }
}

これは私の接続機能です:

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

private void connect(BluetoothDevice device) {
    m_Device = device;
    BluetoothSocket tmp = null;

    // Get a BluetoothSocket for a connection with the
    // given BluetoothDevice
    try {
        tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
    }
    catch (IOException e) {

    }
    m_Socket = tmp;

    m_BluetoothAdapter.cancelDiscovery();

    try {
        // This is a blocking call and will only return on a
        // successful connection or an exception
        m_Socket.connect();
    }
    catch (IOException e) {
        try {
            m_Socket.close();
        }
        catch (IOException e2) {
        }
        return;
    }
}

うまくいけば、私が間違っていることは何でも簡単ですが、簡単ではないことを恐れています。 Bluetooth開発を行うのはこれが初めてであり、多分私はあからさまに間違ったことをしているのかもしれません...

電話でいつでも手動でデバイスをペアリング/検索できます。パスコードが必要ですが、私が抱えている問題ではないと思います。

49
TxAg

3日後、非常に役立つ投稿のおかげで理解できました。

私は交換する必要がありました:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

で:

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
         tmp = (BluetoothSocket) m.invoke(device, 1);

そしてそれはうまくいきます!

93
TxAg

API 15以降、次のメソッドを使用できます。

UUIDをBluetoothDeviceクラスの getUuids ()メソッドの戻り値に置き換えてみてください。私のために働いたのは次のようなものでした:

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);

これが機能する理由は、異なるデバイスが異なるUUIDをサポートし、 getUuids を使用してデバイスのUUIDを取得することにより、すべての機能とデバイスをサポートしているためです。

もう1つの興味深い新しいメソッド(API 14以降でサポートされています)は、 BluetoothHealth.getConnectionState です。試していませんが、有望に見えます...

13
Muzikant

これは 匿名ユーザーからの提案された編集 受け入れられた回答への返信の試みでした。

ビフォーコードとアフターコードの大きな違いの1つは、渡すUUIDです。私はここで答えを見つけました: http://developer.Android.com/reference/Android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord(Java.util.UUID)

私は交換する必要がありました:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

で:

private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
tmp = device.createRfcommSocketToServiceRecord(SPP_UUID);

そして出来上がり!元のコードは、ピアツーピアAndroidアプリです。シンプルなシリアルBluetoothデバイスに接続するときにアプリのUUIDを使用することは意味がありません。そのため、検出に失敗します。

2
Rup

上記で述べたように、ポイントは、サーバーが待機しているUUIDを使用する必要があるということです。

ヘッドセットやマウスなどのBluetoothデバイスに接続している場合、デバイスがリッスンしているUUIDを確認する必要があります。このようなUUIDを確認できます。

UUID[] uuids = bluetoothDevice.getUuids();

これらのUUIDの意味を知りたい場合は、 this を参照してください。

1
Devgrapher

これは本当に古い質問ですが、前述のcreateInsecureRfcommSocketToServiceRecord()とともにcreateRfcommSocketToServiceRecord()の代わりにgetUuids()を使用すると、私のためのトリック

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
1