Android Studio:发现蓝牙设备名称未找到且无法配对设备。

3

我开发了一个应用程序,它使用特定的蓝牙模块(HC-06)进行通信,但首先需要将其配对,使用以下代码进行配对...

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
ListView lView;
ArrayList<String> devNameList, devAddressList;

private ListAdapter arrayAdapter;
private ConnectThread mConnectThread;
private BluetoothSocket mmSocket = null;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final static int REQUEST_ID = 2;

// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Discovery has found a device. Get the BluetoothDevice
            // object and its info from the Intent.
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            String devName = device.getName();
            String devAddress = device.getAddress();

            devAddressList.add(devAddress);

            if (devName == null){
                devName = device.getAddress();
            }

            devNameList.add(devName);

            lView.setAdapter(arrayAdapter);
        }
    }
};

private class ConnectThread extends Thread {
    ConnectThread(BluetoothDevice device) {
        BluetoothSocket tmp = null;

        try {
            // Get a BluetoothSocket to connect with the given BluetoothDevice.
            // MY_UUID is the app's UUID string, also used in the server code.
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            Toast.makeText(getBaseContext(), "ERROR: Socket's create() method failed", Toast.LENGTH_SHORT).show();
        }
        mmSocket = tmp;
    }

    public void run() {
        try {
            // Connect to the remote device through the socket. This call blocks
            // until it succeeds or throws an exception.
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and return.
            try {
                mmSocket.close();
            } catch (IOException closeException) {
                Toast.makeText(getBaseContext(), "ERROR: Could not close the client socket",
                        Toast.LENGTH_SHORT).show();
            }
            return;
        }
        // The connection attempt succeeded. Perform work associated with
        // the connection in a separate thread.
        manageMyConnectedSocket();
    }

    // Closes the client socket and causes the thread to finish.
    void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Toast.makeText(getBaseContext(), "ERROR: Could not close the client socket",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_new_device);

    requestPermissions();

    lView = findViewById(R.id.discList);

    devNameList = new ArrayList<>();
    devAddressList = new ArrayList<>();
    arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, devNameList);

    if (mBluetoothAdapter.isDiscovering()){
        mBluetoothAdapter.cancelDiscovery();
    }
    // Register for broadcasts when a device is discovered.
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mReceiver, filter);
    mBluetoothAdapter.startDiscovery();

    lView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String devName = devNameList.get(position);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if((Objects.equals(devName, "HC-06"))|| (Objects.equals(devName, "00:21:13:00:97:6A"))){
                    Toast.makeText(AddNewDevice.this, "Please wait...", Toast.LENGTH_SHORT).show();

                    mBluetoothAdapter.cancelDiscovery();

                    String address = devAddressList.get(position);
                    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                    mConnectThread = new ConnectThread(device);
                    mConnectThread.run();
                }
                else{
                    Toast.makeText(AddNewDevice.this, "Please connect to an HC-06 device.", Toast.LENGTH_SHORT).show();
                }
            }
            else {
                if("HC-06".equals(devName) || "00:21:13:00:97:6A".equals(devName)){
                Toast.makeText(AddNewDevice.this, "Please wait...", Toast.LENGTH_SHORT).show();

                mBluetoothAdapter.cancelDiscovery();

                String address = devAddressList.get(position);
                BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                mConnectThread = new ConnectThread(device);
                mConnectThread.run();
                }
                else{
                    Toast.makeText(AddNewDevice.this, "Please connect to an HC-06 device.", Toast.LENGTH_SHORT).show();
                }
            }
        }
    });
}

private void requestPermissions(){
    int androidVersion = Build.VERSION.SDK_INT;
    if (androidVersion >= 23){
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                }, REQUEST_ID);
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(mReceiver);
    mBluetoothAdapter.cancelDiscovery();
}

private void manageMyConnectedSocket() {
    mConnectThread.cancel();
    finish();
}

这段代码在运行API 17(Android 4.2.2)的设备上表现良好,但在API 23(Android 6.0)的设备上有些小问题:
首先,有时它能够找到设备名称,有时则不能(这就是为什么我在设备列表[devNameList]中的第50和51行[如果您复制了该代码]添加了一个getAddress行而不是getName,在没有导入头文件的情况下的23和24行)。
其次,当它无法获取设备名称并且我尝试连接时,它会努力配对/连接设备(在我的蓝牙设置中,它只显示“配对...”直到永远),但当它成功获取设备名称时,则可以正确地配对。
有人能帮我解决这个问题吗?
1个回答

1
我在几天前回答了这个问题,链接如下。您在使用较新版本的Android时遇到的问题是需要粗略和精确位置权限才能使用较新版本的Android进行发现。一旦包括这些权限,找到设备并与其配对应该可以正常工作。
链接: 无法发现可用的蓝牙设备 以下是我在上面链接中发布的内容:
尝试添加粗略位置权限。 我的应用程序同时具有Fine和Coarse,并且适用于API 19(Kit Kat),API 21(Lollipop),API 23(Marshmallow)和API 24(Nougat)。
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

在到达应用程序的这一点之前,请确保您请求权限。因此,在onCreate中添加以下方法以确保在Android的更高版本上请求权限。我知道我也需要添加此代码才能使其正常工作。您可以使用自己定义的int来进行REQUEST_ID。当您加载面向较高版本的Android的应用程序时,它将弹出提示框。

private int androidVersion; //define at top of code as a variable

private void requestPermissions(){
androidVersion = Build.VERSION.SDK_INT;
        if (androidVersion >= 23){
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION,                                
                    }, REQUEST_ID);
        }
    }

1
我认为你并没有完全理解我的问题。我能够发现附近的本地蓝牙设备,但有时候在发现HC-06设备的元数据时存在不完整的情况(我无法获取设备的名称,但可以获取设备的地址)。这似乎使得手机难以连接到该设备。 - Vutivi Mashele
抱歉回复晚了。 连接蓝牙所需的仅是地址,而非设备名称本身。 因此,1. 声明设备对象:BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress); 2. 按照 Android 中 BluetoothChat 示例中的说明进行连接。 - Zachariah Rabatah

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