蓝牙配对和连接设备

时间:2012-09-17 03:39:49

标签: android bluetooth connect

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

 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 个答案:

答案 0 :(得分:13)

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

如何解决?

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

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

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

  5. 请记住将您的逻辑放在AsyncTask中。您不希望UI线程阻止此类任务!

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

答案 1 :(得分:2)

引用您的代码:

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

您可以在官方Android文档中找到有关作为客户端here进行连接的代码。

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

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

您可以发布Logcat日志吗?