Android CGM阅读器BLE问题:无法接收GATT广播及后台数据获取失败
CGM阅读器应用问题修正方案
一、广播接收不稳定修复
问题根源
动态广播注册生命周期不匹配、IntentFilter Action与Service发送的不严格一致,或是Android 8.0+静态广播限制导致接收失效。
代码修正
- MainActivity中动态注册广播
private BroadcastReceiver gattUpdateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { // 处理服务发现逻辑 handleGattServices(BluetoothLeService.getSupportedGattServices()); } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { // 解析血糖数据 byte[] rawData = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA); parseGlucoseData(rawData); } // 补充其他Action处理(连接成功/断开等) } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 注册广播过滤器 IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); filter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); filter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); filter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); registerReceiver(gattUpdateReceiver, filter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(gattUpdateReceiver); }
- BluetoothLeService中规范广播发送
private static final String ACTION_GATT_SERVICES_DISCOVERED = "com.your.package.ACTION_GATT_SERVICES_DISCOVERED"; private static final String ACTION_DATA_AVAILABLE = "com.your.package.ACTION_DATA_AVAILABLE"; public static final String EXTRA_DATA = "com.your.package.EXTRA_DATA"; private void broadcastUpdate(String action) { sendBroadcast(new Intent(action)); } private void broadcastUpdate(String action, byte[] data) { Intent intent = new Intent(action); intent.putExtra(EXTRA_DATA, data); sendBroadcast(intent); } // 服务发现回调中触发广播 @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { mGattServices = gatt.getServices(); broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); } }
二、后台数据获取处理
问题根源
Android后台限制(Doze模式、App Standby)导致服务被回收,定时任务失效。
代码修正
- 将BluetoothLeService改为前台服务
@Override public void onCreate() { super.onCreate(); // 创建通知渠道(Android 8.0+必填) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( "CGM_CHANNEL", "血糖监测服务", NotificationManager.IMPORTANCE_LOW ); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); } // 启动前台服务 Notification notification = new NotificationCompat.Builder(this, "CGM_CHANNEL") .setContentTitle("CGM监测中") .setContentText("持续获取血糖数据") .setSmallIcon(R.drawable.ic_cgm) .build(); startForeground(1001, notification); }
- 用WorkManager实现稳定定时任务
注:Android 12+ PeriodicWorkRequest最小间隔为15分钟,若需60秒间隔,需结合前台服务+Handler实现
// MainActivity中初始化定时任务 PeriodicWorkRequest cgmSyncRequest = new PeriodicWorkRequest.Builder( CgmSyncWorker.class, 15, TimeUnit.MINUTES) .setConstraints(new Constraints.Builder() .setRequiredNetworkType(NetworkType.NOT_REQUIRED) .build()) .build(); WorkManager.getInstance(this).enqueue(cgmSyncRequest); // 自定义Worker类 public class CgmSyncWorker extends Worker { public CgmSyncWorker(@NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @NonNull @Override public Result doWork() { // 执行BLE连接与数据获取逻辑 Intent serviceIntent = new Intent(getApplicationContext(), BluetoothLeService.class); getApplicationContext().startForegroundService(serviceIntent); return Result.success(); } }
三、catchNewGlucValue方法修正
问题根源
服务未绑定完成就执行数据获取,或是特征值读取/通知逻辑缺失。
代码修正
private BluetoothLeService mBluetoothLeService; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { BluetoothLeService.LocalBinder binder = (BluetoothLeService.LocalBinder) service; mBluetoothLeService = binder.getService(); // 服务绑定成功后立即触发数据获取 catchNewGlucValue(); } @Override public void onServiceDisconnected(ComponentName name) { mBluetoothLeService = null; } }; private void catchNewGlucValue() { if (mBluetoothLeService == null) { // 重新绑定服务 Intent intent = new Intent(this, BluetoothLeService.class); bindService(intent, mServiceConnection, BIND_AUTO_CREATE); return; } // 获取血糖特征值(替换为你的CGM设备UUID) BluetoothGattCharacteristic glucoseChar = getGlucoseCharacteristic(); if (glucoseChar != null) { // 开启特征值通知(推荐),替代主动读取 mBluetoothLeService.setCharacteristicNotification(glucoseChar, true); // 若需主动读取 // mBluetoothLeService.readCharacteristic(glucoseChar); } } private BluetoothGattCharacteristic getGlucoseCharacteristic() { List<BluetoothGattService> services = mBluetoothLeService.getSupportedGattServices(); if (services == null) return null; // 血糖服务UUID:00001808-0000-1000-8000-00805f9b34fb // 血糖特征值UUID:00002a18-0000-1000-8000-00805f9b34fb for (BluetoothGattService service : services) { if (service.getUuid().equals(UUID.fromString("00001808-0000-1000-8000-00805f9b34fb"))) { return service.getCharacteristic(UUID.fromString("00002a18-0000-1000-8000-00805f9b34fb")); } } return null; }
四、额外注意事项
- 权限申请:Android 12+需动态申请
BLUETOOTH_SCAN、BLUETOOTH_CONNECT、ACCESS_FINE_LOCATION权限 - BLE连接优化:优先保持长连接+特征值通知,避免频繁断开重连,提升稳定性与续航
- 错误处理:在GATT回调中处理连接失败、服务发现失败场景,添加自动重连逻辑
内容的提问来源于stack exchange,提问作者Marco Chiesi
相关产品推荐
相关产品推荐

