io.taig.android.monix.ActivityRecognition.scala Maven / Gradle / Ivy
package io.taig.android.monix
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.{ Context, Intent, IntentFilter }
import com.google.android.gms.location.ActivityRecognition.ActivityRecognitionApi
import com.google.android.gms.location.ActivityRecognitionResult
import io.taig.android.app.broadcast.Receiver
import io.taig.android.log.Log
import io.taig.android.monix.syntax.task._
import monix.eval.Task
import monix.execution.Ack.Stop
import monix.execution.Cancelable
import monix.reactive.observers.Subscriber
import scala.concurrent.duration._
object ActivityRecognition {
def unsubscribe( client: GoogleApiClient, intent: PendingIntent )(
implicit
t: Log.Tag
): Unit =
if ( client.isConnected ) {
Log.d( "Unsubscribing from activity recognition updates" )
ActivityRecognitionApi.removeActivityUpdates( client, intent )
}
class ActivityUpdate(
subscriber: Subscriber.Sync[ActivityRecognitionResult],
client: GoogleApiClient,
pending: PendingIntent
)(
implicit
t: Log.Tag
) extends Receiver {
override def onReceive( intent: Intent )(
implicit
c: Context
): Unit = {
val result = ActivityRecognitionResult.extractResult( intent )
Log.d( s"Received activity recognition update: $result" )
if ( subscriber.onNext( result ) == Stop ) {
unsubscribe( client, pending )
}
}
}
def apply(
client: GoogleApiClient,
interval: FiniteDuration,
subscriber: Subscriber.Sync[ActivityRecognitionResult]
)(
implicit
c: Context,
t: Log.Tag
): Cancelable = {
import subscriber.scheduler
val id = "io.taig.android.monix.ActivityUpdate"
val intent = PendingIntent.getBroadcast(
c,
8437,
new Intent( id ),
FLAG_UPDATE_CURRENT
)
val receiver = new ActivityUpdate( subscriber, client, intent )
val filter = new IntentFilter( id )
c.registerReceiver( receiver, filter )
Log.d( "Subscribing to activity recognition updates" )
val result = ActivityRecognitionApi
.requestActivityUpdates( client, interval.toSeconds, intent )
val cancelable = Task.fromPendingResult( result ).foreach { status ⇒
if ( !status.isSuccess ) {
val message = "Activity recognition updates failed: " +
s"${status.getStatusMessage} (${status.getStatusCode})"
val exception = new IllegalStateException( message )
subscriber.onError( exception )
}
}
Cancelable { () ⇒
cancelable.cancel()
unsubscribe( client, intent )
}
}
}