Android 后台蓝牙处理:最好的方法是什么?

Android Background Bluetooth Processing: What's the best approach?

我刚刚开发了一个Android应用程序(minSdkVersion 23/ targetSdkVersion 29),可以连接到BluetoothLE设备以定期获取数据。

现在,在 MainActivity(不是第一个 activity)中,我执行以下注册 broadcastReciever 的操作:

public class StatusActivity extends AppCompatActivity {    
    BleService mBleService;
    BleScanCallback mScanCallback;
    BroadcastReceiver mBroadcastReceiver;    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mBroadcastReceiver = new LibBleBroadcastReceiver(this);
        IntentFilter intentFilter = new IntentFilter()    
        intentFilter.addAction(BleService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BleService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BleService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BleService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(BleService.ACTION_DID_WRITE_CHARACTERISTIC);
        intentFilter.addAction(BleService.ACTION_DID_FAIL);
        registerReceiver(mBroadcastReceiver, intentFilter);
    
        mScanCallback = new LibBleScanCallback(this);
        intent = new Intent(this, BleService.class);
        connection = new LibBleServiceConnection(this);
    
        startService(intent);
        if (!bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
            throw new IllegalStateException("bindService not successful");
        }
    }
    ...
    public void onDeviceDiscovered(String device_address){
        device_connected.activateNotifications(mBleService, connected_device);
        scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
            public void run() {
                device_connected.requestTemperature(mBleService, connected_device);
            }
        }, 0, 30, TimeUnit.MINUTES);
    }
    ...
}

在 AndroidManifest.xml 中声明了 BleService:

<service android:name=".bluetooth.BleService" android:enabled="true" />

然后,用户 select 一个设备(通过蓝牙扫描)并连接到它以从 BLE 设备获取数据。

一旦连接并发现(服务和特征),我每 30 分钟安排一个任务从设备获取数据。

设备处于 connected/discovered/dataRecieved 时执行的所有回调都在 StatusActivity 中,而不是在 BleService(意图)中以在 UI 中进行更改(尽管在后台它不会必要的)。

另一方面,我也必须始终保持一个 bakground 进程,因为我的应用程序启动了 BLE 广告以使 phone 成为 LE 设备,因此始终必须“开机”才能让其他设备找到 phone.

问题是,当我将应用程序置于后台或终止应用程序时,此计划不会执行或执行几次,直到进程被 android 终止。

在后台模式下执行此服务的最佳方法是什么?考虑到如果应用程序被终止,设备(我认为)将断开连接,所以我应该连接另一次到设备(我保存 MAC 地址重新连接所以这不是问题)并执行 requestData 方法? WorkManager/JobScheduler/AlarmManager/ForegroundService?

有人可以帮助我了解如何实施和理解后台生命周期以及如何访问我需要在后台管理的所有数据吗?

谢谢!

在后台工作的唯一可行解决方案是 ForegroundService,当您的设备进入 Doze 模式时,其他解决方案将被销毁。您可以在 this article 中找到更详细的信息,它描述了扫描 BLE 设备时后台工作的所有障碍。