2016-11-09 4 views
1

Ich möchte eine Funktion implementieren, bei der ein BLE-Scan für 10 Sekunden aktiviert wird, dann für 10 Sekunden bricht und wiederholt wird, während die Ansicht aktiv ist.Kontinuierliches An- und Abmelden von Observable für BLE-Scans

Ich benutze RxAndroidBle, die die Android BLE APIs für Reaktivität umschließt. Ich habe eine Methode scanForRange(getConnectAddress());, die eine Observable<RxBleScanResult> und einige Filter und eine Karte verwendet, um eine einfache Observable<Integer> zurückgeben. Um den Scan zu starten, muss diese Observable einfach abonniert und dann abbestellt werden, um den Scan zu stoppen.

Mein erster Gedanke war Observable.interval() zu verwenden, wie unten dargestellt:

@Override 
protected void onResume() { 
    super.onResume(); 

    mRangeScanSubscription = Observable.interval(10000, TimeUnit.MILLISECONDS) 
      .flatMap(new Func1<Long, Observable<Integer>>() { 
       @Override 
       public Observable<Integer> call(Long aLong) { 
        return scanForRange(getConnectAddress()); 
       } 
      }) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .doOnError(new Action1<Throwable>() { 
       @Override 
       public void call(Throwable throwable) { 
        Log.d(TAG, "onResume() error"); 
        throwable.printStackTrace(); 
       } 
      }) 
      .subscribe(new Action1<Integer>() { 
       @Override 
       public void call(Integer integer) { 
        Toast.makeText(DeviceDetailActivity.this, "Range: " + integer, Toast.LENGTH_SHORT).show(); 
       } 
      }); 
} 

ich dann von diesem Abonnement in meinem onPause() austragen würde. Jetzt funktioniert das nicht, denn sobald das erste Intervall ausgegeben wird, wird der Scan abonniert und gibt kontinuierlich Ergebnisse aus (anstelle des beabsichtigten Starts/Stopps alle 10 Sekunden).

Was wäre der beste Weg, um diese Funktion dann zu implementieren? Ich nehme an, ich könnte es wahrscheinlich mit einer Mischung aus Observablen und Handlern zusammenhacken, aber das scheint falsch zu sein.

Antwort

2

Sie können dies tun, indem TakeUntil und RepeatWhen Operatoren

 mRangeScanSubscription = scanForRange(getConnectAddress()) 
      .takeUntil(Observable.timer(10, TimeUnit.SECONDS)) //emits items for 10 seconds 
      .repeatWhen(completed -> completed.delay(10, TimeUnit.SECONDS)) //resubscribes after 10 seconds 
      ... 
+0

Das wie erwartet zu funktionieren scheint. Vielen Dank! Ich werde deine Antwort als richtig markieren. – Orbit