简体   繁体   English

蓝牙连接无需配对

[英]Bluetooth connect without pairing

The normal way to connect to a bluetooth device is by pairing. 连接蓝牙设备的常用方法是配对。

We need to connect to a device in an abnormal way: By using the Bluetooth MAC address only. 我们需要以异常方式连接到设备:仅使用蓝牙MAC地址。 We do not want to be prompted for a PIN. 我们不希望系统提示您输入PIN码。

We know the device supports this technique, but we cannot find a way to do it on Android. 我们知道该设备支持这种技术,但我们无法在Android上找到这种方法。

The abbreviated code looks like this: 缩写代码如下所示:

  String mac_address = “00:11:22:33:44:55”
  BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

  BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(mac_address);

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

  socket.connect();

The problem is that upon socket.connect() we are prompted for a PIN. 问题是在socket.connect()我们被提示输入PIN。 The PIN is not necessary for this device, so we do not want to be prompted for a PIN. 此设备不需要PIN,因此我们不希望系统提示输入PIN。

The reason we know the PIN is not necessary: 我们知道PIN的原因不是必要的:

  1. We manufacture this device and write the firmware. 我们制造这个设备并编写固件。
  2. We can connect to it using a program on windows written in C#. 我们可以使用C#编写的Windows程序连接到它。

How can we modify the code such that it will not prompt for a PIN? 我们如何修改代码,使其不会提示输入PIN码?

[Edit to test suggestion in comment] [编辑以测试评论中的建议]

We tested method createInsecureRfcommSocketToServiceRecord like this: 我们测试了方法createInsecureRfcommSocketToServiceRecord,如下所示:

ParcelUuid list[] = device.getUuids();
BluetoothSocket  socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(list[0].getUuid());

Then we get error like this: 然后我们得到这样的错误:

I/InputDispatcher(  382): Delivering touch to current input target: action: 0x1
I/InputDispatcher(  382): Delivering touch to current input target: action: 0x1
V/BluetoothSocket.cpp(16956): initSocketNative
V/BluetoothSocket.cpp(16956): ...fd 66 created (RFCOMM, lm = 0)
V/BluetoothSocket.cpp(16956): initSocketFromFdNative
I/BluetoothPolicyService(  382): getBluetoothDataTransferAllowed
D/BluetoothUtils(16956): isSocketAllowedBySecurityPolicy start : device null
V/BluetoothService.cpp(  382): createDeviceNative
V/BluetoothService.cpp(  382): ... address =
V/BluetoothEventLoop.cpp(  382): onCreateDeviceResult
V/BluetoothEventLoop.cpp(  382): onCreateDeviceResult
E/BluetoothEventLoop.cpp(  382): onCreateDeviceResult: D-Bus error: org.bluez.Error.AlreadyExists (Already Exists)
D/BluetoothEventLoop(  382): Result of onCreateDeviceResult:1
V/BluetoothService.cpp(  382): discoverServicesNative
V/BluetoothService.cpp(  382): ... Object Path = /org/bluez/1100/hci0/dev_00_11_22_33_44_55
V/BluetoothService.cpp(  382): ... Pattern = , strlen = 0
D/FStest  (  633): check default
D/FStest  (  633): check default

It's definitely possible. 这绝对是可能的。 You should have a look at the Android BluetoothChat demo app at: http://developer.android.com/samples/BluetoothChat/src/com.example.android.bluetoothchat/BluetoothChatService.html they use the insecure channel: 你应该看看Android蓝牙聊天演示应用程序: http//developer.android.com/samples/BluetoothChat/src/com.example.android.bluetoothchat/BluetoothChatService.html他们使用不安全的渠道:

public ConnectThread(BluetoothDevice device, boolean secure) {
    mmDevice = device;
    BluetoothSocket tmp = null;
    mSocketType = secure ? "Secure" : "Insecure";

    // Get a BluetoothSocket for a connection with the
    // given BluetoothDevice
    try {
        if (secure) {
            tmp = device.createRfcommSocketToServiceRecord(
                    MY_UUID_SECURE);
        } else {
            tmp = device.createInsecureRfcommSocketToServiceRecord(
                    MY_UUID_INSECURE);
        }
    } catch (IOException e) {
        Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
    }
    mmSocket = tmp;
}

on the client side. 在客户端。 And on the server side: 在服务器端:

  public AcceptThread(boolean secure) {
            BluetoothServerSocket tmp = null;
            mSocketType = secure ? "Secure" : "Insecure";

            // Create a new listening server socket
            try {
                if (secure) {
                    tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
                            MY_UUID_SECURE);
                } else {
                    tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
                            NAME_INSECURE, MY_UUID_INSECURE);
                }
            } catch (IOException e) {
                Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
            }
            mmServerSocket = tmp;
        }

Keep in mind that you need the Bluetooth MAC address for this. 请记住,您需要蓝牙MAC地址。 Google is trying to hide the address and make it unusable (to prevent tracking). 谷歌试图隐藏地址并使其无法使用(以防止跟踪)。 You'll have problems getting your own MAC address and the MAC addresses of remote devices are randomised and change after some time: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id 您将无法获得自己的MAC地址,并且远程设备的MAC地址随机化并在一段时间后发生变化: http//developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior -hardware-ID

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM