最近一直在做手机硬件相关的东西的,接触到了手机蓝牙,这篇文章主要介绍经典蓝牙相关的东西,下篇文章将介绍低功耗蓝牙BLE相关的东西,由于时间的关系,只是一个大概的总结和记录,相关要点在注释里面。
一、常用的蓝牙操作
1、打开蓝牙
public static void openBluetooth() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!bluetoothAdapter.isEnabled()) {
bluetoothAdapter.enable();
}
}
public static void openBluetooth(Activity a) {
final BluetoothManager bluetoothManager =
(BluetoothManager) a.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
if (bluetoothAdapter != null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
a.startActivityForResult(enableBtIntent, BLUETOOTH_CODE);
}
}
2、关闭蓝牙
public static void closeBluetooth() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter.isEnabled()) {
bluetoothAdapter.disable();
}
}
3、判断蓝牙是否打开
public static void openBluetooth() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!bluetoothAdapter.isEnabled()) {
bluetoothAdapter.enable();
}
4、获取已经配对的蓝牙信息
public void getConnectedBluetoothDevices(JsGetConnectedBluetoothBean bean) {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
JsCreateDevicesBean jsCreateDevicesBean = new JsCreateDevicesBean();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
LogUtils.d("BlueTooth已配对的设备:" + device.getAddress() + "----" + device.getName());
}
}
}
二、蓝牙权限
1、申请权限
静态注册:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
动态申请定位权限:
String[] p = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
ActivityCompat.requestPermissions(activity,p,1000);
如果您的目标是 Android 10,那么您需要 ACCESS_FINE_LOCATION 来扫描。ACCESS_COARSE_LOCATION 在 Android 10 中不再起作用。
2、打开手机定位
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
MainActivity a = (MainActivity) activity;
a.startActivityForResult(intent, OPEN_GPS_CODE)
注意:蓝牙的搜索、配对等等需要开启权限,否则啥也获取不到。
三、蓝牙搜索、获取蓝牙地址、信号强度、UUID等
1、注册蓝牙广播
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
activity.registerReceiver(bluetoothReceiver, filter);
2、开始搜索
if (bluetoothAdapter.isDiscovering()) {
//搜索蓝牙设备
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
这一步非常耗性能和时间,需要在子线程进行。
3、监听广播
private List<BluetoothDevice> deviceList = new ArrayList<>();
public BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
LogUtils.d("开始搜索");
break;
case BluetoothDevice.ACTION_FOUND:
LogUtils.d("搜索中……");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, (short) 0);
if (!TextUtils.isEmpty(device.getName())) {
String str = device.getName() + "|" + device.getAddress() + "|" + rssi;
LogUtils.d("搜索到的蓝牙信息名称、地址、信号强度:" + str);
if (!deviceList.contains(device)) {
//过滤掉没有名称的重复的内容
deviceList.add(device);
}
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
LogUtils.d("搜索结束");
for (int i = 0; i < deviceList.size(); i++) {
BluetoothDevice bluetoothDevice = deviceList.get(i);
//这块触发了BluetoothDevice.ACTION_UUID,以便于获取到UUID
bluetoothDevice.fetchUuidsWithSdp();
LogUtils.d(bluetoothDevice.getName() + " | " + bluetoothDevice.getAddress());
}
break;
case BluetoothDevice.ACTION_UUID:
LogUtils.d("触发UUID");
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuid = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
try {
//反射获取本地名称
Method method = bluetoothDevice.getClass().getMethod("getAlias");
if (method != null) {
String localName = (String) method.invoke(bluetoothDevice);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (uuid != null) {
for (Parcelable ep : uuid) {
LogUtils.d("UUID :" + ep.toString());
}
} else {
LogUtils.d("UUID : null");
}
break;
}
}
};
4、停止搜索
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
activity.unregisterReceiver(bluetoothReceiver);
注意:搜索结束之后需要停止搜索,否则非常耗电,还浪费性能。
三、蓝牙自动配对
1、获取需要配对的蓝牙设备和pin码
String deviceId = data.deviceId;
String pin = data.pin;
deviceId:需要配对的设备。
pin:设置的配对码。
2、开始配对
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
BluetoothDevice remoteDevice = bluetoothAdapter.getRemoteDevice(deviceId);
if (remoteDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
//已经配对了
LogUtils.d("已经配对了");
} else {
//没有配对
//监听配对状态
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); //配对状态监听
intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST); //配对请求
makeBluetoothPairReceiver = new MakeBluetoothPairReceiver();
activity.registerReceiver(makeBluetoothPairReceiver, intentFilter);
//开始配对
remoteDevice.setPin(pinByte);
remoteDevice.createBond();
}
public class MakeBluetoothPairReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (TextUtils.equals(action, BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int bondSate = bluetoothDevice.getBondState();
switch (bondSate) {
case BluetoothDevice.BOND_NONE:
LogUtils.d("已解除配对");
unMakeBluetoothPairReceiver();
break;
case BluetoothDevice.BOND_BONDING:
LogUtils.d("正在配对...");
break;
case BluetoothDevice.BOND_BONDED:
LogUtils.d("配对成功");
unMakeBluetoothPairReceiver();
break;
}
} else if (TextUtils.equals(action, BluetoothDevice.ACTION_PAIRING_REQUEST)) {
int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
LogUtils.d("ACTION_PAIRING_REQUEST:" + type);
// abortBroadcast();该方法使配对失败,先不用了
}
}
}
public void unMakeBluetoothPairReceiver() {
if (makeBluetoothPairReceiver != null) {
activity.unregisterReceiver(makeBluetoothPairReceiver);
}
}
四、获取已经连接的蓝牙信息
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
JsCreateDevicesBean jsCreateDevicesBean = new JsCreateDevicesBean();
if (pairedDevices.size() > 0) {
List<JsCreateDevicesBean.DeviceData> list = jsCreateDevicesBean.devices;
for (BluetoothDevice device : pairedDevices) {
JsCreateDevicesBean.DeviceData deviceData = new JsCreateDevicesBean.DeviceData();
deviceData.deviceId = device.getAddress();
deviceData.name = device.getName();
LogUtils.d("BlueTooth已配对的设备:" + device.getAddress() + "----" + device.getName() + "----" + device.getUuids().toString());
}
}