蓝牙配对和连接设备

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

    }
2个回答

12
您没有说明,但我假设您的问题在套接字创建部分而不是实际的connect()调用中。这通常是出错的地方。
如何修复?
  1. 你的代码假定耳机支持不安全的蓝牙通信。在许多情况下这是正确的,但并非所有情况都是如此。尝试调用createRfcommSocketToServiceRecord()。

  2. 你的代码使用默认的SPP UUID进行RFCOMM通道查找。对于API版本>= 15,这是错误的做法。相反,尝试调用device.getUuids()并使用第一个返回的UUID作为创建参数。 从我的经验来看,即使对于pre-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文档中找到连接客户端的代码,这里
我看到有4个可能导致问题的原因:
  • 您应该在单独的线程中进行连接!.connect()是一个阻塞调用-请参见上面的链接
  • 并非所有设备都接受不安全的连接
  • 对于低于2.3.3的Android设备,此方法不起作用。 您必须通过反射调用私有方法-请参见此处。 另外,我认为您会在SO上找到它。
  • 请使用try / catch包围.create.... 并将错误发布在Logcat上。
您能发布您的Logcat日志吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接