【问题标题】:Why is LocationCallback not firing within CallbackToFutureAdapter?为什么 LocationCallback 没有在 CallbackToFutureAdapter 中触发?
【发布时间】:2020-04-17 10:22:48
【问题描述】:

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

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

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

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

这是我在 MyWorker 扩展 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");

                    }
                })

相关帖子: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】:

    所以,经过数小时的反复试验,这是最终对我有用的解决方案:

    诀窍是添加一个前台服务,以确保工作人员不会被取消,直到系统有新的位置更新到达。 但是,您无法避免在该时间范围内显示通知。 我还将 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";
            });
        }
    

    【讨论】:

      猜你喜欢
      • 2021-08-05
      • 2016-06-19
      • 2021-05-23
      • 2021-06-21
      • 2019-02-19
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多