react-native-beidou 1.1.3 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/Compass.android.tsx +4 -12
  2. package/Compass.ios.tsx +2 -3
  3. package/android/build.gradle +22 -9
  4. package/android/src/main/AndroidManifest.xml +1 -0
  5. package/android/src/main/java/com/fxzs.rnbeidou/BeiDouBluetoothModule.java +528 -188
  6. package/android/src/main/java/com/fxzs.rnbeidou/BeiDouBluetoothPackage.java +10 -13
  7. package/android/src/main/java/com/fxzs.rnbeidou/BeidouAidlHelper.java +45 -13
  8. package/android/src/main/java/com/fxzs.rnbeidou/SuperSimModule.java +301 -0
  9. package/android/src/main/java/com/fxzs.rnbeidou/view/CompassManager.java +15 -15
  10. package/android/src/main/java/com/fxzs.rnbeidou/view/CompassView.java +10 -4
  11. package/index.ts +128 -228
  12. package/ios/BeiDouBluetoothModule.m +147 -20
  13. package/ios/BeidouBluetooth.framework/BeidouBluetooth +0 -0
  14. package/ios/BeidouBluetooth.framework/FMDB.bundle/Info.plist +0 -0
  15. package/ios/BeidouBluetooth.framework/Info.plist +0 -0
  16. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeDirectory +0 -0
  17. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeRequirements-1 +0 -0
  18. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeResources +4 -4
  19. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeSignature +0 -0
  20. package/ios/CompassView.h +1 -0
  21. package/ios/CompassView.m +3 -0
  22. package/ios/CompassViewComponentView.h +11 -0
  23. package/ios/CompassViewComponentView.mm +64 -0
  24. package/package.json +3 -5
  25. package/react-native-beidou.podspec +6 -3
  26. package/react-native.config.js +2 -5
  27. package/src/CompassViewNativeComponent.ts +13 -0
  28. package/src/NativeBeiDouBluetooth.ts +57 -0
  29. package/src/NativeSuperSim.ts +21 -0
  30. package/BeiDouAIDLTestPage.tsx +0 -1196
  31. package/LogManager.ts +0 -285
  32. package/TestPage.ts +0 -6
  33. package/android/.gradle/8.10/checksums/checksums.lock +0 -0
  34. package/android/.gradle/8.10/dependencies-accessors/gc.properties +0 -0
  35. package/android/.gradle/8.10/fileChanges/last-build.bin +0 -0
  36. package/android/.gradle/8.10/fileHashes/fileHashes.lock +0 -0
  37. package/android/.gradle/8.10/gc.properties +0 -0
  38. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  39. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  40. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  41. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  42. package/android/.gradle/8.9/gc.properties +0 -0
  43. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  44. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  45. package/android/.gradle/config.properties +0 -2
  46. package/android/.gradle/vcs-1/gc.properties +0 -0
  47. package/android/.idea/AndroidProjectSystem.xml +0 -6
  48. package/android/.idea/caches/deviceStreaming.xml +0 -1138
  49. package/android/.idea/gradle.xml +0 -13
  50. package/android/.idea/migrations.xml +0 -10
  51. package/android/.idea/misc.xml +0 -9
  52. package/android/.idea/runConfigurations.xml +0 -17
  53. package/android/.idea/vcs.xml +0 -6
  54. package/android/local.properties +0 -8
  55. package/android/src/main/java/com/fxzs.rnbeidou/LogManager.java +0 -488
@@ -2,8 +2,10 @@ package com.fxzs.rnbeidou;
2
2
 
3
3
  import android.Manifest;
4
4
  import android.bluetooth.BluetoothAdapter;
5
+ import android.content.ContentResolver;
5
6
  import android.content.Context;
6
7
  import android.content.pm.PackageManager;
8
+ import android.database.Cursor;
7
9
  import android.net.ConnectivityManager;
8
10
  import android.net.NetworkInfo;
9
11
  import android.net.wifi.WifiInfo;
@@ -13,6 +15,7 @@ import android.os.Build;
13
15
  import android.os.Bundle;
14
16
  import android.os.Handler;
15
17
  import android.os.Looper;
18
+ import android.provider.ContactsContract;
16
19
  import android.util.Log;
17
20
  import android.location.Location;
18
21
  import android.location.LocationListener;
@@ -31,6 +34,12 @@ import com.beidou.bluetooth.callback.BluetoothConnectionCallback;
31
34
  import com.beidou.bluetooth.callback.BluetoothDataCallback;
32
35
  import com.beidou.bluetooth.callback.BluetoothPushCallback;
33
36
  import com.beidou.bluetooth.model.BlueDeviceInfoEntity;
37
+ //import com.cmcc.bdmsg.bdmsgterminal.BDMsgAuthTerminalSdk;
38
+ //import com.cmcc.bdmsg.bdmsgterminal.model.BDMsgGetKeyAndAuthTerminalResponse;
39
+ //import com.cmcc.bdmsg.bdmsgterminal.model.BDMsgGetUserInfoTerminalResponse;
40
+ //import com.cmcc.bdmsgserver.bdmsgauth.model.BDMsgEphemerisFileDownloadResponse;
41
+ //import com.cmcc.bdmsgserver.bdmsgauth.model.BDMsgMailReplyResponse;
42
+ //import com.cmcc.bdmsgserver.bdmsgauth.model.BDMsgSMCryptResponse;
34
43
  import com.facebook.react.bridge.Callback;
35
44
  import com.facebook.react.bridge.Promise;
36
45
  import com.facebook.react.bridge.ReactApplicationContext;
@@ -46,25 +55,44 @@ import com.facebook.react.modules.core.DeviceEventManagerModule;
46
55
 
47
56
  import org.json.JSONException;
48
57
 
58
+ import java.text.Collator;
49
59
  import java.util.Arrays;
50
60
  import java.util.Base64;
61
+ import java.util.LinkedList;
51
62
  import java.util.Map;
52
63
  import java.util.Objects;
53
64
  import java.util.ArrayList;
65
+ import java.util.HashSet;
54
66
  import java.util.List;
67
+ import java.util.Locale;
55
68
  import java.util.concurrent.atomic.AtomicBoolean;
56
69
 
57
70
  public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
71
+ public static final String NAME = "BeiDouBluetoothModule";
72
+ private static final String EVENT_BLUETOOTH_ERROR = "beidouBluetoothError";
73
+ private static final int RESULT_OK = 1;
74
+ private static final int RESULT_FAIL = 0;
75
+ private static final int RESULT_PERMISSION_DENIED = 3;
76
+ private static final int RESULT_BLUETOOTH_OFF = 4;
77
+ private static final int RESULT_LOCATION_OFF = 5;
78
+ private static final String[] PINYIN_BOUNDARY = {
79
+ "阿", "芭", "擦", "搭", "蛾", "发", "噶", "哈", "击", "喀", "垃",
80
+ "妈", "拿", "哦", "啪", "期", "然", "撒", "塌", "挖", "昔", "压", "匝"
81
+ };
82
+ private static final String[] PINYIN_INITIAL = {
83
+ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L",
84
+ "M", "N", "O", "P", "Q", "R", "S", "T", "W", "X", "Y", "Z"
85
+ };
58
86
  private ReactContext reactContext;
