为什么在CallbackToFutureAdapter中不触发LocationCallback?

问题描述 投票:0回答:1

我需要完成的工作:我的应用程序应该请求用户的当前位置,每15分钟重复一次,即使在后台,甚至在应用程序终止时也要重复一次。

我做了什么:我正在使用在定期WorkManager中调用的FusedLocationProviderAPI,扩展了ListenableWorker,因为该API是异步的。每次系统提供新的位置更新(最多每十五分钟)一次,就会调用LocationCallback。

由于ResolvableFuture似乎不建议在ListenableWorker的startWork-Method中使用,因此我使用CallbackToFutureAdapter。在此适配器中,我初始化LocationCallback并调用doWork-Method,该方法包括用于请求信息的所有逻辑。

我的问题:当屏幕处于活动状态时,一切正常。但是一旦应用程序在后台运行或被终止,LocationCallback不会被触发。(最后一个日志:“等待回调”)。请注意,我在下面删除了大量代码(例如异常处理和详细信息)。

这是我在MyWorker中的代码扩展了ListenableWorkerstartWork-Method:

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");

                    }
                })

[相关文章:How do I return a ListenableFuture<Result> with work manager 2.0?WorkManager: ResolvableFuture can only be called from within the same library group prefix

android future android-workmanager fusedlocationproviderapi
1个回答
0
投票

因此,经过数小时的反复试验,这是最终适用于我的解决方案:

技巧是添加一个前台服务,以确保在从系统收到新的位置更新之前,不取消该工作人员。但是,您无法避免在该时间段内显示通知。在请求位置更新之前,我还将LocationCallback移到了doWork-Method中(因为您需要将Callback传递给该方法。)

此解决方案基于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";
        });
    }
© www.soinside.com 2019 - 2024. All rights reserved.