4

我想配对设备并连接它,但我有一个问题,我只能配对设备但我无法连接它们。我想知道如何解决这个问题。恐怕,我没有很好地解释我的问题,我无法连接意味着,将你的手机连接到蓝牙耳机,我只能配对,这是代码

 if (btAdapt.isEnabled()) {
                    tbtnSwitch.setChecked(false);
            } else {
                    tbtnSwitch.setChecked(true);
            }
            // ============================================================

            IntentFilter intent = new IntentFilter();
            intent.addAction(BluetoothDevice.ACTION_FOUND);
            intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
            intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
            registerReceiver(searchDevices, intent);
    }

    private BroadcastReceiver searchDevices = new BroadcastReceiver() {

            public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    Bundle b = intent.getExtras();
                    Object[] lstName = b.keySet().toArray();


                    for (int i = 0; i < lstName.length; i++) {
                            String keyName = lstName[i].toString();
                            Log.e(keyName, String.valueOf(b.get(keyName)));
                    }
                    BluetoothDevice device = null;

                    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                            device = intent
                                            .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            if (device.getBondState() == BluetoothDevice.BOND_NONE) {
                                    String str = "no pair|" + device.getName() + "|"
                                                    + device.getAddress();
                                    if (lstDevices.indexOf(str) == -1)
                                            lstDevices.add(str); 
                                    adtDevices.notifyDataSetChanged();
                            }
                    }else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
                            device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            switch (device.getBondState()) {
                            case BluetoothDevice.BOND_BONDING:
                                    Log.d("BlueToothTestActivity", "it is pairing");
                                    break;
                            case BluetoothDevice.BOND_BONDED:
                                    Log.d("BlueToothTestActivity", "finish");
                                    connect(device);
                                    break;
                            case BluetoothDevice.BOND_NONE:
                                    Log.d("BlueToothTestActivity", "cancel");
                            default:
                                    break;
                            }
                    }

            }
    };

    @Override
    protected void onDestroy() {
            this.unregisterReceiver(searchDevices);
            super.onDestroy();
            android.os.Process.killProcess(android.os.Process.myPid());
    }

    class ItemClickEvent implements AdapterView.OnItemClickListener {

            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) 
            {
                    if(btAdapt.isDiscovering())btAdapt.cancelDiscovery();
                    String str = lstDevices.get(arg2);
                    String[] values = str.split("\\|");
                    String address = values[2];
                    Log.e("address", values[2]);
                    BluetoothDevice btDev = btAdapt.getRemoteDevice(address);
                    try {
                            Boolean returnValue = false;
                            if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {
                                  BluetoothDevice.createBond(BluetoothDevice remoteDevice);
                                    Method createBondMethod = BluetoothDevice.class
                                                    .getMethod("createBond");
                                    Log.d("BlueToothTestActivity", "start");
                                    returnValue = (Boolean) createBondMethod.invoke(btDev);

                            }else if(btDev.getBondState() == BluetoothDevice.BOND_BONDED){
                                    connect(btDev);
                            }
                    } catch (Exception e) {
                            e.printStackTrace();
                    }

            }

    }

    private void connect(BluetoothDevice btDev) {
            UUID uuid = UUID.fromString(SPP_UUID);
            try {
                    btSocket = btDev.createInsecureRfcommSocketToServiceRecord(uuid);
                    Log.d("BlueToothTestActivity", "connecting...");
                    btSocket.connect();
            } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }
    }

    class ClickEvent implements View.OnClickListener {
            public void onClick(View v) {
                    if (v == btnSearch)
                    {
                            if (btAdapt.getState() == BluetoothAdapter.STATE_OFF) {
                                    Toast.makeText(BlueToothTestActivity.this, "please open", 1000)
                                                    .show();
                                    return;
                            }
                            if (btAdapt.isDiscovering())
                                    btAdapt.cancelDiscovery();
                            lstDevices.clear();
                            Object[] lstDevice = btAdapt.getBondedDevices().toArray();
                            for (int i = 0; i < lstDevice.length; i++) {
                                    BluetoothDevice device = (BluetoothDevice) lstDevice[i];
                                    String str = "pair|" + device.getName() + "|"
                                                    + device.getAddress();
                                    lstDevices.add(str); 
                                    adtDevices.notifyDataSetChanged();
                            }
                            setTitle("address:" + btAdapt.getAddress());
                            btAdapt.startDiscovery();
                    } else if (v == tbtnSwitch) {
                            if (tbtnSwitch.isChecked() == false)
                                    btAdapt.enable();

                            else if (tbtnSwitch.isChecked() == true)
                                    btAdapt.disable();
                    } else if (v == btnDis)
                    {
                            Intent discoverableIntent = new Intent(
                                            BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                            discoverableIntent.putExtra(
                                            BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                            startActivity(discoverableIntent);
                    } else if (v == btnExit) {
                            try {
                                    if (btSocket != null)
                                            btSocket.close();
                            } catch (IOException e) {
                                    e.printStackTrace();
                            }
                            BlueToothTestActivity.this.finish();
                    }
            }

    }

}

4

2 回答 2

13

您尚未指定,但我认为您的问题出在套接字创建部分而不是实际的 connect() 调用中。这是事情通常出错的地方。

怎么修?

  1. 您的代码假定耳机支持不安全的 BT 通信。在许多情况下,这是真的,但并非完全如此。尝试调用 createRfcommSocketToServiceRecord()

  2. 您的代码使用默认的 SPP UUID 进行 RFCOMM 通道查找。对于 API 版本 >= 15,这是错误的做法。而是尝试调用 device.getUuids() 并使用第一个返回的 UUID 作为创建参数。根据我自己的经验,即使对于 15 之前的 API 版本,您仍然可以调用 getUuids() 并获得良好的结果,但您需要通过反射来完成。仅当上述失败时,您才应尝试使用默认 SPP UUID 创建套接字

  3. 如果上述方法失败,作为最后的手段,您可以尝试激活“createRfcommSocket”隐藏 API。这对我有用好几次,并且适用于多个 Android 版本。使用 java 反射来激活此调用,并且由于本质上不安全,因此使用 try catch 保护它。

  4. 请记住将您的逻辑放在 AsyncTask 或其他东西中。您不希望 UI 线程阻塞此类任务!

最后随意使用https://github.com/giladHaimov/BTWiz来更简单地处理蓝牙连接和简单的异步 IO 接口。

于 2014-06-24T16:10:45.410 回答
2

引用您的代码:

 btSocket = btDev.createInsecureRfcommSocketToServiceRecord(uuid);
 Log.d("BlueToothTestActivity", "connecting...");
 btSocket.connect();

您可以在此处找到有关以客户端身份连接的官方 Android 文档的代码。

我可以看到可能导致问题的 4 件事:

  • 你应该在一个单独的线程中连接!.connect() 是一个阻塞调用 - 见上面的链接
  • 并非所有设备都接受不安全的连接
  • 对于 2.3.3 以下的 Android 设备,此方法不起作用。您必须通过反射调用私有方法 - 请参阅。另外,我认为您会在 SO 上找到它。
  • 围绕 .create.... 使用 try/catch 并在 Logcat 上发布错误。

您可以发布您的 Logcat 日志吗?

于 2012-09-18T14:40:29.643 回答