4

デバイスをペアリングして接続したいのですが、問題があります。デバイスをペアリングできますが、接続できません。この問題を解決する方法を知りたいです。恐れ入りますが、問題について十分に説明していません。手段を接続できません。スマートフォンをBluetoothヘッドセットに接続し、ペアリングすることしかできません。コードは次のとおりです。

 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. コードでは、RFCOMMチャネルルックアップにデフォルトのSPPUUIDを使用します。APIバージョン>=15の場合、これは間違ったことです。代わりに、device.getUuids()を呼び出して、最初に返されたUUIDを作成パラメーターとして使用してみてください。私自身の経験から、15より前のAPIバージョンでも、getUuids()を呼び出して良好な結果を得ることができますが、リフレクションによってそれを行う必要があります。上記が失敗した場合にのみ、デフォルトのSPPUUIDを使用してソケットの作成を試みる必要があります

  3. 上記が失敗した場合は、最後の手段として、「createRfcommSocket」非表示APIをアクティブ化してみてください。それは私にとって何度か、そして複数のAndroidバージョンでうまくいきました。Javaリフレクションを使用してこの呼び出しをアクティブにし、本質的に安全ではないため、trycatchで保護します。

  4. ロジックをAsyncTaskなどに配置することを忘れないでください。UIスレッドがそのようなタスクをブロックすることは望ましくありません!

最後に、 https://github.com/giladHaimov/BTWizを使用して、Bluetooth接続の処理を大幅に簡素化し、非同期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 に答える