Browse Source

实现获取蓝牙列表接口,还需完善

master
白凤吉 4 months ago
parent
commit
87bc73ac9f
  1. 27
      app/src/main/java/com/iflytop/profilometer/api/ble/BleApi.java
  2. 5
      app/src/main/java/com/iflytop/profilometer/api/ble/BleRoutes.kt
  3. 82
      app/src/main/java/com/iflytop/profilometer/core/bluetooth/BleManager.java

27
app/src/main/java/com/iflytop/profilometer/api/ble/BleApi.java

@ -1,10 +1,8 @@
package com.iflytop.profilometer.api.ble;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import com.iflytop.profilometer.ProfilometerApplication;
import com.iflytop.profilometer.common.result.Result;
import com.iflytop.profilometer.core.bluetooth.BleManager;
@ -47,5 +45,30 @@ public class BleApi {
}
}
/**
* 链接蓝牙设备
*/
public String connect(String mac) {
try {
BleManager.getInstance(context).connectToDevice(mac);
return Result.success();
} catch (Exception e) {
Log.e(TAG, "链接蓝牙设备失败", e);
return Result.failed("链接蓝牙设备失败");
}
}
/**
* 断开链接蓝牙设备
*/
public String disconnect() {
try {
BleManager.getInstance(context).disconnect();
return Result.success();
} catch (Exception e) {
Log.e(TAG, "断开蓝牙设备链接失败", e);
return Result.failed("断开蓝牙设备链接失败");
}
}
}

5
app/src/main/java/com/iflytop/profilometer/api/ble/BleRoutes.kt

@ -31,12 +31,17 @@ fun Routing.bleRoutes(context: Context) {
*
*/
post("/api/ble/connect") {
val params = call.receive<Map<String, String>>()
val jsonResponse = api.connect(params["mac"])
call.respondText(jsonResponse, ContentType.Application.Json)
}
/**
*
*/
post("/api/ble/disconnect") {
val jsonResponse = api.disconnect()
call.respondText(jsonResponse, ContentType.Application.Json)
}
}

82
app/src/main/java/com/iflytop/profilometer/core/bluetooth/BleManager.java

