如何等待requestLocationupdates()回调意图完成



我想等待fusedlocationproviderclient.requestlocationupdates()中的回调意图完成。与超时的暂停循环是最好的解决方案吗?以下是一个示例,没有超时。

通常,我会使用startwakefulservice()等待异步服务完成,但是我不知道一种与requestLocationupdates()一起使用它的方法。

Task t = flpc.requestLocationUpdates(locationRequest, pe);
while (! t.isSuccessful()) {
    Log.v(TAG, "Waiting for result...");
}

如果您熟悉rxjava/rxandroid稍微熟悉您可以将方法调用包装在可观察的可观察(或callable,单身,无论您看到的最好),请在另一个线程上运行它比用户界

在代码中看起来像这样:

Observable.fromCallable(() -> flpc.requestLocationUpdates(locationRequest, pe))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(task -> onLocationUpdatesSuccess(task), throwable -> Log.e(TAG, throwable.getMessage()));

否则,另一个解决方案是将您的方法包裹在异步中,例如,您最终会得到类似的东西:

    new AsyncTask<Void, Void, Task>() {
            @Override
            protected Task doInBackground(Void... params) {
                return flpc.requestLocationUpdates(locationRequest, pe);
            }
            @Override
            protected void onPostExecute(Task task) {
                onLocationUpdatesSuccess(task)
            }
    }.execute();

这是我最终做的:

使用手动Wakelock。在您的班级中声明静态Wakelock变量。还定义了两种方法:Acceaire()和Release()。

aceaceire()实例化Wakelock并将其分配为类中的静态Wakelock变量。这是一种实例方法(不是静态),因为它使用需要上下文的PowerManager。

RELAYE()是一种静态方法,因此其他类可以调用它。它释放了Wakelock。我使用了一个带有wakelock柜台的单身人士Wakelock,在称呼时减少柜台,然后在计数器为零时释放Wakelock。但是柜台是完全可选的。

所有这些的"技巧"是创建一个实例Wakelock并将其分配给静态变量。这使Wakelock可以在服务中修改,该服务无法访问我的班级实例。

而不是从班级外部调用饰面(),而是使用task.oncompletelistener()来调用finish()。requestLocationupdates()返回任务对象。

这是我仅获得1个位置的解决方案:

private fun getNewLocation(): Single<Location> =
    Single.create { emitter ->
        locationClient.requestLocationUpdates(locationRequest, object : LocationCallback() {
            override fun onLocationResult(result: LocationResult) {
                locationClient.removeLocationUpdates(this)
                val location = result.locations.firstOrNull()
                if (location != null) {
                    emitter.onSuccess(location)
                } else {
                    emitter.onError(NullPointerException("Null location"))
                }
            }
            override fun onLocationAvailability(result: LocationAvailability) {
                if (!result.isLocationAvailable) {
                    locationClient.removeLocationUpdates(this)
                    emitter.onError(IllegalStateException("Location not available"))
                }
            }
        }, Looper.getMainLooper())
    }

locationRequest看起来像:

private val locationRequest =
    LocationRequest()
        .setExpirationDuration(TimeUnit.SECONDS.toMillis(30L))
        .setInterval(TimeUnit.SECONDS.toMillis(15L))
        .setNumUpdates(1)

最新更新