问题描述
首先,我在Windows 8.1上使用Android Studio 4.0.1。
因此,对我已经工作了一段时间的应用程序项目进行更多测试时,出现了另一个问题。 在制作一个应用程序时,我偶然发现了这个问题,该应用程序从周围的蓝牙设备收集数据,然后再连接到正确的应用程序(使用Bluetooth Classic而不是Low Energy的自定义嵌入式系统)。
如前一篇文章所述,我在两部不同的手机(具有不同的android版本)上尝试了相同的应用,其中一部使用Android 5.1.1,另一部使用Android 9;考虑到它们各自的权限和限制。
这次,我专门尝试从周围的设备中收集UUID。需要明确的是,获取设备名称及其各自的MAC地址并不费吹灰之力,并且一切都完美地显示在不同的手机上。但是UUID是这些让我非常烦恼的小野兽,似乎Android Studio的用于提取UUID的API有缺陷,并且行为随机,这就是原因:
为简化起见,我制作了另一个非常简单的应用程序,该应用程序从已知设备中收集UUID,这意味着我对要从中获取UUID的MAC地址进行了硬编码。
我创建了一个Button,通过调用以下代码来开始获取:
isFetchUUIDSButtonPressed = true;
bluetoothDiscoveredUUID.clear();
String UUID = "00:00:00:00:00:00"; // MAC ADDRESS IS OBVIOUSLY SOMETHING DIFFERENT,BUT I AM NOT SHOWING IT HERE.
BluetoothManager bluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothDevice mBluetoothDevice = bluetoothManager.getAdapter().getRemoteDevice(UUID);
Log.w(TAG,"BEFORE Check if fetch succeeded: " + checkIfUUIDFetchSucceeded);
checkIfUUIDFetchSucceeded = mBluetoothDevice.fetchUuidsWithSdp();
Log.w(TAG,"AFTER Check if fetch succeeded: " + checkIfUUIDFetchSucceeded);
checkIfUUIDFetchSucceeded = false;
现在,有一个广播接收器向我显示建立ACL连接的时间,因为完成了低级连接以便从所需设备中获取UUID:
////////////////////////////// BLUETOOTH IN GENERAL BROADCAST RECEIVER //////////////////////////////
BroadcastReceiver bluetoothBroadcastReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context,Intent intent){
String action = intent.getAction();
if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
//STATE_OFF = 10;
//STATE_TURNING_ON = 11;
//STATE_ON = 12;
//STATE_TURNING_OFF = 13;
int previousBluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE,BluetoothAdapter.ERROR);
int currentBluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.ERROR);
Log.w(TAG,"Previous Bluetooth Adapter State: " + previousBluetoothState);
Log.w(TAG,"Current Bluetooth Adapter State: " + currentBluetoothState);
if( previousBluetoothState == BluetoothAdapter.STATE_ON ){
//TODO: CANCEL CURRENT OPERATIONS,RESET ALL VARIABLES,LISTVIEWS,BUTTONS,etc,TO THEIR INITIAL STATES.
// this is to guarantee a fresh restart of operations after the Bluetooth adapter is turned ON again.
Log.w(TAG,"Bluetooth Turning Off: RESETTING ALL FIELDS AND VIEWS TO THEIR INITIAL STATES");
resetFields();
}
}
////////////////////////////// CONNECTION ESTABLISHED //////////////////////////////
else if(BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)){
Log.w(TAG,"Provisional Connection to Retrieve UUID");
}
////////////////////////////// DISCONNECTION VERIFIED //////////////////////////////
else if(BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)){
Log.w(TAG,"ACTION_ACL_DISCONNECTED: Provisional connection finished!");
Log.w(TAG,"ACTION_ACL_DISCONNECTED: Disconnected from device");
}
}
};
建立低级连接后,将获取UUID并将其捕获到另一个广播接收器上:
////////////////////////////// UUIDs BROADCAST RECEIVER //////////////////////////////
private final BroadcastReceiver UUIDBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context,Intent intent) {
String action = intent.getAction();
if( BluetoothDevice.ACTION_UUID.equals(action) && isFetchUUIDSButtonPressed){
Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
Log.e(TAG,"FROM ACTION_UUID");
bluetoothDiscoveredUUID.add(new ArrayList<UUID>());
if (uuids != null) {
for (Parcelable ep : uuids) {
Log.e(TAG,"UUID = " + ep.toString());
bluetoothDiscoveredUUID.get((bluetoothDiscoveredUUID.size()) - 1).add(UUID.fromString(ep.toString()));
}
}
else{
bluetoothDiscoveredUUID.get((bluetoothDiscoveredUUID.size()) - 1).add(nullUUID);
Log.e(TAG,"Null UUID");
}
Log.w(TAG,"UUID data acquired");
isFetchUUIDSButtonPressed = false;
}
}
};
现在,事情发生的假定顺序是:
- 已发送获取命令
- 建立ACL连接以从设备中检索UUID
- 检索到UUID
- ACL连接已终止。
让我们弄清楚这一点:
- UUID广播接收器获取存储在缓存中的UUID(如果设备是 之前在同一会话中发现的。蓝牙之后 适配器已关闭,在该会话期间发现了所有设备 现在已删除存储在缓存中的数据,因此,当打开蓝牙适配器并尝试 从现在关闭的另一台设备获取UUID,该值在广播内部获取 接收器现在为空。
实际上:
- 从已经搜索过的设备中获取UUID时,事物应该发生,随机发生或根本不发生的顺序。
- 并非总是有临时的ACL连接来从设备中检索UUID。
- 即使在获取缓存的UUID之后,也会执行ACL连接和断开连接。
这是一遍又一遍地在同一设备上获取UUID之后的记录结果:
D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
W/MainActivity: BEFORE Check if fetch succeeded: false
W/MainActivity: AFTER Check if fetch succeeded: true
E/MainActivity: FROM ACTION_UUID
Null UUID -------------------------------------->>>> //Other device is off and no UUIDs stored in cache
W/MainActivity: UUID data acquired
D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
W/MainActivity: BEFORE Check if fetch succeeded: false
W/MainActivity: AFTER Check if fetch succeeded: true
W/MainActivity: Provisional Connection to Retrieve UUID!
E/MainActivity: FROM ACTION_UUID
UUID = 00001101-0000-1000-8000-00805f9b34fb
UUID = 00000000-0000-1000-8000-00805f9b34fb
W/MainActivity: UUID data acquired
W/MainActivity: ACTION_ACL_DISCONNECTED: Provisional connection finished!
ACTION_ACL_DISCONNECTED: Disconnected from device
D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
W/MainActivity: BEFORE Check if fetch succeeded: false
W/MainActivity: AFTER Check if fetch succeeded: true
E/MainActivity: FROM ACTION_UUID
UUID = 00001101-0000-1000-8000-00805f9b34fb
UUID = 00000000-0000-1000-8000-00805f9b34fb
W/MainActivity: UUID data acquired
D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
W/MainActivity: BEFORE Check if fetch succeeded: false
W/MainActivity: AFTER Check if fetch succeeded: true
E/MainActivity: FROM ACTION_UUID
UUID = 00001101-0000-1000-8000-00805f9b34fb
UUID = 00000000-0000-1000-8000-00805f9b34fb
W/MainActivity: UUID data acquired
W/MainActivity: Provisional Connection to Retrieve UUID!
W/MainActivity: ACTION_ACL_DISCONNECTED: Provisional connection finished!
ACTION_ACL_DISCONNECTED: Disconnected from device
我可以确认这不是特定于设备的问题,因为它发生在不同的手机上,并且从其他设备(蓝牙键盘,其他手机,耳机等)获取UUID时,我也可以确认这不仅是滞后记录日志,因为在我正在使用的更完整的应用程序上,与ACL连接和断开连接有关的标志根本不会被触发,或者也不会按照它们应该发生的顺序被触发。
那么...在这篇漫长的帖子之后...这里发生了什么事?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)