蓝牙自动配对怎么实现

明年就要毕业了,所以最近开始刷面试题,碰到了一个问题“蓝牙自动配对怎么实现的?”,刚开始有点懵逼了。于是学习一波,记录下来。

1 实现过程及原理

  配对是建立连接的基础,任何从未配对过的设备(或曾经配对但其中一方已删除配对关系)都无法建立连接,因此配对无法绕过。配对的方式有输入pin码、输入密码、免输入的随机验证码等多种。当前XX设备与控制端的配对方式为免输入的随机验证码,两端确认6位数密码一致,点击“确认配对”即可完成配对。但由于XX设备无法用户交互,所以只能由程序完成确认实现自动配对——当然,XX设备只针对确定来源的请求(如XX助手)才默认同意并接受配对。

2 查找设备的方式

  蓝牙开启后查找设备的方式有两种:搜索和指定mac,用搜索功能查找蓝牙设备涉及“可见性”的概念,蓝牙对外可见(即能被别的蓝牙设备搜索到)最多可设置为300s(5分钟),而指定的mac方式没有时间限制,只要蓝牙开启就可以找到设备,因为XX设备与控制端需要随时能(配对)连接,显然搜索查找的方式,不适用于XX设备。因此只能选择指定mac地址的方式。

3 相关代码实现

3.1 注册权限

  因为需要实现蓝牙配对,所以需要开启蓝牙相关的权限,在Android的清单文件中申请如下权限:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" />

3.2 注册广播

  BoradcastReceiver(想更了解百度)在Android中充当的是传递数据和消息的作用。所以这是实现蓝牙自动配置的关键。其注册方式分为静态注册和动态注册。

3.2.1 动态注册

  动态注册就是采用activity内部实现广播类,采用java代码的方式实现,相关代码如下:

// 注册Receiver来获取蓝牙设备相关的结果(主要逻辑是第一行和最后一行代码)
IntentFilter intent = new IntentFilter();
// 用BroadcastReceiver来取得搜索结果
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);
// searchDevices表示广播类,详细了解百度
registerReceiver(searchDevices, intent);

注:动态配置结尾必须在Activity中的生命周期函数onDestroy()中调用销毁广播逻辑,代码为:this.unregisterReceiver(searchDevices);

3.2.2 静态注册

  静态注册就是把广播类注册到清单文件中,写个广播类,之后在清单文件中填写相关代码,代码如下:

// 类地址
<receiver android:name=".broadcast.BluetoothReceiver" >
    <intent-filter android:priority="1000">
    	// 详细了解百度
        <action android:name="android.bluetooth.device.action.PAIRING_REQUEST"/>
        <action android:name="android.bluetooth.device.action.FOUND"/>
    </intent-filter>
</receiver>

注:idea中我一般直接可以新建一个广播类,也不用填写上面代码,但是你配置更详细一些需要添加action节点。

3.3 配对逻辑

  在广播中的广播接收回调函数onReceive()实现配对逻辑,这里建议跳转阅读一下BluetoothAdapter的API使用,文章时间可能有点老,但是非常全面,其相关代码如下:

// 我这里没有代码重构,我看一下,网上都把其操作逻辑封装在工具类中。
@Override
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;
    // 搜索设备时,取得设备的MAC地址
    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
        device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (device.getBondState() == BluetoothDevice.BOND_NONE) {
            String str = "未配对|" + device.getName() + "|"
                    + device.getAddress();
            if (lstDevices.indexOf(str) == -1)// 防止重复添加
            {
                lstDevices.add(str);
            }
            // 获取设备名称和mac地址
            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", "正在配对......");
                break;
            case BluetoothDevice.BOND_BONDED:
                Log.d("BlueToothTestActivity", "完成配对");
                connect(device);//连接设备
                break;
            case BluetoothDevice.BOND_NONE:
                Log.d("BlueToothTestActivity", "取消配对");
            default:
                break;
        }
    }
}

总结

  以上写的是蓝牙自动配对的整个过程,是一个思路以及主要代码,但作为程序猿的我们理论上掌握肯定不行的。所以我会上传两个demo(分别代表静态注册和动态注册)。有问题大家一起探头。@[email protected],qq也是这个哦。(要代码直接@我不需要积分的哦)。

发布了39 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/a1920135141/article/details/100610238