59
- private LogManager logger;
60
87
 
61
88
  // 北斗AIDL服务辅助类
62
89
  private final BeidouAidlHelper beidouAidlHelper;
90
+ private final AtomicBoolean sdkPushCallbackRegistered = new AtomicBoolean(false);
63
91
 
64
92
  @NonNull
65
93
  @Override
66
94
  public String getName() {
67
- return "BeiDouBluetoothModule";
95
+ return NAME;
68
96
  }
69
97
 
70
98
  public BeiDouBluetoothModule(@Nullable ReactApplicationContext reactContext) {
@@ -72,27 +100,107 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
72
100
  this.reactContext = reactContext;
73
101
  this.beidouAidlHelper = new BeidouAidlHelper(reactContext);
74
102
 
75
- // 初始化日志管理器
76
- this.logger = LogManager.getInstance();
77
- // 默认配置:根据ApplicationInfo.FLAG_DEBUGGABLE判断是否为Debug模式
78
103
  boolean isDebug = reactContext != null &&
79
104
  (reactContext.getApplicationInfo().flags & android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0;
80
- logger.initialize(reactContext, isDebug, true, null);
105
+ Log.i("BeiDouBluetoothModule", "BeiDouBluetoothModule initialized - Debug: " + isDebug);
106
+ }
81
107
 
82
- logger.i("BeiDouBluetoothModule", "BeiDouBluetoothModule initialized - Debug: " + isDebug);
108
+ private static final class BlePrereqResult {
109
+ final int code;
110
+ final String message;
83
111
 
84
- BluetoothSDK.getInstance(reactContext).setPushCallback(new BluetoothPushCallback() {
85
- @Override
86
- public void onDevicePush(String deviceNo, String data, int cmd) {
87
- logger.d("BeiDouBluetoothModule", "收到设备推送消息: " + data);
88
- // 处理接收到的数据
89
- WritableMap writableMap = new WritableNativeMap();
90
- writableMap.putInt("type", 0);
91
- writableMap.putString("message", data);
92
- reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
93
- .emit("listenBluetoolth", writableMap);
112
+ BlePrereqResult(int code, String message) {
113
+ this.code = code;
114
+ this.message = message;
115
+ }
116
+ }
117
+
118
+ private void emitBluetoothError(int code, @Nullable String message) {
119
+ if (reactContext == null) return;
120
+ try {
121
+ WritableMap writableMap = new WritableNativeMap();
122
+ writableMap.putInt("code", code);
123
+ writableMap.putString("message", message == null ? "" : message);
124
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
125
+ .emit(EVENT_BLUETOOTH_ERROR, writableMap);
126
+ } catch (Throwable ignore) {
127
+ // 避免事件发送失败导致崩溃
128
+ }
129
+ }
130
+
131
+ private BluetoothSDK getBluetoothSdkInitialized() {
132
+ BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
133
+ if (sdkPushCallbackRegistered.compareAndSet(false, true)) {
134
+ instance.setPushCallback(new BluetoothPushCallback() {
135
+ @Override
136
+ public void onDevicePush(String deviceNo, String data, int cmd) {
137
+ Log.d("BeiDouBluetoothModule", "收到设备推送消息: " + data);
138
+ ReactContext ctx = BeiDouBluetoothModule.this.reactContext;
139
+ if (ctx == null) return;
140
+
141
+ WritableMap writableMap = new WritableNativeMap();
142
+ writableMap.putInt("type", 0);
143
+ writableMap.putString("message", data);
144
+ ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
145
+ .emit("listenBluetoolth", writableMap);
146
+ }
147
+ });
148
+ }
149
+ return instance;
150
+ }
151
+
152
+ private boolean isLocationServiceEnabled() {
153
+ if (reactContext == null) return false;
154
+ try {
155
+ LocationManager locationManager = (LocationManager) reactContext.getSystemService(Context.LOCATION_SERVICE);
156
+ if (locationManager == null) return false;
157
+
158
+ boolean gpsEnabled = false;
159
+ boolean networkEnabled = false;
160
+ try {
161
+ gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
162
+ } catch (Exception ignore) {
94
163
  }
95
- });
164
+ try {
165
+ networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
166
+ } catch (Exception ignore) {
167
+ }
168
+ return gpsEnabled || networkEnabled;
169
+ } catch (Throwable ignore) {
170
+ return false;
171
+ }
172
+ }
173
+
174
+ private BlePrereqResult checkBlePrerequisitesForScanOrConnect() {
175
+ if (reactContext == null) {
176
+ return new BlePrereqResult(RESULT_FAIL, "上下文为空,无法执行蓝牙操作");
177
+ }
178
+
179
+ BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
180
+ if (bluetoothAdapter == null) {
181
+ return new BlePrereqResult(RESULT_BLUETOOTH_OFF, "设备不支持蓝牙");
182
+ }
183
+ if (!bluetoothAdapter.isEnabled()) {
184
+ return new BlePrereqResult(RESULT_BLUETOOTH_OFF, "请先打开系统蓝牙开关");
185
+ }
186
+
187
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
188
+ boolean scanGranted = ContextCompat.checkSelfPermission(reactContext, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;
189
+ boolean connectGranted = ContextCompat.checkSelfPermission(reactContext, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED;
190
+ if (!scanGranted || !connectGranted) {
191
+ return new BlePrereqResult(RESULT_PERMISSION_DENIED, "缺少蓝牙权限,请在系统设置中允许“附近设备/蓝牙”权限");
192
+ }
193
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
194
+ boolean locationGranted = ContextCompat.checkSelfPermission(reactContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
195
+ if (!locationGranted) {
196
+ return new BlePrereqResult(RESULT_PERMISSION_DENIED, "缺少定位权限(用于蓝牙扫描)");
197
+ }
198
+ if (!isLocationServiceEnabled()) {
199
+ return new BlePrereqResult(RESULT_LOCATION_OFF, "请先打开系统定位开关(用于蓝牙扫描)");
200
+ }
201
+ }
202
+
203
+ return new BlePrereqResult(RESULT_OK, "");
96
204
  }
97
205
 
98
206
  // 消息数据库管理器实例
@@ -108,14 +216,14 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
108
216
 
109
217
  // 插入北斗蓝牙短信
110
218
  @ReactMethod
111
- public void insertMsg(String phone, String content, Double timestamp, Boolean isSend) {
219
+ public void insertMsg(String phone, String content, double timestamp, boolean isSend) {
112
220
  try {
113
- long timeInterval = timestamp.longValue();
114
- boolean send = isSend != null ? isSend : false;
221
+ long timeInterval = (long) timestamp;
222
+ boolean send = isSend;
115
223
  getChatDBManager().insertMessage(content, phone, send, timeInterval);
116
- logger.d("BeiDouBluetoothModule", String.format("插入消息成功 - 手机号: %s, 是否发送: %b", phone, send));
224
+ Log.d("BeiDouBluetoothModule", String.format("插入消息成功 - 手机号: %s, 是否发送: %b", phone, send));
117
225
  } catch (Exception e) {
118
- logger.e("BeiDouBluetoothModule", "插入消息失败: " + e.getMessage(), e);
226
+ Log.e("BeiDouBluetoothModule", "插入消息失败: " + e.getMessage(), e);
119
227
  }
120
228
  }
121
229
 
@@ -134,10 +242,10 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
134
242
 
135
243
  // 获取会话详情
136
244
  @ReactMethod
137
- public void getMessagesForPhone(String phone, Integer page, Integer pageSize, Callback callback) {
245
+ public void getMessagesForPhone(String phone, double page, double pageSize, Callback callback) {
138
246
  try {
139
- int pageNum = page != null ? page : 0;
140
- int size = pageSize != null ? pageSize : 20;
247
+ int pageNum = (int) page;
248
+ int size = (int) pageSize;
141
249
 
142
250
  List<Map<String, Object>> messages = getChatDBManager().getMessagesForPhone(phone, pageNum, size);
143
251
  String jsonString = JsonUtil.objectToJson(messages);
@@ -152,50 +260,109 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
152
260
  // 开始扫描蓝牙设备
153
261
  @ReactMethod
154
262
  public void startScanForService(Callback callback) {
155
- BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
263
+ // Android 12+ 理论上不强制依赖定位开关,但部分厂商机型仍会在定位关闭时扫不到设备
264
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !isLocationServiceEnabled()) {
265
+ emitBluetoothError(RESULT_LOCATION_OFF, "请先打开系统定位开关");
266
+ }
267
+
268
+ BlePrereqResult prereq = checkBlePrerequisitesForScanOrConnect();
269
+ if (prereq.code != RESULT_OK) {
270
+ Log.w("BluetoothSDK", "startScanForService blocked: " + prereq.message);
271
+ emitBluetoothError(prereq.code, prereq.message);
272
+ if (callback != null) callback.invoke(prereq.code);
273
+ return;
274
+ }
275
+ BluetoothSDK instance = getBluetoothSdkInitialized();
156
276
  Log.d("BluetoothSDK", "MyModule-> 开始扫描");
157
- instance.startScan();
277
+ try {
278
+ instance.startScan();
279
+ if (callback != null) callback.invoke(RESULT_OK);
280
+ } catch (Throwable t) {
281
+ String msg = "开始扫描失败: " + (t.getMessage() == null ? t.getClass().getSimpleName() : t.getMessage());
282
+ Log.e("BluetoothSDK", msg, t);
283
+ emitBluetoothError(RESULT_FAIL, msg);
284
+ if (callback != null) callback.invoke(RESULT_FAIL);
285
+ }
158
286
  }
159
287
 
160
288
  // 停止扫描蓝牙设备
161
289
  @ReactMethod
162
290
  public void stopScanning() {
163
- BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
164
- instance.stopScan();
291
+ try {
292
+ BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
293
+ if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) return;
294
+ BluetoothSDK instance = getBluetoothSdkInitialized();
295
+ instance.stopScan();
296
+ } catch (Throwable t) {
297
+ String msg = "停止扫描失败: " + (t.getMessage() == null ? t.getClass().getSimpleName() : t.getMessage());
298
+ Log.e("BluetoothSDK", msg, t);
299
+ emitBluetoothError(RESULT_FAIL, msg);
300
+ }
165
301
  }
166
302
 
167
303
  // 获取扫描结果
168
304
  @ReactMethod
169
- public void getDiscoveredDevices(Promise promise) throws JSONException {
170
- BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
171
- Map<String, BlueDeviceInfoEntity> deviceInfoMap = instance.getScannedDevices();
172
-
173
- // 将 BlueDeviceInfoEntity 对象转换为 List 以便序列化
174
- List<BlueDeviceInfoEntity> deviceList = new ArrayList<>(deviceInfoMap.values());
175
- String s = JsonUtil.objectToJson(deviceList);
176
- Log.d("BluetoothSDK", "获取设备列表:" + s);
177
- promise.resolve(s);
305
+ public void getDiscoveredDevices(Promise promise) {
306
+ try {
307
+ BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
308
+ if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
309
+ promise.resolve("[]");
310
+ return;
311
+ }
312
+ BluetoothSDK instance = getBluetoothSdkInitialized();
313
+ Map<String, BlueDeviceInfoEntity> deviceInfoMap = instance.getScannedDevices();
314
+
315
+ // 将 BlueDeviceInfoEntity 对象转换为 List 以便序列化
316
+ List<BlueDeviceInfoEntity> deviceList = new ArrayList<>(deviceInfoMap.values());
317
+ String s = JsonUtil.objectToJson(deviceList);
318
+ Log.d("BluetoothSDK", "获取设备列表:" + s);
319
+ promise.resolve(s);
320
+ } catch (Throwable t) {
321
+ String msg = "获取设备列表失败: " + (t.getMessage() == null ? t.getClass().getSimpleName() : t.getMessage());
322
+ Log.e("BluetoothSDK", msg, t);
323
+ emitBluetoothError(RESULT_FAIL, msg);
324
+ promise.resolve("[]");
325
+ }
178
326
  }
179
327
 
180
328
  // 根据 deviceNo 连接蓝牙设备
181
329
  @ReactMethod
182
- public void connectToDeviceFromCloudDeviceNO(String deviceNO, Double a, Promise promise) {
330
+ public void connectToDeviceFromCloudDeviceNO(String deviceNO, double a, Promise promise) {
183
331
  if (StringUtils.isEmpty(deviceNO)) {
184
332
  Log.e("BluetoothSDK", "connectToDeviceFromCloudDeviceNO: deviceNo isEmpty");
333
+ emitBluetoothError(RESULT_FAIL, "设备编号为空,无法连接");
185
334
  promise.resolve("0");
186
335
  return;
187
336
  }
188
- BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
337
+
338
+ // Android 12+ 理论上不强制依赖定位开关,但部分厂商机型仍会在定位关闭时扫不到设备
339
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !isLocationServiceEnabled()) {
340
+ emitBluetoothError(RESULT_LOCATION_OFF, "请先打开系统定位开关(部分机型蓝牙扫描需要)");
341
+ }
342
+
343
+ BlePrereqResult prereq = checkBlePrerequisitesForScanOrConnect();
344
+ if (prereq.code != RESULT_OK) {
345
+ Log.w("BluetoothSDK", "connect blocked: " + prereq.message);
346
+ emitBluetoothError(prereq.code, prereq.message);
347
+ promise.resolve(String.valueOf(prereq.code));
348
+ return;
349
+ }
350
+
351
+ BluetoothSDK instance = getBluetoothSdkInitialized();
352
+ AtomicBoolean handled = new AtomicBoolean(false);
189
353
  BluetoothConnectionCallback connectionCallback = new BluetoothConnectionCallback() {
190
354
  @Override
191
355
  public void onConnected(String deviceNo) {
192
356
  Log.d("BluetoothSDK", "蓝牙连接状态返回给 RN: 1");
357
+ if (handled.getAndSet(true)) return;
193
358
  promise.resolve("1");
194
359
  }
195
360
 
196
361
  @Override
197
362
  public void onConnectionFailed(String deviceNo, int errorCode, String errorMessage) {
198
363
  Log.d("BluetoothSDK", "蓝牙连接状态返回给 RN: 0");
364
+ if (handled.getAndSet(true)) return;
365
+ emitBluetoothError(RESULT_FAIL, "连接失败: " + errorMessage);
199
366
  promise.resolve("0");
200
367
  }
201
368
 
@@ -203,6 +370,8 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
203
370
  public void onDisconnected(String deviceNo) {
204
371
  // 连接过程中意外断开
205
372
  Log.d("BluetoothSDK", "蓝牙连接状态返回给 RN: 0");
373
+ if (handled.getAndSet(true)) return;
374
+ emitBluetoothError(RESULT_FAIL, "连接断开");
206
375
  promise.resolve("0");
207
376
  }
208
377
 
@@ -211,7 +380,15 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
211
380
  // 服务发现完成,不需要特殊处理
212
381
  }
213
382
  };
214
- instance.connectDevice(deviceNO, connectionCallback);
383
+ try {
384
+ instance.connectDevice(deviceNO, connectionCallback);
385
+ } catch (Throwable t) {
386
+ if (handled.getAndSet(true)) return;
387
+ String msg = "发起连接异常: " + (t.getMessage() == null ? t.getClass().getSimpleName() : t.getMessage());
388
+ Log.e("BluetoothSDK", msg, t);
389
+ emitBluetoothError(RESULT_FAIL, msg);
390
+ promise.resolve("0");
391
+ }
215
392
  }
216
393
 
217
394
  /**
@@ -256,7 +433,7 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
256
433
  * 蓝牙权限--根据Android的不同版本,判断是否具有蓝牙权限
257
434
  */
258
435
  @ReactMethod
259
- public void checkBlueToothPermission(Callback callback) throws JSONException {
436
+ public void checkBlueToothPermission(Callback callback) {
260
437
  if (reactContext == null) {
261
438
  return;
262
439
  }
@@ -299,7 +476,7 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
299
476
  * 蓝牙权限--BLUETOOTH
300
477
  */
301
478
  @ReactMethod
302
- public void shouldShowBlueToothPermissionRationale(String params, Callback callback) throws JSONException {
479
+ public void shouldShowBlueToothPermissionRationale(String params, Callback callback) {
303
480
  String ret = "";
304
481
  System.out.println("获取Android版本2::::::::::::::Build.VERSION.SDK_INT" + Build.VERSION.SDK_INT);
305
482
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -328,7 +505,7 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
328
505
  * 初始化蓝牙--BLUETOOTH
329
506
  */
330
507
  @ReactMethod
331
- public void initializeBluetooth(Callback callback) throws JSONException {
508
+ public void initializeBluetooth(Callback callback) {
332
509
  String ret = "";
333
510
  System.out.println("初始化蓝牙操作::::::::::::::Build.VERSION.SDK_INT" + Build.VERSION.SDK_INT);
334
511
  BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -356,8 +533,8 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
356
533
  public String generateRandom16BytesString() {
357
534
  byte[] bytes = ByteUtil.generateRandomHexBytes(32);
358
535
  Log.d("BluetoothSDK", "获取随机字节数组:" + Arrays.toString(bytes));
359
- // String b = java.util.Base64.getEncoder().encodeToString(bytes);
360
- String b = "2PJFUoUNB502/KJdVQg5Kg==";
536
+ String b = java.util.Base64.getEncoder().encodeToString(bytes);
537
+ // String b = "2PJFUoUNB502/KJdVQg5Kg==";
361
538
  Log.d("BluetoothSDK", "随机字节数组加密 Base64字符串:" + b);
362
539
  return b;
363
540
  }
@@ -373,7 +550,7 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
373
550
  // instance.writeData(randomString, deviceNo, command, attrType,true,callback);
374
551
  // }
375
552
  @ReactMethod
376
- public void writeData(String randomString, String deviceNo, Integer command, Integer attrType,
553
+ public void writeData(String randomString, String deviceNo, double command, double attrType,
377
554
  Callback writeCallback) {
378
555
  BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
379
556
  Log.d("BluetoothSDK", "收到写入请求" + command + " " + attrType + " " + randomString);
@@ -413,15 +590,15 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
413
590
  }
414
591
  };
415
592
  instance.setDataCallback(dataCallback);
416
- instance.writeData(randomString, deviceNo, command, attrType);
593
+ instance.writeData(randomString, deviceNo, (int) command, (int) attrType);
417
594
  }
418
595
 
419
596
  // 存储BLE密钥的字段
420
597
  private String bleKeyHex = "";
421
598
 
422
599
  @ReactMethod
423
- public void writeInfo(@Nullable String base64Payload, String deviceNO, Integer command, Integer opCode,
424
- Integer attrType, Boolean encrypted, Promise promise) {
600
+ public void writeInfo(@Nullable String base64Payload, String deviceNO, double command, double opCode,
601
+ double attrType, boolean encrypted, Promise promise) {
425
602
  try {
426
603
  BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
427
604
 
@@ -441,10 +618,10 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
441
618
  }
442
619
 
443
620
  // 转换参数类型
444
- int commandValue = command & 0xFF;
445
- int opCodeValue = opCode & 0xFF;
446
- int attrTypeValue = attrType & 0xFFFF;
447
- boolean isEncrypted = encrypted != null ? encrypted : false;
621
+ int commandValue = (int) command;
622
+ int opCodeValue = (int) opCode;
623
+ int attrTypeValue = (int) attrType;
624
+ boolean isEncrypted = encrypted;
448
625
 
449
626
  Log.d("BluetoothSDK", String.format(
450
627
  "writeInfo - deviceNO: %s, command: 0x%02X, opCode: 0x%02X, attrType: 0x%04X, encrypted: %b",
@@ -504,7 +681,7 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
504
681
  }
505
682
 
506
683
  @ReactMethod
507
- public void writeValueInfo(String randomString, String deviceNo, Integer command, Integer attrType, Integer value,
684
+ public void writeValueInfo(String randomString, String deviceNo, double command, double attrType, double value,
508
685
  Callback writeCallback) {
509
686
  // BluetoothSDK instance = BluetoothSDK.getInstance(reactContext);
510
687
  // Log.d(BluetoothSDK.TAG, "收到写入请求" + command +" "+attrType+" "+randomString);
@@ -750,11 +927,173 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
750
927
  promise.reject("PERMISSION_DENIED", "获取SIM卡信息权限被拒绝: " + permissionException.getMessage(),
751
928
  permissionException);
752
929
  } catch (Exception e) {
753
- logger.e("BeiDouBluetoothModule", "获取SIM卡信息失败: " + e.getMessage(), e);
930
+ Log.e("BeiDouBluetoothModule", "获取SIM卡信息失败: " + e.getMessage(), e);
754
931
  promise.reject("SIM_INFO_ERROR", "获取SIM卡信息失败: " + e.getMessage(), e);
755
932
  }
756
933
  }
757
934
 
935
+ /**
936
+ * 获取系统通讯录(仅返回包含号码的联系人)
937
+ * 返回结构:
938
+ * [
939
+ * {
940
+ * "id": "123",
941
+ * "name": "张三",
942
+ * "firstLetter": "Z",
943
+ * "phoneNumbers": ["13800138000", ...]
944
+ * }
945
+ * ]
946
+ */
947
+ @ReactMethod
948
+ public void getContacts(Promise promise) {
949
+ try {
950
+ if (reactContext == null) {
951
+ promise.reject("CONTEXT_NULL", "React上下文不可用");
952
+ return;
953
+ }
954
+
955
+ Context context = reactContext.getCurrentActivity();
956
+ if (context == null) {
957
+ context = reactContext;
958
+ }
959
+
960
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
961
+ != PackageManager.PERMISSION_GRANTED) {
962
+ promise.reject("PERMISSION_DENIED", "缺少通讯录权限: READ_CONTACTS");
963
+ return;
964
+ }
965
+
966
+ ContentResolver contentResolver = context.getContentResolver();
967
+ WritableArray contactsArray = new WritableNativeArray();
968
+
969
+ Cursor contactsCursor = null;
970
+ try {
971
+ contactsCursor = contentResolver.query(
972
+ ContactsContract.Contacts.CONTENT_URI,
973
+ new String[] {
974
+ ContactsContract.Contacts._ID,
975
+ ContactsContract.Contacts.DISPLAY_NAME,
976
+ ContactsContract.Contacts.HAS_PHONE_NUMBER
977
+ },
978
+ null,
979
+ null,
980
+ ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
981
+
982
+ if (contactsCursor == null) {
983
+ promise.resolve(contactsArray);
984
+ return;
985
+ }
986
+
987
+ int idIndex = contactsCursor.getColumnIndex(ContactsContract.Contacts._ID);
988
+ int nameIndex = contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
989
+ int hasPhoneIndex = contactsCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
990
+
991
+ while (contactsCursor.moveToNext()) {
992
+ if (idIndex < 0 || nameIndex < 0 || hasPhoneIndex < 0) {
993
+ continue;
994
+ }
995
+
996
+ String contactId = contactsCursor.getString(idIndex);
997
+ String displayName = contactsCursor.getString(nameIndex);
998
+ int hasPhoneNumber = contactsCursor.getInt(hasPhoneIndex);
999
+ if (hasPhoneNumber <= 0) {
1000
+ continue;
1001
+ }
1002
+
1003
+ WritableArray phoneNumbers = new WritableNativeArray();
1004
+ HashSet<String> dedup = new HashSet<>();
1005
+ Cursor phonesCursor = null;
1006
+ try {
1007
+ phonesCursor = contentResolver.query(
1008
+ ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
1009
+ new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER },
1010
+ ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?",
1011
+ new String[] { contactId },
1012
+ null);
1013
+
1014
+ if (phonesCursor != null) {
1015
+ int numberIndex =
1016
+ phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
1017
+ while (phonesCursor.moveToNext()) {
1018
+ if (numberIndex < 0) {
1019
+ continue;
1020
+ }
1021
+ String rawNumber = phonesCursor.getString(numberIndex);
1022
+ if (rawNumber == null || rawNumber.trim().isEmpty()) {
1023
+ continue;
1024
+ }
1025
+ String cleaned = rawNumber.replaceAll("\\D", "");
1026
+ if (cleaned.isEmpty() || dedup.contains(cleaned)) {
1027
+ continue;
1028
+ }
1029
+ dedup.add(cleaned);
1030
+ phoneNumbers.pushString(cleaned);
1031
+ }
1032
+ }
1033
+ } finally {
1034
+ if (phonesCursor != null) {
1035
+ phonesCursor.close();
1036
+ }
1037
+ }
1038
+
1039
+ if (phoneNumbers.size() == 0) {
1040
+ continue;
1041
+ }
1042
+
1043
+ String name = (displayName == null || displayName.trim().isEmpty())
1044
+ ? "未知联系人"
1045
+ : displayName.trim();
1046
+
1047
+ String firstLetter = getSortLetter(name);
1048
+
1049
+ WritableMap contact = new WritableNativeMap();
1050
+ contact.putString("id", contactId);
1051
+ contact.putString("name", name);
1052
+ contact.putString("firstLetter", firstLetter);
1053
+ contact.putArray("phoneNumbers", phoneNumbers);
1054
+ contactsArray.pushMap(contact);
1055
+ }
1056
+ } finally {
1057
+ if (contactsCursor != null) {
1058
+ contactsCursor.close();
1059
+ }
1060
+ }
1061
+
1062
+ promise.resolve(contactsArray);
1063
+ } catch (SecurityException permissionException) {
1064
+ promise.reject("PERMISSION_DENIED", "读取通讯录权限被拒绝: " + permissionException.getMessage(),
1065
+ permissionException);
1066
+ } catch (Exception e) {
1067
+ Log.e("BeiDouBluetoothModule", "获取通讯录失败: " + e.getMessage(), e);
1068
+ promise.reject("CONTACTS_ERROR", "获取通讯录失败: " + e.getMessage(), e);
1069
+ }
1070
+ }
1071
+
1072
+ /**
1073
+ * 联系人分组首字母:
1074
+ * - 英文开头:直接取 A-Z
1075
+ * - 汉字开头:按拼音首字母归组
1076
+ * - 其它:#
1077
+ */
1078
+ private String getSortLetter(String name) {
1079
+ if (name == null || name.trim().isEmpty()) {
1080
+ return "#";
1081
+ }
1082
+ String firstChar = name.trim().substring(0, 1);
1083
+ String upper = firstChar.toUpperCase(Locale.ROOT);
1084
+ if (upper.matches("[A-Z]")) {
1085
+ return upper;
1086
+ }
1087
+
1088
+ Collator collator = Collator.getInstance(Locale.CHINA);
1089
+ for (int i = PINYIN_BOUNDARY.length - 1; i >= 0; i--) {
1090
+ if (collator.compare(firstChar, PINYIN_BOUNDARY[i]) >= 0) {
1091
+ return PINYIN_INITIAL[i];
1092
+ }
1093
+ }
1094
+ return "#";
1095
+ }
1096
+
758
1097
  // ================== 北斗AIDL服务相关方法 ==================
759
1098
 
760
1099
  @ReactMethod
@@ -768,89 +1107,162 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
768
1107
  }
769
1108
 
770
1109
  @ReactMethod
771
- public void BDAuthenticate(int slotId, Promise promise) {
772
- beidouAidlHelper.authenticate(slotId, promise);
1110
+ public void BDAuthenticate(double slotId, Promise promise) {
1111
+ beidouAidlHelper.authenticate((int) slotId, promise);
1112
+ // new Thread(() -> {
1113
+ // BDMsgGetKeyAndAuthTerminalResponse ksKeyAndAuthResult = BDMsgAuthTerminalSdk.getInstance(reactContext).getKsKeyAndAuthResult(slotId);
1114
+ // promise.resolve(ksKeyAndAuthResult.toString());
1115
+ // }).start();
773
1116
  }
774
1117
 
775
1118
  @ReactMethod
776
- public void getBDMsgStatus(int slotId, Promise promise) {
777
- beidouAidlHelper.getStatus(slotId, promise);
1119
+ public void getBDMsgStatus(double slotId, Promise promise) {
1120
+ beidouAidlHelper.getStatus((int) slotId, promise);
1121
+ // new Thread(() -> {
1122
+ // BDMsgGetUserInfoTerminalResponse currentUserInfo = BDMsgAuthTerminalSdk.getInstance(reactContext).getCurrentUserInfo(slotId);
1123
+ // promise.resolve(currentUserInfo.toString());
1124
+ // }).start();
778
1125
  }
779
1126
 
780
1127
  @ReactMethod
781
- public void checkValidatedKey(int slotId, Promise promise) {
782
- beidouAidlHelper.checkValidatedKey(slotId, promise);
1128
+ public void checkValidatedKey(double slotId, Promise promise) {
1129
+ beidouAidlHelper.checkValidatedKey((int) slotId, promise);
1130
+ // new Thread(() -> {
1131
+ // int i = BDMsgAuthTerminalSdk.getInstance(reactContext).checkKeyIsExistAndValidate(slotId);
1132
+ // promise.resolve(i);
1133
+ // }).start();
783
1134
  }
784
1135
 
785
1136
  @ReactMethod
786
- public void commonBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
1137
+ public void commonBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
787
1138
  Promise promise) {
788
- beidouAidlHelper.commonBDMsgEncrypt(slotId, speedType, receiveList, inputMsg, promise);
1139
+ beidouAidlHelper.commonBDMsgEncrypt((int) slotId, speedType, receiveList, inputMsg, promise);
1140
+ // new Thread(() -> {
1141
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1142
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).commonMessageEncryptBDMsgByTerminal(slotId, speedType, receiveStringList, inputMsg);
1143
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1144
+ // }).start();
789
1145
  }
790
1146
 
791
1147
  @ReactMethod
792
- public void positionBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
1148
+ public void positionBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
793
1149
  double longitude, double latitude, Promise promise) {
794
- beidouAidlHelper.positionBDMsgEncrypt(slotId, speedType, receiveList, inputMsg, longitude, latitude, promise);
1150
+ beidouAidlHelper.positionBDMsgEncrypt((int) slotId, speedType, receiveList, inputMsg, longitude, latitude, promise);
1151
+ // new Thread(() -> {
1152
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1153
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).positionReportEncryptBDMsgByTerminal(slotId, speedType, receiveStringList, inputMsg, longitude, latitude);
1154
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1155
+ // }).start();
795
1156
  }
796
1157
 
797
1158
  @ReactMethod
798
- public void commonEmergencyBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
1159
+ public void commonEmergencyBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
799
1160
  Promise promise) {
800
- beidouAidlHelper.commonEmergencyBDMsgEncrypt(slotId, speedType, receiveList, inputMsg, promise);
1161
+ beidouAidlHelper.commonEmergencyBDMsgEncrypt((int) slotId, speedType, receiveList, inputMsg, promise);
1162
+ // new Thread(() -> {
1163
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1164
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).commonMessageEncryptBDMsgByEmergencyTerminal(slotId, speedType, receiveStringList, inputMsg);
1165
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1166
+ // }).start();
801
1167
  }
802
1168
 
803
1169
  @ReactMethod
804
- public void positionEmergencyBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
1170
+ public void positionEmergencyBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String inputMsg,
805
1171
  double longitude, double latitude, Promise promise) {
806
- beidouAidlHelper.positionEmergencyBDMsgEncrypt(slotId, speedType, receiveList, inputMsg, longitude, latitude, promise);
1172
+ beidouAidlHelper.positionEmergencyBDMsgEncrypt((int) slotId, speedType, receiveList, inputMsg, longitude, latitude, promise);
1173
+ // new Thread(() -> {
1174
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1175
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).positionReportEncryptBDMsgByEmergencyTerminal(slotId, speedType, receiveStringList, inputMsg, longitude, latitude);
1176
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1177
+ // }).start();
807
1178
  }
808
1179
 
809
1180
  @ReactMethod
810
- public void commonRichMediaBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String msgType,
1181
+ public void commonRichMediaBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String msgType,
811
1182
  @Nullable ReadableArray inputRichMediaData, Promise promise) {
812
- beidouAidlHelper.commonRichMediaBDMsgEncrypt(slotId, speedType, receiveList, msgType, inputRichMediaData, promise);
1183
+ beidouAidlHelper.commonRichMediaBDMsgEncrypt((int) slotId, speedType, receiveList, msgType, inputRichMediaData, promise);
1184
+ // new Thread(() -> {
1185
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1186
+ // byte[] bytes = readableArrayToByteArray(inputRichMediaData);
1187
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).commonRichMediaEncryptBDMsgByTerminal(slotId, speedType, receiveStringList,msgType,bytes);
1188
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1189
+ // }).start();
813
1190
  }
814
1191
 
815
1192
  @ReactMethod
816
- public void positionRichMediaBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String msgType,
1193
+ public void positionRichMediaBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String msgType,
817
1194
  @Nullable ReadableArray inputRichMediaData, double longitude, double latitude, Promise promise) {
818
- beidouAidlHelper.positionRichMediaBDMsgEncrypt(slotId, speedType, receiveList, msgType, inputRichMediaData, longitude,
1195
+ beidouAidlHelper.positionRichMediaBDMsgEncrypt((int) slotId, speedType, receiveList, msgType, inputRichMediaData, longitude,
819
1196
  latitude, promise);
1197
+ // new Thread(() -> {
1198
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1199
+ // byte[] bytes = readableArrayToByteArray(inputRichMediaData);
1200
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).positionRichMediaReportEncryptBDMsgByTerminal(slotId, speedType, receiveStringList, msgType, bytes, longitude, latitude);
1201
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1202
+ // }).start();
820
1203
  }
821
1204
 
822
1205
  @ReactMethod
823
- public void commonRichMediaAndTextBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String text,
1206
+ public void commonRichMediaAndTextBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String text,
824
1207
  String msgType, @Nullable ReadableArray inputRichMediaData, Promise promise) {
825
- beidouAidlHelper.commonRichMediaAndTextBDMsgEncrypt(slotId, speedType, receiveList, text, msgType, inputRichMediaData,
1208
+ beidouAidlHelper.commonRichMediaAndTextBDMsgEncrypt((int) slotId, speedType, receiveList, text, msgType, inputRichMediaData,
826
1209
  promise);
1210
+ // new Thread(() -> {
1211
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1212
+ // byte[] bytes = readableArrayToByteArray(inputRichMediaData);
1213
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).commonRichMediaAndTextEncryptBDMsgByTerminal(slotId, speedType, receiveStringList, text, msgType, bytes);
1214
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1215
+ // }).start();
827
1216
  }
828
1217
 
829
1218
  @ReactMethod
830
- public void positionRichMediaAndTextBDMsgEncrypt(int slotId, String speedType, @Nullable ReadableArray receiveList, String text,
1219
+ public void positionRichMediaAndTextBDMsgEncrypt(double slotId, String speedType, @Nullable ReadableArray receiveList, String text,
831
1220
  String msgType, @Nullable ReadableArray inputRichMediaData, double longitude, double latitude, Promise promise) {
832
- beidouAidlHelper.positionRichMediaAndTextBDMsgEncrypt(slotId, speedType, receiveList, text, msgType, inputRichMediaData,
1221
+ beidouAidlHelper.positionRichMediaAndTextBDMsgEncrypt((int) slotId, speedType, receiveList, text, msgType, inputRichMediaData,
833
1222
  longitude, latitude, promise);
1223
+ // new Thread(() -> {
1224
+ // LinkedList<String> receiveStringList = readableArrayToStringList(receiveList);
1225
+ // byte[] bytes = readableArrayToByteArray(inputRichMediaData);
1226
+ // List<BDMsgSMCryptResponse> bdMsgSMCryptResponses = BDMsgAuthTerminalSdk.getInstance(reactContext).positionRichMediaAndTextReportEncryptBDMsgByTerminal(slotId, speedType, receiveStringList, text, msgType, bytes, longitude, latitude);
1227
+ // promise.resolve(bdMsgSMCryptResponses.toString());
1228
+ // }).start();
834
1229
  }
835
1230
 
836
1231
  @ReactMethod
837
- public void BDMailboxQueryEncrypt(int slotId, Promise promise) {
838
- beidouAidlHelper.mailboxQueryEncrypt(slotId, promise);
1232
+ public void BDMailboxQueryEncrypt(double slotId, Promise promise) {
1233
+ beidouAidlHelper.mailboxQueryEncrypt((int) slotId, promise);
1234
+ // new Thread(() -> {
1235
+ // BDMsgSMCryptResponse bdMsgSMCryptResponse = BDMsgAuthTerminalSdk.getInstance(reactContext).mailboxQueryEncryptBDMsg(slotId);
1236
+ // promise.resolve(bdMsgSMCryptResponse.toString());
1237
+ // }).start();
839
1238
  }
840
1239
 
841
1240
  @ReactMethod
842
- public void EmergencyBDMailboxQueryEncrypt(int slotId, String replyMobile, Promise promise) {
843
- beidouAidlHelper.emergencyMailboxQueryEncrypt(slotId, replyMobile, promise);
1241
+ public void EmergencyBDMailboxQueryEncrypt(double slotId, String replyMobile, Promise promise) {
1242
+ beidouAidlHelper.emergencyMailboxQueryEncrypt((int) slotId, replyMobile, promise);
1243
+ // new Thread(() -> {
1244
+ // BDMsgSMCryptResponse bdMsgSMCryptResponse = BDMsgAuthTerminalSdk.getInstance(reactContext).mailboxQueryEncryptBDMsgByEmergency(slotId,replyMobile);
1245
+ // promise.resolve(bdMsgSMCryptResponse.toString());
1246
+ // }).start();
844
1247
  }
845
1248
 
846
1249
  @ReactMethod
847
- public void BDMsgDecrypt(int slotId, @Nullable ReadableArray msg, int len, Promise promise) {
848
- beidouAidlHelper.decryptMessage(slotId, msg, len, promise);
1250
+ public void BDMsgDecrypt(double slotId, @Nullable ReadableArray msg, double len, Promise promise) {
1251
+ beidouAidlHelper.decryptMessage((int) slotId, msg, (int) len, promise);
1252
+ // new Thread(() -> {
1253
+ // byte[] bytes = readableArrayToByteArray(msg);
1254
+ // BDMsgMailReplyResponse bdMsgMailReplyResponse = BDMsgAuthTerminalSdk.getInstance(reactContext).mailboxReplyDecryptBDMsg(slotId, bytes, len);
1255
+ // promise.resolve(bdMsgMailReplyResponse.toString());
1256
+ // }).start();
849
1257
  }
850
1258
 
851
1259
  @ReactMethod
852
- public void DLEphemerisFile(int slotId, String type, String version, Promise promise) {
853
- beidouAidlHelper.downloadEphemerisFile(slotId, type, version, promise);
1260
+ public void DLEphemerisFile(double slotId, String type, String version, Promise promise) {
1261
+ beidouAidlHelper.downloadEphemerisFile((int) slotId, type, version, promise);
1262
+ // new Thread(() -> {
1263
+ // BDMsgEphemerisFileDownloadResponse bdMsgEphemerisFileDownloadResponse = BDMsgAuthTerminalSdk.getInstance(reactContext).downloadEphemerisFile(slotId, type, version);
1264
+ // promise.resolve(bdMsgEphemerisFileDownloadResponse.toString());
1265
+ // }).start();
854
1266
  }
855
1267
 
856
1268
  // 设置BLE密钥
@@ -900,13 +1312,13 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
900
1312
  try {
901
1313
  Location gpsLocation = null;
902
1314
  Location networkLocation = null;
903
-
1315
+
904
1316
  try {
905
1317
  if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
906
1318
  gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
907
1319
  }
908
1320
  } catch (Exception ignored) {}
909
-
1321
+
910
1322
  try {
911
1323
  if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
912
1324
  networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
@@ -941,7 +1353,7 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
941
1353
  });
942
1354
 
943
1355
  } catch (Exception e) {
944
- logger.e("BeiDouBluetoothModule", "获取GPS位置失败: " + e.getMessage(), e);
1356
+ Log.e("BeiDouBluetoothModule", "获取GPS位置失败: " + e.getMessage(), e);
945
1357
  promise.reject("LOCATION_ERROR", "获取GPS位置失败: " + e.getMessage(), e);
946
1358
  }
947
1359
  }
@@ -959,6 +1371,26 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
959
1371
  return map;
960
1372
  }
961
1373
 
1374
+ private LinkedList<String> readableArrayToStringList(@Nullable ReadableArray readableArray) {
1375
+ LinkedList<String> list = new LinkedList<>();
1376
+ if (readableArray == null) {
1377
+ return list;
1378
+ }
1379
+ for (int i = 0; i < readableArray.size(); i++) {
1380
+ list.add(readableArray.getString(i));
1381
+ }
1382
+ return list;
1383
+ }
1384
+ private byte[] readableArrayToByteArray(@Nullable ReadableArray readableArray) {
1385
+ if (readableArray == null) {
1386
+ return new byte[0];
1387
+ }
1388
+ byte[] bytes = new byte[readableArray.size()];
1389
+ for (int i = 0; i < readableArray.size(); i++) {
1390
+ bytes[i] = (byte) readableArray.getInt(i);
1391
+ }
1392
+ return bytes;
1393
+ }
962
1394
  /**
963
1395
  * 主动请求单次定位(带超时)
964
1396
  */
@@ -1008,7 +1440,7 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
1008
1440
  if (isHandled.compareAndSet(false, true)) {
1009
1441
  // 超时后移除监听
1010
1442
  locationManager.removeUpdates(listener);
1011
-
1443
+
1012
1444
  // 尝试最后一次获取缓存作为保底
1013
1445
  try {
1014
1446
  Location loc = locationManager.getLastKnownLocation(provider);
@@ -1032,107 +1464,15 @@ public class BeiDouBluetoothModule extends ReactContextBaseJavaModule {
1032
1464
  }
1033
1465
  }
1034
1466
 
1035
- // ================== 日志管理相关方法 ==================
1467
+ // SDK logging uses android.util.Log directly now.
1036
1468
 
1037
- /**
1038
- * 配置日志管理器
1039
- *
1040
- * @param enableFileLog 是否启用文件日志
1041
- * @param enableConsoleLog 是否启用控制台日志
1042
- * @param maxFileSize 最大文件大小(MB)
1043
- * @param maxFileCount 最大文件数量
1044
- * @param encryptionKey 加密密钥(可选)
1045
- */
1046
1469
  @ReactMethod
1047
- public void configureLogger(boolean enableFileLog, boolean enableConsoleLog,
1048
- double maxFileSize, int maxFileCount,
1049
- @Nullable String encryptionKey, Promise promise) {
1050
- try {
1051
- // 重新初始化日志管理器
1052
- boolean isDebug = reactContext != null &&
1053
- (reactContext.getApplicationInfo().flags & android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0;
1054
-
1055
- logger.initialize(reactContext, isDebug, enableFileLog, encryptionKey);
1056
- logger.setLogConfig(enableFileLog, enableConsoleLog,
1057
- (long) (maxFileSize * 1024 * 1024), maxFileCount);
1058
-
1059
- logger.i("BeiDouBluetoothModule", "Logger configured - FileLog: " + enableFileLog +
1060
- ", ConsoleLog: " + enableConsoleLog +
1061
- ", MaxFileSize: " + maxFileSize + "MB" +
1062
- ", MaxFileCount: " + maxFileCount +
1063
- ", Encryption: " + (encryptionKey != null));
1064
-
1065
- promise.resolve(true);
1066
- } catch (Exception e) {
1067
- logger.e("BeiDouBluetoothModule", "配置日志管理器失败: " + e.getMessage(), e);
1068
- promise.reject("CONFIG_ERROR", "配置日志管理器失败: " + e.getMessage(), e);
1069
- }
1470
+ public void addListener(String eventName) {
1471
+ // Required for RN 0.65+ to avoid warnings when JS adds listeners.
1070
1472
  }
1071
1473
 
1072
- /**
1073
- * 获取日志统计信息
1074
- */
1075
1474
  @ReactMethod
1076
- public void getLogStats(Promise promise) {
1077
- try {
1078
- String stats = logger.getLogStats();
1079
- promise.resolve(stats);
1080
- } catch (Exception e) {
1081
- logger.e("BeiDouBluetoothModule", "获取日志统计失败: " + e.getMessage(), e);
1082
- promise.reject("STATS_ERROR", "获取日志统计失败: " + e.getMessage(), e);
1083
- }
1084
- }
1085
-
1086
- /**
1087
- * 清空所有日志文件
1088
- */
1089
- @ReactMethod
1090
- public void clearAllLogs(Promise promise) {
1091
- try {
1092
- logger.clearAllLogs();
1093
- logger.i("BeiDouBluetoothModule", "所有日志文件已清空");
1094
- promise.resolve(true);
1095
- } catch (Exception e) {
1096
- logger.e("BeiDouBluetoothModule", "清空日志失败: " + e.getMessage(), e);
1097
- promise.reject("CLEAR_ERROR", "清空日志失败: " + e.getMessage(), e);
1098
- }
1099
- }
1100
-
1101
- /**
1102
- * 手动记录日志
1103
- */
1104
- @ReactMethod
1105
- public void writeLog(String level, String tag, String message, Promise promise) {
1106
- try {
1107
- switch (level.toUpperCase()) {
1108
- case "VERBOSE":
1109
- case "V":
1110
- logger.v(tag, message);
1111
- break;
1112
- case "DEBUG":
1113
- case "D":
1114
- logger.d(tag, message);
1115
- break;
1116
- case "INFO":
1117
- case "I":
1118
- logger.i(tag, message);
1119
- break;
1120
- case "WARN":
1121
- case "W":
1122
- logger.w(tag, message);
1123
- break;
1124
- case "ERROR":
1125
- case "E":
1126
- logger.e(tag, message);
1127
- break;
1128
- default:
1129
- logger.i(tag, message);
1130
- break;
1131
- }
1132
- promise.resolve(true);
1133
- } catch (Exception e) {
1134
- logger.e("BeiDouBluetoothModule", "写入日志失败: " + e.getMessage(), e);
1135
- promise.reject("LOG_ERROR", "写入日志失败: " + e.getMessage(), e);
1136
- }
1475
+ public void removeListeners(double count) {
1476
+ // Required for RN 0.65+ to avoid warnings when JS removes listeners.
1137
1477
  }
1138
1478
  }