gpt4 book ai didi

Android WorkManager : how to handle ongoing work, 喜欢蓝牙扫描

转载 作者:行者123 更新时间:2023-11-29 14:43:16 25 4
gpt4 key购买 nike

随着最近对background Services的限制和 implicit Broadcasts , Android 开发者留下 JobScheduler ,并且在更高层次上,WorkManager安排后台任务。

WorkManager 的 Worker 类非常简单,但我对实现持续工作而不是一次性工作的最佳方式感到有点困惑。对于我们的示例,让我们考虑蓝牙低功耗扫描,但同样的问题适用于所有正在进行的、不确定的工作。

这样的事情显然行不通:

public class MyWorker extends Worker {

private BluetoothLeScanner mBluetoothLeScanner;

@Override
public Worker.Result doWork() {
mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();

// Pretend there's some bluetooth setup here
// ...

mBluetoothLeScanner.startScan( .. , .. , .. );
return Result.SUCCESS;
}

}

上面我们开始扫描,然后立即超出范围,所以扫描不会继续。

我们可以使用 wait()/notify() 来解决这个问题,但感觉很脏。像这样的……

public class MyWorker extends Worker {

private BluetoothLeScanner mBluetoothLeScanner;
private final Object mLock = new Object();
private Handler mBackgroundHandler;

private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread thread = new HandlerThread("background");
thread.start();
mBackgroundHandler = new Handler(thread.getLooper());
}
return mBackgroundHandler;
}

@Override
public Worker.Result doWork() {
getBackgroundHandler().post(new Runnable() {
@Override
public void run() {
mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
// Pretend there's some bluetooth setup here
// ...
mBluetoothLeScanner.startScan( .. , .. , mScanCallback);
}
});

getBackgroundHandler().postDelayed(new Runnable() {
@Override
public void run() {
mBluetoothLeScanner.stopScan(mScanCallback);
synchronized (mLock) {
mLock.notify();
}
}
}, 60 * 1000); //stop after a minute

try {
synchronized (mLock) {
mLock.wait();
}
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}

return Result.SUCCESS;
}

private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
//We found an advertisement
mBluetoothLeScanner.stopScan(mScanCallback);
synchronized (mLock) {
mLock.notify();
}
}

@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
}

@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
mBluetoothLeScanner.stopScan(mScanCallback);
synchronized (mLock) {
mLock.notify();
}
}
};

@Override
public void onStopped(boolean cancelled) {
if (mBackgroundHandler != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBackgroundHandler.getLooper().quitSafely();
} else {
mBackgroundHandler.getLooper().quit();
}
mBackgroundHandler = null;
}
}
}

TLDR:在现代(8.1+)Android 中实现持续后台工作的最佳方式是什么?鉴于 Worker/WorkManager 的架构,这种持续后台工作似乎确实是被谷歌扼杀。 Worker 中的 wait()/notify() 模式是否可以接受,或者此解决方法是否会被系统终止?

如有任何提示,我们将不胜感激。

编辑:

我希望避免使用前台服务 + 持续通知。答案here看起来很有希望,但它显然已在 Android 7.1 中进行了修补。在我运行 Android 9 的手机上,我的无线 BLE 耳机从耳机盒中取出后几乎立即连接。耳机供应商未运行前台服务(至少不可见——没有持续通知)来检测广告。我不知道他们是如何做到如此可靠的。

最佳答案

WorkManager 不适合连续工作 - 这将是前台服务的用例。

但是,随着 BluetoothLeScanner.startScan(List<ScanFilter>, ScanSettings, PendingIntent) 的引入,BLE 扫描不需要您的应用程序在 API 26+ 设备上持续运行。方法,它允许您注册 PendingIntent作为回调,仅在扫描结果可用时启动您的应用。

对于以前版本的 Android,您需要一个持续运行的服务来维持主动扫描。

关于Android WorkManager : how to handle ongoing work, 喜欢蓝牙扫描,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52104571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com