为什么 LocationCallback 没有在 CallbackToFutureAdapter 中触发?
Why is LocationCallback not firing within CallbackToFutureAdapter?
我需要完成的事情:
我的应用程序应该请求用户的当前位置,每 15 分钟重复一次,也在后台,甚至在应用程序终止时也是如此。
我做了什么:
我正在使用 FusedLocationProviderAPI,在定期的 WorkManager 中调用,扩展 ListenableWorker,因为 API 是异步的。
每次系统提供新的位置更新时(最多每十五分钟一次),都会调用 LocationCallback。
由于似乎不推荐在 ListenableWorker 的 startWork-Method 中使用 ResolvableFuture,因此我使用了 CallbackToFutureAdapter。
在这个适配器中,我初始化了 LocationCallback 并调用了 doWork-Method,它包括请求信息的所有逻辑。
我的问题:
当屏幕处于活动状态时,一切正常。但是一旦应用程序在后台运行或终止,LocationCallback 将不会被调用。(最后一个日志:"Waiting for callback")。请注意,我删除了下面的大部分代码(例如异常处理和详细信息)。
这是我在 MyWorker extends ListenableWorker 中的代码
开始工作方法:
public ListenableFuture<Result> startWork() {
return CallbackToFutureAdapter.getFuture(completer -> {
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
// Storing data to different repositories.
completer.set(Result.success());
}
};
doWork();
return "startSomeAsyncStuff";
});
}
doWork():
public Result doWork() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
mSettingsClient = LocationServices.getSettingsClient(mContext);
createLocationCallback();
createLocationRequest();
buildLocationSettingsRequest();
startLocationUpdates();
return Result.success();
}
startLocationUpdates():
private void startLocationUpdates() {
// Begin by checking if the device has the necessary location settings.
mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "All location settings are satisfied.");
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper());
Log.i(TAG, "Location updated requested - Waiting for Callback");
}
})
相关帖子: and
因此,经过数小时的反复试验,这里是最终适合我的解决方案:
诀窍是添加一个前台服务,确保工作人员不会被取消,直到从系统收到新的位置更新。
但是,您无法避免在该时间范围内显示通知。
我还将 LocationCallback 移动到 doWork-Method 中,就在请求位置更新之前(因为您需要将回调传递给该方法。)
这个解决方案是基于 https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running 的,我应该在一开始就看一看,以免让我有些沮丧;)
这是 startWork() 方法:
public ListenableFuture<Result> startWork() {
return CallbackToFutureAdapter.getFuture(completer -> {
setForegroundAsync(createForegroundInfo());
doWork(completer);
// This value is used only for debug purposes: it will be used
// in toString() of returned future or error cases.
return "Location Worker";
});
}
我需要完成的事情: 我的应用程序应该请求用户的当前位置,每 15 分钟重复一次,也在后台,甚至在应用程序终止时也是如此。
我做了什么: 我正在使用 FusedLocationProviderAPI,在定期的 WorkManager 中调用,扩展 ListenableWorker,因为 API 是异步的。 每次系统提供新的位置更新时(最多每十五分钟一次),都会调用 LocationCallback。
由于似乎不推荐在 ListenableWorker 的 startWork-Method 中使用 ResolvableFuture,因此我使用了 CallbackToFutureAdapter。 在这个适配器中,我初始化了 LocationCallback 并调用了 doWork-Method,它包括请求信息的所有逻辑。
我的问题: 当屏幕处于活动状态时,一切正常。但是一旦应用程序在后台运行或终止,LocationCallback 将不会被调用。(最后一个日志:"Waiting for callback")。请注意,我删除了下面的大部分代码(例如异常处理和详细信息)。
这是我在 MyWorker extends ListenableWorker 中的代码 开始工作方法:
public ListenableFuture<Result> startWork() {
return CallbackToFutureAdapter.getFuture(completer -> {
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
// Storing data to different repositories.
completer.set(Result.success());
}
};
doWork();
return "startSomeAsyncStuff";
});
}
doWork():
public Result doWork() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
mSettingsClient = LocationServices.getSettingsClient(mContext);
createLocationCallback();
createLocationRequest();
buildLocationSettingsRequest();
startLocationUpdates();
return Result.success();
}
startLocationUpdates():
private void startLocationUpdates() {
// Begin by checking if the device has the necessary location settings.
mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "All location settings are satisfied.");
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper());
Log.i(TAG, "Location updated requested - Waiting for Callback");
}
})
相关帖子:
因此,经过数小时的反复试验,这里是最终适合我的解决方案:
诀窍是添加一个前台服务,确保工作人员不会被取消,直到从系统收到新的位置更新。 但是,您无法避免在该时间范围内显示通知。 我还将 LocationCallback 移动到 doWork-Method 中,就在请求位置更新之前(因为您需要将回调传递给该方法。)
这个解决方案是基于 https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running 的,我应该在一开始就看一看,以免让我有些沮丧;)
这是 startWork() 方法:
public ListenableFuture<Result> startWork() {
return CallbackToFutureAdapter.getFuture(completer -> {
setForegroundAsync(createForegroundInfo());
doWork(completer);
// This value is used only for debug purposes: it will be used
// in toString() of returned future or error cases.
return "Location Worker";
});
}