我能看到 Android 上的蓝牙设备有两种状态:
1. 已配对
2. 连接中。
我正在尝试获取当前已连接的 Android 蓝牙设备。但我只能从 adapter.getBondedDevices();
获取已配对的设备列表。我需要获取当前连接的设备。请有经验的人帮助我实现这个功能。先谢谢。
我能看到 Android 上的蓝牙设备有两种状态:
1. 已配对
2. 连接中。
我正在尝试获取当前已连接的 Android 蓝牙设备。但我只能从 adapter.getBondedDevices();
获取已配对的设备列表。我需要获取当前连接的设备。请有经验的人帮助我实现这个功能。先谢谢。
这很简单。Android BluetoothManager 有一个方法叫做
getConnectedDevices()
实现方式如下:
BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
List<BluetoothDevice> connected = manager.getConnectedDevices(GATT);
Log.i("Connected Devices: ", connected.size()+"");
如果您想了解有关连接设备的更多详细信息,则可以使用上面的列表方法将其放入循环中,并获取每个已连接蓝牙设备的内部详细信息。
日志:
12-20 18:04:09.679 14933-14933/com.salman.dleague.blescanning I/Connected Devices:: 2
希望它有所帮助 :)<receiver android:name=".MyBluetoothReceiver" >
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"
/>
<action
android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"
/>
</intent-filter>
</receiver>
添加这个类
public class MyBluetoothReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(getApplicationContext(),device.getName() +" CONNECTED",Toast.LENGTH_LONG).show();
} else if (BluetoothAdapter.ACL_DISCONNECTED
.equals(action)) {
}
}
}
我之前使用了一种方法来获取通过“耳机”配置文件连接的设备,但是我在使用三星Galaxy Watch 4时遇到了问题,因为它被识别为“耳机”设备,即使它不支持音频。当只是询问是否连接了“耳机”时,这会带来问题,因为您可能会无意中尝试将音频发送到该设备,即使它不支持音频。
要获取所有已连接的设备,您需要使用ServiceListener
。好消息是,服务侦听器将始终列出已连接的设备,并且您可以使用它来检查它们是否支持音频。为了进一步简化事情,我使用了以下回调流程:
@OptIn(ExperimentalCoroutinesApi::class)
internal fun headsetConnectedAndSupportsAudio() = callbackFlow<Boolean> {
val serviceListener = object : BluetoothProfile.ServiceListener {
override fun onServiceDisconnected(profile: Int) = Unit // no op
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
var connected = false
var supportsAudio = false
// check for a device that supports audio and is connected in our connected bluetooth devices.
for (device in proxy.connectedDevices) {
connected = proxy.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED
supportsAudio = device.bluetoothClass.hasService(BluetoothClass.Service.AUDIO)
Timber.d("Bluetooth Device - ${device.name} isConnected: $connected supportsAudio: $supportsAudio")
// we have found a connected device that supports audio, stop iterating and emit a success
if (connected && supportsAudio) { break }
}
trySend(connected && supportsAudio)
.onClosed { throwable -> Timber.e(throwable) }
.isSuccess
getBluetoothAdapter().closeProfileProxy(profile, proxy)
close()
}
}
// register our service listener to receive headset connection updates
getBluetoothAdapter().getProfileProxy(
context,
serviceListener,
BluetoothProfile.HEADSET
)
awaitClose { channel.close() }
}
然后要使用回调流,你可以这样做:
mainScope.launch {
headsetConnectedAndSupportsAudio().cancellable().collect { btAudioSourceConnected ->
if (btAudioSourceConnected) {
Timber.d("Bluetooth headset connected + supports audio"
} else {
Timber.d("No Bluetooth headset connected that supports audio")
}
}
}
我们可以使用反射技术来调用Android SDK方法以获取已连接设备。以下是对我有效的代码。
private void checkBluetoothGamepadIsConnected() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Class<BluetoothAdapter> bluetoothAdapterClass = BluetoothAdapter.class;
boolean isConnectedGamePad = false;
try {
Method method = bluetoothAdapterClass.getDeclaredMethod("getConnectionState",
(Class[]) null);
//Open permission.
method.setAccessible(true);
int state = (int) method.invoke(adapter, (Object[]) null);
LogUtil.d("MainViewModel" + "getConnectedBluetooth() state:" + state);
LogUtil.d(TAG + "getConnectedBluetooth() state:" + state
+ " stateSTATE_CONNECTED:" + BluetoothAdapter.STATE_CONNECTED
+ " STATE_CONNECTING:" + BluetoothAdapter.STATE_CONNECTING
+ " STATE_DISCONNECTED:" + BluetoothAdapter.STATE_DISCONNECTED);
Set<BluetoothDevice> devices = adapter.getBondedDevices();
LogUtil.d(TAG + "getConnectedBluetooth devices.size:" + devices.size());
for (BluetoothDevice device : devices) {
Method isConnectedMethod = BluetoothDevice.class.getDeclaredMethod("isConnected",
(Class[]) null);
method.setAccessible(true);
boolean isConnected = (boolean) isConnectedMethod.invoke(device, (Object[]) null);
LogUtil.d(TAG + "getConnectedBluetooth() isConnected:" + isConnected
+ " getAddress:" + device.getAddress() + " getName:" + device.getName());
if (isConnected) {
LogUtil.d(TAG + "getConnectedBluetooth() ** Connected getAddress:"
+ device.getAddress() + " getName:" + device.getName() + " getBondState:"
+ device.getBondState() + " getType:" + device.getType());
if(device.getName().contains(GAMEPAD_NAME)){
isConnectedGamePad = true;
break;
}
}
}
} catch (Exception e) {
LogUtil.d(TAG + "getConnectedBluetooth() error:" + e.toString());
e.printStackTrace();
}
isGamePadConnectedData.postValue(isConnectedGamePad);
}
您使用以下方法无法知道设备当前是否连接,必须使用调用来检查连接或未连接。
Set<BluetoothDevice> devices = adapter.getBondedDevices();
Set<BluetoothDevice> devices = adapter.getBondedDevices();
LogUtil.d(TAG + "getConnectedBluetooth devices.size:" + devices.size());
for (BluetoothDevice device : devices) {
Method isConnectedMethod = BluetoothDevice.class.getDeclaredMethod("isConnected",
(Class[]) null);
method.setAccessible(true);
boolean isConnected = (boolean) isConnectedMethod.invoke(device, (Object[]) null);
LogUtil.d(TAG + "getConnectedBluetooth() isConnected:" + isConnected
+ " getAddress:" + device.getAddress() + " getName:" + device.getName());
if (isConnected) {
LogUtil.d(TAG + "getConnectedBluetooth() ** Connected getAddress:"
+ device.getAddress() + " getName:" + device.getName() + " getBondState:"
+ device.getBondState() + " getType:" + device.getType());
if(device.getName().contains(GAMEPAD_NAME)){
isConnectedGamePad = true;
break;
}
}
}
关于常量GAMEPAD_NAME是我的蓝牙设备名称, 我的做法是检查我的蓝牙是否已连接。
当我的蓝牙连接时,它将返回true。 变量isConnectedGamePad = true;
我的livedata将发布布尔值isConnect。
这个功能非常好用。