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

时间:2017-09-20 03:59:01

标签: java android asynchronous android-fusedlocation

我想等待FusedLocationProviderClient.requestLocationUpdates()中的回调意图完成。具有超时的while循环是最佳解决方案吗?下面是一个例子,没有超时。

通常我会使用startWakefulService()等待异步服务完成,但我不知道如何将它与requestLocationUpdates()一起使用。

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

3 个答案:

答案 0 :(得分:1)

如果您熟悉RxJava / RxAndroid,可以将方法调用包装在一个Observable中(或者Callable,Single,无论你看到什么最好),在UI之外的另一个线程上运行它然后一次你有从你的方法得到的结果,你在主线程上收到它,并用它做你想做的任何事情。

在代码中它看起来像这样:

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

否则,另一个解决方案是将您的方法包装在AsyncTask中,例如,您最终得到的结果如下:

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

答案 1 :(得分:0)

这是我最终做的事情:

使用手动唤醒锁。在类中声明一个静态wakelock变量。还定义了两个方法:acquire()和release()。

acquire()实例化一个唤醒锁并在类中为其指定静态wakelock变量。它是一个实例方法(非静态),因为它使用需要上下文的PowerManager。

release()是一种静态方法,因此其他类可以调用它。它释放了唤醒锁。我使用带有唤醒锁计数器的单独唤醒锁,在调用此计数器时递减计数器,并在计数器为零时释放唤醒锁。但柜台是完全可选的。

&#34;技巧&#34;所有这一切都是创建一个实例唤醒锁并将其分配给静态变量。这允许在无法访问我的类实例的服务中修改唤醒锁。

不是从类外部调用finish(),而是使用Task.OnCompleteListener()来调用finish()。 requestLocationUpdates()返回一个Task对象。

答案 2 :(得分:0)

这是我仅获得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)