BluetoothUtils.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package com.mes.util;
  2. import com.mes.ui.MesClient;
  3. import javax.bluetooth.*;
  4. import javax.microedition.io.Connector;
  5. import javax.microedition.io.StreamConnection;
  6. import java.io.*;
  7. public class BluetoothUtils {
  8. // 目标设备地址 二线:001135390238 k3:00113538028A 一线:001135390246
  9. private static final String TARGET_DEVICE_ADDRESS = "001135390238";
  10. // 标志位
  11. private static volatile boolean isRunning = true;
  12. // 【关键修改】将连接对象和流对象提升为静态变量,保持持久化
  13. private static StreamConnection connection;
  14. private static InputStream is;
  15. private static BufferedReader reader;
  16. public static void init() {
  17. try {
  18. LocalDevice localDevice = LocalDevice.getLocalDevice();
  19. System.out.println("本地蓝牙名称: " + localDevice.getFriendlyName());
  20. System.out.println("将尝试连接到设备地址: " + TARGET_DEVICE_ADDRESS);
  21. String btsppUrl = "btspp://" + TARGET_DEVICE_ADDRESS + ":1;authenticate=false;encrypt=false;master=false";
  22. // 在新线程中连接,避免阻塞
  23. new Thread(() -> {
  24. try {
  25. // 如果已经连接,先跳过
  26. if (connection != null && MesClient.com_connect_flag) {
  27. return;
  28. }
  29. System.out.println("尝试建立蓝牙连接...");
  30. // 建立连接
  31. connection = (StreamConnection) Connector.open(btsppUrl);
  32. // 【关键修改】连接成功后立即初始化流,并保持打开状态
  33. if (connection != null) {
  34. is = connection.openInputStream();
  35. reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
  36. MesClient.com_connect_flag = true;
  37. System.out.println("蓝牙连接成功,输入流已就绪");
  38. }
  39. } catch (IOException e) {
  40. System.err.println("蓝牙连接失败: " + e.getMessage());
  41. closeConnection(); // 连接失败清理资源
  42. }
  43. }).start();
  44. } catch (BluetoothStateException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. /**
  49. * 接收数据并解析重量 (复用已有的连接和流)
  50. */
  51. public static String connectAndReceiveData() {
  52. // 1. 检查连接状态
  53. if (connection == null || reader == null || !MesClient.com_connect_flag) {
  54. System.err.println("错误: 蓝牙未连接");
  55. return "未连接";
  56. }
  57. try {
  58. long startTime = System.currentTimeMillis();
  59. long timeout = 2000; // 3秒超时
  60. // 清空缓冲区旧数据(可选,视称重仪表特性而定)
  61. while (reader.ready()) { reader.readLine(); }
  62. System.out.println("开始读取重量数据...");
  63. // 2. 循环读取直到超时或获取到数据
  64. while ((System.currentTimeMillis() - startTime < timeout)) {
  65. // 使用 ready() 避免 readLine() 在没有数据时无限阻塞
  66. if (reader.ready()) {
  67. String data = reader.readLine();
  68. if (data != null) {
  69. System.out.println("收到数据: " + data);
  70. String wet = extractWeight(data);
  71. if (wet != null && !wet.equals("")) {
  72. return wet;
  73. }
  74. }
  75. } else {
  76. // 没有数据时短暂休眠
  77. Thread.sleep(100);
  78. }
  79. }
  80. System.out.println("读取超时");
  81. return "超时";
  82. } catch (IOException | InterruptedException e) {
  83. System.err.println("读取数据异常: " + e.getMessage());
  84. // 【关键修改】只有在发生真实IO异常时才关闭连接,触发重连
  85. closeConnection();
  86. return "异常";
  87. }
  88. // 【关键修改】这里去掉了 finally { close() },确保连接不被切断
  89. }
  90. /**
  91. * 关闭蓝牙连接并重置资源
  92. */
  93. public static void closeConnection() {
  94. isRunning = false;
  95. MesClient.com_connect_flag = false;
  96. try {
  97. if (reader != null) {
  98. reader.close();
  99. reader = null;
  100. }
  101. if (is != null) {
  102. is.close();
  103. is = null;
  104. }
  105. if (connection != null) {
  106. connection.close();
  107. connection = null;
  108. }
  109. System.out.println("蓝牙资源已释放");
  110. } catch (IOException e) {
  111. e.printStackTrace();
  112. }
  113. }
  114. // 解析重量
  115. public static String extractWeight(String input) {
  116. if (input == null) return null;
  117. java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("\\d+(?:\\.\\d+)?\\s*kg", java.util.regex.Pattern.CASE_INSENSITIVE);
  118. java.util.regex.Matcher matcher = pattern.matcher(input);
  119. if (matcher.find()) {
  120. return matcher.group().trim();
  121. }
  122. // 如果没有kg单位,尝试直接提取数字(视仪表格式调整)
  123. try {
  124. // 简单的数字提取备用方案
  125. String num = input.replaceAll("[^0-9.]", "");
  126. if(!num.isEmpty()) return num + "kg";
  127. } catch(Exception e){}
  128. return "";
  129. }
  130. }