LoginSignup
1

More than 5 years have passed since last update.

reactive4java で位置を取得し続ける

Last updated at Posted at 2012-09-26

前回に続き、 reactive4java ネタ。
調子に乗って Android で位置を取得し続けるのを reactive4java を使ってやってみた。

LocationFunctions.java
/**
 * 位置を取得し続ける(finish は呼ばれない)
 */
public static Observable<Location> getCurrentLocationAsObservable(          
        final Context context, final String provider) {
    return Reactive.createWithCloseable(new Func1<Observer<? super Location>, Closeable>() {
        private volatile boolean _stop = false;

        @Override
        public Closeable invoke(final Observer<? super Location> observer) {
            final LocationManager locMan = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);

            final LocationListener listener = new LocationListener() {

                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) { }

                @Override
                public void onProviderEnabled(String provider) { }

                @Override
                public void onProviderDisabled(String provider) {
                    observer.error(
                        new InvalidParameterException("LocationProvider disabled."));
                }

                @Override
                public void onLocationChanged(Location location) {
                    if (_stop) {
                        return;
                    }

                    // 発火
                    observer.next(location);
                }
            };

            // 位置取得開始
            locMan.requestLocationUpdates(provider, 0, 0, listener, Looper.getMainLooper());

            return new Closeable() {
                @Override
                public void close() throws IOException {
                    if (_stop) {
                        return;
                    }
                    _stop = true;
                    locMan.removeUpdates(listener);
                    observer.finish();
                }
            };
        }
    });
}

使い方は、方位の時とほとんど同じ。パラメータが Float から Location に代わっただけ。

_stop フラグは、Listener を unregister しても溜まってるデータは流しちゃうんじゃないか、という事で用意した。
方位のやつは AtomicBoolean を使ったけどこっちは volatile でやってる。確かどっかで 'AtomicBoolean の方が確実に Atomic' って言ってた気がするけど、そもそもそんなに神経質になるところじゃないか。

Observable にすることで、「n秒間位置を取得して貯めて、その中で一番精度の良いものを通す」みたいなことも簡単にできる。

Android の場合、購読開始時に registerXXXListener、Close で unregisterXXXEventListener てのがひとつのパターン。
たぶん BroadcastReceiver にも適用できる。

XXXListener も BroadcastReceiver も Observable でラップしちゃえば、その後は同じように扱えるので便利♪

追記 9.27

実はこのプログラム、Cold でしたー。というわけで、Hot についての記事を書きました。
* Cold を Hot にできる。そう、Publish ならね。 - Qiita

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1