【问题标题】:bluetooth pair and connect device蓝牙配对并连接设备
【发布时间】:2012-09-17 03:39:48
【问题描述】:

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

 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();
                    }
            }

    }

}

【问题讨论】:

    标签: android bluetooth connect


    【解决方案1】:

    您尚未指定,但我认为您的问题出在套接字创建部分,而不是实际的 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 接口。

    【讨论】:

      【解决方案2】:

      引用您的代码:

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

      您可以在 Android 官方文档中找到有关以客户端身份连接的代码,here

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

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

      你能发布你的 Logcat 日志吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-18
        • 1970-01-01
        • 1970-01-01
        • 2021-04-26
        • 1970-01-01
        • 2015-10-26
        • 2016-06-08
        • 1970-01-01
        相关资源
        最近更新 更多