【发布时间】:2010-10-14 10:32:16
【问题描述】:
如何在安卓上列出所有连接的蓝牙设备?
谢谢!
【问题讨论】:
-
你有解决方案吗?我正在寻找相同的,请提供答案。
如何在安卓上列出所有连接的蓝牙设备?
谢谢!
【问题讨论】:
public void checkConnected()
{
// true == headset connected && connected headset is support hands free
int state = BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(BluetoothProfile.HEADSET);
if (state != BluetoothProfile.STATE_CONNECTED)
return;
try
{
BluetoothAdapter.getDefaultAdapter().getProfileProxy(_context, serviceListener, BluetoothProfile.HEADSET);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private ServiceListener serviceListener = new ServiceListener()
{
@Override
public void onServiceDisconnected(int profile)
{
}
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy)
{
for (BluetoothDevice device : proxy.getConnectedDevices())
{
Log.i("onServiceConnected", "|" + device.getName() + " | " + device.getAddress() + " | " + proxy.getConnectionState(device) + "(connected = "
+ BluetoothProfile.STATE_CONNECTED + ")");
}
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(profile, proxy);
}
};
【讨论】:
从 API 14(Ice Cream)开始,Android 有一些新的 BluetoothAdapter 方法,包括:
public int getProfileConnectionState (int profile)
其中配置文件是HEALTH, HEADSET, A2DP 之一
检查回复,如果不是STATE_DISCONNECTED,你就知道你有一个实时连接。
下面是适用于任何 API 设备的代码示例:
BluetoothAdapter mAdapter;
/**
* Check if a headset type device is currently connected.
*
* Always returns false prior to API 14
*
* @return true if connected
*/
public boolean isVoiceConnected() {
boolean retval = false;
try {
Method method = mAdapter.getClass().getMethod("getProfileConnectionState", int.class);
// retval = mAdapter.getProfileConnectionState(android.bluetooth.BluetoothProfile.HEADSET) != android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
retval = (Integer)method.invoke(mAdapter, 1) != 0;
} catch (Exception exc) {
// nothing to do
}
return retval;
}
【讨论】:
BluetoothAdapter:最终蓝牙适配器 btAdapter = BluetoothAdapter.getDefaultAdapter();
if (btAdapter != null && btAdapter.isEnabled()) // null 表示没有 蓝牙!
如果蓝牙没有打开,您可以使用文档中不推荐的btAdapter.enable() 或要求用户这样做:Programmatically enabling bluetooth on Android
final int[] states = new int[] {BluetoothProfile.STATE_CONNECTED, 蓝牙配置文件.STATE_CONNECTING};
第四,你创建一个BluetoothProfile.ServiceListener
包含连接服务时触发的两个回调,并且
断开连接:
final BluetoothProfile.ServiceListener listener = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
}
@Override
public void onServiceDisconnected(int profile) {
}
};
现在,由于您必须对 Android SDK (A2Dp, GATT, GATT_SERVER, Handset, Health, SAP) 中的所有可用蓝牙配置文件重复查询过程,您应该按照以下步骤进行:
在onServiceConnected 中,放置一个检查当前配置文件的条件,以便我们将找到的设备添加到正确的集合中,并使用:proxy.getDevicesMatchingConnectionStates(states) 过滤掉未连接的设备:
switch (profile) {
case BluetoothProfile.A2DP:
ad2dpDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.GATT: // NOTE ! Requires SDK 18 !
gattDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.GATT_SERVER: // NOTE ! Requires SDK 18 !
gattServerDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.HEADSET:
headsetDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.HEALTH: // NOTE ! Requires SDK 14 !
healthDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.SAP: // NOTE ! Requires SDK 23 !
sapDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
}
最后,要做的最后一件事是开始查询过程:
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.A2DP);
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.GATT); // NOTE ! Requires SDK 18 !
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.GATT_SERVER); // NOTE ! Requires SDK 18 !
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.HEADSET);
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.HEALTH); // NOTE ! Requires SDK 14 !
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.SAP); // NOTE ! Requires SDK 23 !
【讨论】:
这样你就得到了配对设备的列表。
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevicesList = btAdapter.getBondedDevices();
for (BluetoothDevice pairedDevice : pairedDevicesList) {
Log.d("BT", "pairedDevice.getName(): " + pairedDevice.getName());
Log.d("BT", "pairedDevice.getAddress(): " + pairedDevice.getAddress());
saveValuePreference(getApplicationContext(), pairedDevice.getName(), pairedDevice.getAddress());
}
【讨论】:
Android 系统不允许您查询所有“当前”连接的设备。但是,您可以查询配对设备。您将需要使用广播接收器来侦听 ACTION_ACL_{CONNECTED|DISCONNECTED} 事件以及 STATE_BONDED 事件,以更新您的应用程序状态以跟踪当前连接的内容。
【讨论】:
我找到了一个解决方案,它适用于 android 10
private val serviceListener: ServiceListener = object : ServiceListener {
var name: String? = null
var address: String? = null
var threadName: String? = null
override fun onServiceDisconnected(profile: Int) {}
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
for (device in proxy.connectedDevices) {
name = device.name
address = device.address
threadName = Thread.currentThread().name
Toast.makeText(
this@MainActivity,
"$name $address$threadName",
Toast.LENGTH_SHORT
).show()
Log.i(
"onServiceConnected",
"|" + device.name + " | " + device.address + " | " + proxy.getConnectionState(
device
) + "(connected = "
+ BluetoothProfile.STATE_CONNECTED + ")"
)
}
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(profile, proxy)
}
}
BluetoothAdapter.getDefaultAdapter()
.getProfileProxy(this, serviceListener, BluetoothProfile.HEADSET)
【讨论】:
请在线分析this class。
您将在此处了解如何发现所有已连接(配对)的蓝牙设备。
【讨论】:
以下是步骤:
首先,您开始意图发现设备
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
为它注册一个广播接收器:
registerReceiver(mReceiver, filter);
关于mReceiver的定义:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
arrayadapter.add(device.getName())//arrayadapter is of type ArrayAdapter<String>
lv.setAdapter(arrayadapter); //lv is the list view
arrayadapter.notifyDataSetChanged();
}
}
并且该列表将在新设备发现时自动填充。
【讨论】: