|
|
@@ -0,0 +1,573 @@
|
|
|
+package com.vber.chicken_farm.bluetooth.core;
|
|
|
+
|
|
|
+import android.app.Service;
|
|
|
+import android.bluetooth.BluetoothAdapter;
|
|
|
+import android.bluetooth.BluetoothDevice;
|
|
|
+import android.bluetooth.BluetoothManager;
|
|
|
+import android.bluetooth.BluetoothSocket;
|
|
|
+import android.bluetooth.le.BluetoothLeScanner;
|
|
|
+import android.bluetooth.le.ScanCallback;
|
|
|
+import android.bluetooth.le.ScanResult;
|
|
|
+import android.bluetooth.le.ScanSettings;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.Intent;
|
|
|
+import android.content.pm.PackageManager;
|
|
|
+import android.os.Binder;
|
|
|
+import android.os.Handler;
|
|
|
+import android.os.IBinder;
|
|
|
+import android.os.Looper;
|
|
|
+import android.util.Log;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.OutputStream;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.UUID;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 通用蓝牙串口通信服务
|
|
|
+ * 支持多设备类型复用 + 蓝牙扫描功能
|
|
|
+ */
|
|
|
+public class BluetoothSerialService extends Service {
|
|
|
+ private static final String TAG = "BluetoothSerialService";
|
|
|
+ private final IBinder binder = new BluetoothSerialBinder();
|
|
|
+ private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
|
|
+ private BluetoothAdapter bluetoothAdapter;
|
|
|
+ private BluetoothLeScanner bluetoothLeScanner;
|
|
|
+
|
|
|
+ // 设备连接池:key=设备类型,value=设备连接信息
|
|
|
+ private final ConcurrentHashMap<String, DeviceConnection> deviceConnectionMap = new ConcurrentHashMap<>();
|
|
|
+
|
|
|
+ // 扫描相关
|
|
|
+ private int scanState = BluetoothConstants.SCAN_STATE_IDLE;
|
|
|
+ private final List<BluetoothDeviceInfo> discoveredDevices = new ArrayList<>();
|
|
|
+ private Handler scanTimeoutHandler;
|
|
|
+ private BluetoothDeviceCallback globalCallback; // 扫描回调使用全局回调
|
|
|
+
|
|
|
+ // 绑定器
|
|
|
+ public class BluetoothSerialBinder extends Binder {
|
|
|
+ public BluetoothSerialService getService() {
|
|
|
+ return BluetoothSerialService.this;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设备连接信息封装
|
|
|
+ */
|
|
|
+ private static class DeviceConnection {
|
|
|
+ BluetoothSocket socket;
|
|
|
+ InputStream inputStream;
|
|
|
+ OutputStream outputStream;
|
|
|
+ ReadThread readThread;
|
|
|
+ int connectionState = BluetoothConstants.STATE_DISCONNECTED;
|
|
|
+ BluetoothDeviceCallback callback;
|
|
|
+ String deviceAddress;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCreate() {
|
|
|
+ super.onCreate();
|
|
|
+ Log.d(TAG, "通用蓝牙串口服务创建");
|
|
|
+ // 初始化蓝牙适配器
|
|
|
+ BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
|
|
|
+ if (bluetoothManager != null) {
|
|
|
+ bluetoothAdapter = bluetoothManager.getAdapter();
|
|
|
+ }
|
|
|
+ // 初始化BLE扫描器
|
|
|
+ if (bluetoothAdapter != null) {
|
|
|
+ bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IBinder onBind(Intent intent) {
|
|
|
+ return binder;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------- 扫描相关核心方法 ---------------------
|
|
|
+ /**
|
|
|
+ * 设置全局回调(用于扫描)
|
|
|
+ */
|
|
|
+ public void setGlobalCallback(BluetoothDeviceCallback callback) {
|
|
|
+ this.globalCallback = callback;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开始扫描蓝牙设备
|
|
|
+ * @param scanDuration 扫描时长(毫秒),0表示一直扫描
|
|
|
+ */
|
|
|
+ public void startScan(long scanDuration) {
|
|
|
+ // 1. 校验蓝牙支持
|
|
|
+ if (bluetoothAdapter == null) {
|
|
|
+ notifyScanError(BluetoothConstants.ERROR_BLUETOOTH_NOT_SUPPORT, "设备不支持蓝牙");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 校验蓝牙是否开启
|
|
|
+ if (!bluetoothAdapter.isEnabled()) {
|
|
|
+ notifyScanError(BluetoothConstants.ERROR_BLUETOOTH_DISABLED, "蓝牙未开启,请先开启蓝牙");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 校验扫描权限
|
|
|
+ if (checkSelfPermission(android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
|
|
|
+ notifyScanError(BluetoothConstants.ERROR_SCAN_PERMISSION_DENIED, "缺少蓝牙扫描权限");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 校验扫描状态
|
|
|
+ if (scanState == BluetoothConstants.SCAN_STATE_SCANNING) {
|
|
|
+ Log.w(TAG, "蓝牙扫描已在进行中");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 初始化扫描
|
|
|
+ scanState = BluetoothConstants.SCAN_STATE_SCANNING;
|
|
|
+ discoveredDevices.clear();
|
|
|
+ notifyScanStateChanged(BluetoothConstants.SCAN_STATE_SCANNING);
|
|
|
+ Log.d(TAG, "开始蓝牙扫描,时长:" + scanDuration + "ms");
|
|
|
+
|
|
|
+ // 6. 先获取已配对设备
|
|
|
+ getPairedDevices();
|
|
|
+
|
|
|
+ // 7. 启动BLE扫描(兼容传统蓝牙)
|
|
|
+ ScanSettings scanSettings = new ScanSettings.Builder()
|
|
|
+ .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ if (bluetoothLeScanner != null) {
|
|
|
+ bluetoothLeScanner.startScan(null, scanSettings, scanCallback);
|
|
|
+ } else {
|
|
|
+ // 兼容传统蓝牙扫描(API < 21)
|
|
|
+ bluetoothAdapter.startDiscovery();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 8. 设置扫描超时
|
|
|
+ if (scanDuration > 0) {
|
|
|
+ if (scanTimeoutHandler == null) {
|
|
|
+ scanTimeoutHandler = new Handler(Looper.getMainLooper());
|
|
|
+ }
|
|
|
+ scanTimeoutHandler.postDelayed(this::stopScan, scanDuration);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 停止蓝牙扫描
|
|
|
+ */
|
|
|
+ public void stopScan() {
|
|
|
+ if (scanState != BluetoothConstants.SCAN_STATE_SCANNING) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 停止扫描
|
|
|
+ if (bluetoothLeScanner != null) {
|
|
|
+ bluetoothLeScanner.stopScan(scanCallback);
|
|
|
+ } else {
|
|
|
+ bluetoothAdapter.cancelDiscovery();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 取消超时
|
|
|
+ if (scanTimeoutHandler != null) {
|
|
|
+ scanTimeoutHandler.removeCallbacksAndMessages(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新状态
|
|
|
+ scanState = BluetoothConstants.SCAN_STATE_STOPPED;
|
|
|
+ notifyScanStateChanged(BluetoothConstants.SCAN_STATE_STOPPED);
|
|
|
+ notifyScanCompleted();
|
|
|
+ Log.d(TAG, "蓝牙扫描已停止,发现设备数:" + discoveredDevices.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取已配对的蓝牙设备
|
|
|
+ */
|
|
|
+ private void getPairedDevices() {
|
|
|
+ if (bluetoothAdapter == null) return;
|
|
|
+
|
|
|
+ for (BluetoothDevice device : bluetoothAdapter.getBondedDevices()) {
|
|
|
+ BluetoothDeviceInfo deviceInfo = new BluetoothDeviceInfo(
|
|
|
+ device.getName(),
|
|
|
+ device.getAddress(),
|
|
|
+ 0,
|
|
|
+ true
|
|
|
+ );
|
|
|
+ addDiscoveredDevice(deviceInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加发现的设备
|
|
|
+ */
|
|
|
+ private void addDiscoveredDevice(BluetoothDeviceInfo deviceInfo) {
|
|
|
+ // 按MAC地址去重
|
|
|
+ for (BluetoothDeviceInfo info : discoveredDevices) {
|
|
|
+ if (info.getAddress().equals(deviceInfo.getAddress())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ discoveredDevices.add(deviceInfo);
|
|
|
+ // 通知发现设备
|
|
|
+ if (globalCallback != null) {
|
|
|
+ mainHandler.post(() -> globalCallback.onDeviceDiscovered(deviceInfo));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * BLE扫描回调
|
|
|
+ */
|
|
|
+ private final ScanCallback scanCallback = new ScanCallback() {
|
|
|
+ @Override
|
|
|
+ public void onScanResult(int callbackType, ScanResult result) {
|
|
|
+ super.onScanResult(callbackType, result);
|
|
|
+ if (result == null || result.getDevice() == null) return;
|
|
|
+
|
|
|
+ BluetoothDevice device = result.getDevice();
|
|
|
+ BluetoothDeviceInfo deviceInfo = new BluetoothDeviceInfo(
|
|
|
+ device.getName(),
|
|
|
+ device.getAddress(),
|
|
|
+ result.getRssi(),
|
|
|
+ device.getBondState() == BluetoothDevice.BOND_BONDED
|
|
|
+ );
|
|
|
+ addDiscoveredDevice(deviceInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onScanFailed(int errorCode) {
|
|
|
+ super.onScanFailed(errorCode);
|
|
|
+ String errorMsg = "扫描失败,错误码:" + errorCode;
|
|
|
+ Log.e(TAG, errorMsg);
|
|
|
+ notifyScanError(BluetoothConstants.ERROR_SCAN_FAILED, errorMsg);
|
|
|
+ stopScan();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通知扫描状态变化
|
|
|
+ */
|
|
|
+ private void notifyScanStateChanged(int state) {
|
|
|
+ if (globalCallback != null) {
|
|
|
+ mainHandler.post(() -> globalCallback.onScanStateChanged(state));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通知扫描完成
|
|
|
+ */
|
|
|
+ private void notifyScanCompleted() {
|
|
|
+ if (globalCallback != null) {
|
|
|
+ mainHandler.post(() -> globalCallback.onScanCompleted(new ArrayList<>(discoveredDevices)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通知扫描错误
|
|
|
+ */
|
|
|
+ private void notifyScanError(String errorCode, String errorMsg) {
|
|
|
+ if (globalCallback != null) {
|
|
|
+ mainHandler.post(() -> globalCallback.onError("", errorCode, errorMsg));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------- 设备连接相关方法 ---------------------
|
|
|
+ /**
|
|
|
+ * 初始化设备连接(首次连接前调用)
|
|
|
+ * @param deviceType 设备类型
|
|
|
+ * @param callback 回调接口
|
|
|
+ */
|
|
|
+ public void initDeviceConnection(String deviceType, BluetoothDeviceCallback callback) {
|
|
|
+ if (!deviceConnectionMap.containsKey(deviceType)) {
|
|
|
+ DeviceConnection connection = new DeviceConnection();
|
|
|
+ connection.callback = callback;
|
|
|
+ deviceConnectionMap.put(deviceType, connection);
|
|
|
+ Log.d(TAG, "初始化设备连接: " + deviceType);
|
|
|
+ } else {
|
|
|
+ deviceConnectionMap.get(deviceType).callback = callback;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 连接指定类型的蓝牙设备
|
|
|
+ * @param deviceType 设备类型
|
|
|
+ * @param deviceAddress MAC地址
|
|
|
+ */
|
|
|
+ public void connect(String deviceType, String deviceAddress) {
|
|
|
+ // 校验蓝牙适配器
|
|
|
+ if (bluetoothAdapter == null) {
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_BLUETOOTH_NOT_SUPPORT, "设备不支持蓝牙");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验设备连接
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection == null) {
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_DEVICE_NOT_FOUND, "设备连接未初始化");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验重复连接
|
|
|
+ if (connection.connectionState == BluetoothConstants.STATE_CONNECTING) {
|
|
|
+ Log.w(TAG, deviceType + " 正在连接中,请勿重复调用");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新状态
|
|
|
+ connection.deviceAddress = deviceAddress;
|
|
|
+ updateConnectionState(deviceType, BluetoothConstants.STATE_CONNECTING);
|
|
|
+
|
|
|
+ // 启动连接线程
|
|
|
+ new ConnectThread(deviceType, deviceAddress).start();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 断开指定类型设备的连接
|
|
|
+ * @param deviceType 设备类型
|
|
|
+ */
|
|
|
+ public void disconnect(String deviceType) {
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection == null || connection.connectionState == BluetoothConstants.STATE_DISCONNECTED) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 停止读取线程
|
|
|
+ if (connection.readThread != null) {
|
|
|
+ connection.readThread.interrupt();
|
|
|
+ connection.readThread = null;
|
|
|
+ }
|
|
|
+ // 关闭socket
|
|
|
+ if (connection.socket != null) {
|
|
|
+ connection.socket.close();
|
|
|
+ connection.socket = null;
|
|
|
+ }
|
|
|
+ // 清空流
|
|
|
+ connection.inputStream = null;
|
|
|
+ connection.outputStream = null;
|
|
|
+ // 更新状态
|
|
|
+ updateConnectionState(deviceType, BluetoothConstants.STATE_DISCONNECTED);
|
|
|
+ Log.d(TAG, deviceType + " 蓝牙连接已断开");
|
|
|
+ } catch (IOException e) {
|
|
|
+ Log.e(TAG, deviceType + " 断开连接失败", e);
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_DISCONNECT_FAILED, "断开连接失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送数据到指定设备
|
|
|
+ * @param deviceType 设备类型
|
|
|
+ * @param data 字节数据
|
|
|
+ * @return 是否发送成功
|
|
|
+ */
|
|
|
+ public boolean sendData(String deviceType, byte[] data) {
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection == null || connection.connectionState != BluetoothConstants.STATE_CONNECTED || connection.outputStream == null) {
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_SEND_DATA_FAILED, "设备未连接,发送失败");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ connection.outputStream.write(data);
|
|
|
+ connection.outputStream.flush();
|
|
|
+ Log.d(TAG, deviceType + " 发送数据长度: " + data.length);
|
|
|
+ return true;
|
|
|
+ } catch (IOException e) {
|
|
|
+ Log.e(TAG, deviceType + " 发送数据失败", e);
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_SEND_DATA_FAILED, "发送数据失败: " + e.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定设备的连接状态
|
|
|
+ * @param deviceType 设备类型
|
|
|
+ * @return 连接状态
|
|
|
+ */
|
|
|
+ public int getConnectionState(String deviceType) {
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ return connection != null ? connection.connectionState : BluetoothConstants.STATE_DISCONNECTED;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查指定设备是否已连接
|
|
|
+ * @param deviceType 设备类型
|
|
|
+ * @return 是否连接
|
|
|
+ */
|
|
|
+ public boolean isConnected(String deviceType) {
|
|
|
+ return getConnectionState(deviceType) == BluetoothConstants.STATE_CONNECTED;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 释放指定设备的连接资源
|
|
|
+ * @param deviceType 设备类型
|
|
|
+ */
|
|
|
+ public void releaseDeviceConnection(String deviceType) {
|
|
|
+ disconnect(deviceType);
|
|
|
+ deviceConnectionMap.remove(deviceType);
|
|
|
+ Log.d(TAG, "释放设备连接: " + deviceType);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 释放所有设备连接资源
|
|
|
+ */
|
|
|
+ public void releaseAllConnections() {
|
|
|
+ for (String deviceType : deviceConnectionMap.keySet()) {
|
|
|
+ disconnect(deviceType);
|
|
|
+ }
|
|
|
+ deviceConnectionMap.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------- 私有工具方法 ---------------------
|
|
|
+ /**
|
|
|
+ * 获取设备连接信息
|
|
|
+ */
|
|
|
+ private DeviceConnection getDeviceConnection(String deviceType) {
|
|
|
+ return deviceConnectionMap.get(deviceType);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新连接状态并回调
|
|
|
+ */
|
|
|
+ private void updateConnectionState(String deviceType, int state) {
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection != null) {
|
|
|
+ connection.connectionState = state;
|
|
|
+ mainHandler.post(() -> {
|
|
|
+ if (connection.callback != null) {
|
|
|
+ connection.callback.onConnectionStateChanged(deviceType, state);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通知错误信息
|
|
|
+ */
|
|
|
+ private void notifyError(String deviceType, String errorCode, String errorMsg) {
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection != null && connection.callback != null) {
|
|
|
+ mainHandler.post(() -> connection.callback.onError(deviceType, errorCode, errorMsg));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------- 内部线程类 ---------------------
|
|
|
+ /**
|
|
|
+ * 连接线程
|
|
|
+ */
|
|
|
+ private class ConnectThread extends Thread {
|
|
|
+ private final String deviceType;
|
|
|
+ private final String deviceAddress;
|
|
|
+
|
|
|
+ public ConnectThread(String deviceType, String deviceAddress) {
|
|
|
+ this.deviceType = deviceType;
|
|
|
+ this.deviceAddress = deviceAddress;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(deviceAddress);
|
|
|
+ if (bluetoothDevice == null) {
|
|
|
+ mainHandler.post(() -> {
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_DEVICE_NOT_FOUND, "未找到蓝牙设备: " + deviceAddress);
|
|
|
+ updateConnectionState(deviceType, BluetoothConstants.STATE_DISCONNECTED);
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 创建串口Socket
|
|
|
+ UUID uuid = UUID.fromString(BluetoothConstants.UUID_SERIAL_PORT);
|
|
|
+ BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
|
|
|
+
|
|
|
+ // 关闭蓝牙发现(提升连接速度)
|
|
|
+ if (bluetoothAdapter.isDiscovering()) {
|
|
|
+ bluetoothAdapter.cancelDiscovery();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 连接设备
|
|
|
+ socket.connect();
|
|
|
+
|
|
|
+ // 更新连接信息
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection != null) {
|
|
|
+ connection.socket = socket;
|
|
|
+ connection.inputStream = socket.getInputStream();
|
|
|
+ connection.outputStream = socket.getOutputStream();
|
|
|
+
|
|
|
+ // 启动读取线程
|
|
|
+ connection.readThread = new ReadThread(deviceType);
|
|
|
+ connection.readThread.start();
|
|
|
+
|
|
|
+ // 更新连接状态
|
|
|
+ updateConnectionState(deviceType, BluetoothConstants.STATE_CONNECTED);
|
|
|
+ Log.d(TAG, deviceType + " 连接成功: " + deviceAddress);
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ Log.e(TAG, deviceType + " 连接失败", e);
|
|
|
+ mainHandler.post(() -> {
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_CONNECTION_FAILED, "连接失败: " + e.getMessage());
|
|
|
+ updateConnectionState(deviceType, BluetoothConstants.STATE_DISCONNECTED);
|
|
|
+ });
|
|
|
+ // 关闭失败的socket
|
|
|
+ try {
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection != null && connection.socket != null) {
|
|
|
+ connection.socket.close();
|
|
|
+ }
|
|
|
+ } catch (IOException closeException) {
|
|
|
+ Log.e(TAG, deviceType + " 关闭Socket失败", closeException);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数据读取线程
|
|
|
+ */
|
|
|
+ private class ReadThread extends Thread {
|
|
|
+ private final String deviceType;
|
|
|
+ private final byte[] buffer = new byte[1024];
|
|
|
+
|
|
|
+ public ReadThread(String deviceType) {
|
|
|
+ this.deviceType = deviceType;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ DeviceConnection connection = getDeviceConnection(deviceType);
|
|
|
+ if (connection == null) return;
|
|
|
+
|
|
|
+ while (!isInterrupted()) {
|
|
|
+ try {
|
|
|
+ if (connection.inputStream == null) break;
|
|
|
+
|
|
|
+ int bytes = connection.inputStream.read(buffer);
|
|
|
+ if (bytes > 0) {
|
|
|
+ byte[] data = new byte[bytes];
|
|
|
+ System.arraycopy(buffer, 0, data, 0, bytes);
|
|
|
+
|
|
|
+ // 1. 通知原始数据
|
|
|
+ if (connection.callback != null) {
|
|
|
+ mainHandler.post(() -> connection.callback.onRawDataReceived(deviceType, data));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ Log.e(TAG, deviceType + " 读取数据失败", e);
|
|
|
+ mainHandler.post(() -> {
|
|
|
+ notifyError(deviceType, BluetoothConstants.ERROR_READ_DATA_FAILED, "读取数据失败: " + e.getMessage());
|
|
|
+ disconnect(deviceType);
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDestroy() {
|
|
|
+ stopScan(); // 销毁时停止扫描
|
|
|
+ releaseAllConnections();
|
|
|
+ Log.d(TAG, "通用蓝牙串口服务销毁");
|
|
|
+ super.onDestroy();
|
|
|
+ }
|
|
|
+}
|