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

```java LocationFunctions.java
/**

  • 位置を取得し続ける(finish は呼ばれない)
    */
    public static Observable 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 についての記事を書きました。

##参考

Android
reactive4java
Java
ReactiveExtensions

published

Ads

Read more!

amay077

Microsoft MVP(Xamarin). フルリモートワーカー. Geospatial Mobile app developer. Love C#.

amay077 amay077