工作问题记录
工作笔记¶
1. 蓝牙的启动与关闭¶
1. 使用Service
¶
在MainActivity
启动时,检查数据库中是否已经存在登录后的账户数据。如果有,就获取这些账户的uuid
,开启service
。
1 2 3 |
|
2. 开启蓝牙¶
服务用于实现低功耗蓝牙单独的控制,在服务的onCreate
中开启蓝牙
1 2 3 4 5 |
|
3. 在BluetoothService
的onDestory
中关闭蓝牙。¶
1 2 3 4 5 6 |
|
2. 登录模块¶
1. 开启蓝牙¶
在启动MainActivity
时,检查是否存在账户信息,若存在,直接开启蓝牙。
1 2 3 4 5 6 7 8 9 10 |
|
2. 连接状态改变¶
当设备被连接后会触发回调中的onConnectionStateChange
方法。
3. 接收消息¶
当设备被成功连接后,会收到客户端发来的用户名。在onCharacteristicWriteRequest
中接收该用户名,如果该用户名匹配成功,就打开DialogActivity
让用户确认是否登录。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
用户点击确认登录后,调用onResponseToClient()
方法向客户端发送密码。
1 2 3 4 5 6 7 8 9 |
|
4. 记录登录信息¶
1 |
|
3. 注册模块¶
通过点击屏幕右下角的按钮,申请摄像头权限,打开扫码页面。通过扫描客户端生成的二维码,获取账户信息。保存这些信息,数据库插入成功后开启蓝牙进行广播。
1. 保存扫码信息¶
1 2 3 4 5 6 7 8 9 10 |
|
2. 开启蓝牙¶
同登录模块的openService()
方法。由于扫码结束后会重新启动MainActivity
,因此和登录模块一起在Activity
启动时开启服务即可。
3. 接收消息¶
同登录模块的onCharacteristicWriteRequest()
,接收到消息:listening
4. 发送消息¶
在onCharacteristicWriteRequest()
中,返回消息:done!
1 2 3 |
|
4. 问题与解决¶
1. 扫码后向客户端发送数据¶
流程
- 扫码注册后会获取到用户的注册信息,将该信息通过子线程插入到
room
数据库中 - 如果插入成功,就向客户端发送消息:
done!
问题
- 通过
writeCharacteristic
发送数据不成功,获取到的数据都是空的,猜测可能的问题是在子线程里发送蓝牙消息不正确 - 后改到主线程,客户端依旧闪退。于是检查蓝牙类的单例是否出了问题,但是单例没写错。
- 又想或者是通过
writeCharacteristic
发送数据的方式不对,另一种看到的发送方法为notifyCharacteristicChanged
。 - 尝试通过点击按钮发送数据,这样是成功的,这可以确定不是参数、回调中发送数据导致的问题。
- 调试后发现原项目将蓝牙的启动和关闭绑定在了
MainActivity
的启动和销毁中,在MainActivity
生命周期结束后会导致蓝牙断开,从而导致发送消息闪退。
解决方法
- 将数据库插入的返回值作为
LiveData
监控,当它变化且不为0
时,进行数据的发送 - 创建一个
Service
类,将蓝牙的开启与关闭和它绑定在后台运行,这样Activity
不管怎么切换,都不会影响蓝牙的开关了。 Service
的启动放在Activity
启动和开启相机的时候,在成功发送完数据后关闭Service
,从而避免一直开启蓝牙而占用手机资源、消耗性能。
2. 多设备蓝牙配对问题1¶
问题
有好几个手机、电脑同事扫码注册/登录时,如何保证准确连接上自己的设备?
解决方法
-
由电脑端在生成的二维码中放入一个随机
uuid
,在手机端扫码后保存好这个uuid
。 -
手机端使用该
uuid
开启蓝牙服务,再由电脑端去连接。
这样就能保证电脑和手机蓝牙连接的时候,uuid
是一一对应的了。
3. 多设备蓝牙配对问题2¶
问题
由问题1又产生了新的问题,如果一个人同时有好几个设备,每个设备在注册前都随机生成了一个uuid
。那么在登录时,手机端应当使用哪个uuid
进行蓝牙广播?
解决思路
-
可以全部进行广播,然后让客户端查询它需要的
uuid
主动连接。 -
让用户点击账号,通过该账号的点击来发布对应的
uuid
服务。但是用户得知道登录前要点击登录的设备。 -
两层嵌套的方式,客户端先用默认的
uuid
发送一个登录请求,这个请求中包含它自己的uuid
,服务端查询表项中有没有这个uuid
,有的话就直接连接,没有就丢弃。
这个想法不行,客户端只有建立了连接才能发送uuid
,使用默认uuid
建立连接的话又会产生多设备配对问题。
4. 蓝牙主设备无法被扫描到¶
问题
在某一次代码更新后,用同事的手机广播蓝牙,其他设备搜索不到它。但是我的手机可以正常广播并连接,这导致了我们猜测是手机系统问题,而没有第一时间查看日志有没有输出报错。
一开始以为是uuid
生成不正确的问题,但是网上都是随机生成的uuid
。
随后发现我的手机是鸿蒙系统,同事的是Android
系统,所以猜测是不是系统的问题,但依旧不是这个问题。
经过排查,发现是服务端广播失败了,报错ADVERTISE_FAILED_DATA_TOO_LARGE
。
解决问题
最后发现是因为广播数据包括uuid
+device name
,字段太长导致广播失败。应当取消发送设备名称。