@ -26,7 +26,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* BleManager 用于管理蓝牙相关的功能包括权限检查扫描设备和连接设备
* BleManager 用于管理蓝牙相关的功能包括权限检查扫描设备连接和断开设备
* 本类采用单例模式确保整个应用中只有一个实例
*/
public class BleManager {
@ -35,27 +35,21 @@ public class BleManager {
// 单例实例
private static BleManager instance;
// Android 系统蓝牙管理器
private final BluetoothManager bluetoothManager;
// 蓝牙适配器
private BluetoothAdapter bluetoothAdapter;
// 蓝牙低功耗扫描器
private BluetoothLeScanner bluetoothLeScanner;
// 保存扫描到的蓝牙设备列表
private final List<BluetoothDevice> scannedDevices = new ArrayList<>();
// 扫描回调对象
private ScanCallback scanCallback;
// 蓝牙连接操作返回的 BluetoothGatt 对象
private BluetoothGatt bluetoothGatt;
// 应用上下文使用 ApplicationContext 防止内存泄露
private final Context context;
/**
* 私有构造函数防止外部直接实例化
*
* @param context 上下文
*/
private BleManager(Context context) {
// 使用 ApplicationContext 避免内存泄露
// 使用 ApplicationContext 防止内存泄露
this.context = context.getApplicationContext();
bluetoothManager = (BluetoothManager) this.context.getSystemService(Context.BLUETOOTH_SERVICE);
if (bluetoothManager != null) {
@ -64,7 +58,8 @@ public class BleManager {
}
/**
* 获取单例实例确保整个应用中只有一个 BleManager 对象
* 获取单例实例确保全局只有一个 BleManager 对象
*
* @param context 上下文
* @return 单例 BleManager 实例
*/
@ -77,7 +72,8 @@ public class BleManager {
/**
* 辅助方法检查指定权限是否已被授予
* @param permission 权限名称例如 Manifest.permission.BLUETOOTH_SCAN
*
* @param permission 权限名称
* @return true 表示已授予false 表示未授予
*/
private boolean hasPermission(String permission) {
@ -85,9 +81,8 @@ public class BleManager {
}
/**
* 检查并请求必要的权限例如位置权限BLUETOOTH_SCANBLUETOOTH_CONNECT
* 该方法需要在 Activity 中调用并在 onRequestPermissionsResult 中处理回调
* 需要 API 31Android S及以上版本
* 检查并请求必要权限例如位置BLUETOOTH_SCANBLUETOOTH_CONNECT
* 此方法需要在 Activity 中调用并在 onRequestPermissionsResult 中处理回调
*
* @param activity 当前 Activity
*/
@ -110,7 +105,7 @@ public class BleManager {
/**
* 提示用户蓝牙未开启
* 注意此方法不自动开启蓝牙而是直接通过 Toast 提示用户蓝牙未开启请先开启蓝牙
* 如果蓝牙未开启直接通过 Toast 提示用户蓝牙未开启请先开启蓝牙
*
* @param activity 当前 Activity
*/
@ -122,13 +117,15 @@ public class BleManager {
if (bluetoothAdapter.isEnabled()) {
return;
}
// 直接提示用户蓝牙未开启无需弹出对话框要求开启
// 提示用户蓝牙未开启
Toast.makeText(activity, "蓝牙未开启,请先开启蓝牙", Toast.LENGTH_LONG).show();
// 可选这里不再调用自动开启逻辑而是等待用户手动开启蓝牙
// startScan() 内部也会检查蓝牙状态
}
/**
* 开始扫描 BLE 设备扫描结果保存到 scannedDevices 列表中
* 需要确保蓝牙已开启且 BLUETOOTH_SCAN 权限已授予
* 开始扫描 BLE 设备扫描结果保存到 scannedDevices 列表中
* 需要确保蓝牙已开启且 BLUETOOTH_SCAN 权限已授予
*/
@SuppressLint("MissingPermission")
public void startScan() {
@ -145,14 +142,12 @@ public class BleManager {
Log.e(TAG, "获取 BluetoothLeScanner 失败");
return;
}
// 清空上一次扫描结果
// 清空上一次扫描结果
scannedDevices.clear();
// 定义扫描回调
scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
// 添加新设备到列表中避免重复
if (device != null && !scannedDevices.contains(device)) {
scannedDevices.add(device);
Log.d(TAG, "发现设备: " + device.getName() + " - " + device.getAddress());
@ -175,13 +170,12 @@ public class BleManager {
Log.e(TAG, "BLE 扫描失败,错误码:" + errorCode);
}
};
// 开始扫描
bluetoothLeScanner.startScan(scanCallback);
}
/**
* 停止 BLE 设备扫描
* 需要确保 BLUETOOTH_SCAN 权限已被授予
* 需要确保蓝牙已开启且具有 BLUETOOTH_SCAN 权限
*/
@SuppressLint("MissingPermission")
public void stopScan() {
@ -200,19 +194,17 @@ public class BleManager {
/**
* 返回当前扫描到的设备列表
* 直接返回内部保存的 List<BluetoothDevice> 对象
*
* @return 蓝牙设备列表
* @return List<BluetoothDevice> 扫描到的蓝牙设备列表
*/
public List<BluetoothDevice> getScannedDevices() {
return scannedDevices;
}
/**
* 判断是否已经有设备建立了蓝牙连接
* 这里通过 BluetoothGatt 是否为 null 进行简单判断
* 判断是否已有设备建立了蓝牙连接简单判断 BluetoothGatt 是否非空
*
* @return 如果已有设备连接返回 true否则返回 false
* @return true 表示已有设备连接否则返回 false
*/
public boolean isConnected() {
return bluetoothGatt != null;
@ -220,9 +212,10 @@ public class BleManager {
/**
* 尝试连接指定的 BLE 设备
* 传入设备的 MAC 地址通过 bluetoothAdapter.getRemoteDevice() 获取 BluetoothDevice 对象再调用 connectGatt 进行连接
* 如果当前已连接的设备和传入的 MAC 地址相同则不做任何操作
* 如果当前已连接其他设备则先断开当前连接再连接新设备
*
* @param macAddress 设备的 MAC 地址字符串
* @param macAddress 目标设备的 MAC 地址字符串
*/
@SuppressLint("MissingPermission")
public void connectToDevice(String macAddress) {
@ -234,10 +227,22 @@ public class BleManager {
Log.e(TAG, "BLUETOOTH_CONNECT 权限未授予");
return;
}
// 如果当前已有设备连接
if (bluetoothGatt != null) {
BluetoothDevice connectedDevice = bluetoothGatt.getDevice();
if (connectedDevice != null && connectedDevice.getAddress().equals(macAddress)) {
// 如果新连接的设备与当前已连接设备相同则不做任何操作
Log.d(TAG, "设备已连接,无需重复连接: " + connectedDevice.getName());
return;
} else {
// 否则断开当前连接
disconnect();
}
}
try {
// 根据 MAC 地址获取 BluetoothDevice 对象
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(macAddress);
// 建立蓝牙连接connectGatt 为异步操作
// 建立蓝牙连接异步操作
bluetoothGatt = device.connectGatt(context, false, new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
@ -253,4 +258,19 @@ public class BleManager {
Log.e(TAG, "无效的 MAC 地址: " + macAddress, e);
}
}
/**
* 断开当前已连接的蓝牙设备
* 如果当前有连接的设备则调用 disconnect() close() 方法断开连接
* 并将内部的 bluetoothGatt 置为 null
*/
@SuppressLint("MissingPermission")
public void disconnect() {
if (bluetoothGatt != null) {
bluetoothGatt.disconnect();
bluetoothGatt.close();
bluetoothGatt = null;
Log.d(TAG, "当前蓝牙设备已断开连接");
}
}
}
Loading…
Cancel
Save