Created
October 2, 2015 19:52
-
-
Save beaucollins/05d32b40f87233a47e92 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.automattic.geopit; | |
| import android.app.Activity; | |
| import android.app.Application; | |
| import android.app.Service; | |
| import android.content.Context; | |
| import android.content.Intent; | |
| import android.os.Bundle; | |
| import android.os.IBinder; | |
| import android.os.RemoteException; | |
| import android.util.Log; | |
| import com.automattic.geopit.api.GeopitService; | |
| import com.estimote.sdk.Beacon; | |
| import com.estimote.sdk.BeaconManager; | |
| import com.estimote.sdk.Region; | |
| import javax.inject.Inject; | |
| import rx.Observable; | |
| import rx.android.schedulers.AndroidSchedulers; | |
| import rx.schedulers.Schedulers; | |
| public class RangingService extends Service { | |
| protected static final String TAG = "RangingService"; | |
| private static final Region REGION = new Region("region", null, null, null); | |
| private static final String STARTED_FROM_APP_EXTRA = "started_in_app"; | |
| @Inject public BeaconManager beaconManager; | |
| protected GeopitService service = GeopitService.Client.createService(); | |
| protected CheckinThrottle throttle = new CheckinThrottle(); | |
| protected DisplayIntentBuilder displayIntentBuilder; | |
| protected CheckinBroadcaster checkinBroadcaster; | |
| protected CheckinNotificationBuilder checkinNotificationBuilder; | |
| protected NotificationDisplay notificationDisplay; | |
| private int startCount = 0; | |
| public RangingService() { | |
| } | |
| @Override | |
| public void onCreate() { | |
| super.onCreate(); | |
| Injector.obtain(getApplicationContext()).inject(this); | |
| getApplication().registerActivityLifecycleCallbacks(lifecycleObserver); | |
| displayIntentBuilder = new DisplayIntentBuilder(this); | |
| checkinBroadcaster = new CheckinBroadcaster(this); | |
| checkinNotificationBuilder = new CheckinNotificationBuilder(this); | |
| notificationDisplay = new NotificationDisplay(this); | |
| beaconManager.setRangingListener((region, list) -> { | |
| if (list.size() <= 0) return; | |
| Beacon nearest = list.get(0); | |
| if (nearest == null) return; | |
| checkin(nearest); | |
| }); | |
| if (BuildConfig.DEBUG) { | |
| Log.d(TAG, "Start ranging"); | |
| } | |
| beaconManager.connect(() -> { | |
| try { | |
| beaconManager.startRanging(REGION); | |
| } catch (RemoteException e) { | |
| Log.d(TAG, "Failed to start ranging ", e); | |
| } | |
| }); | |
| } | |
| @Override | |
| public int onStartCommand(Intent intent, int flags, int startId) { | |
| if (BuildConfig.DEBUG) Log.d(TAG, "Received start " + startId + ": " + intent); | |
| if (intent.getBooleanExtra(STARTED_FROM_APP_EXTRA, false)) { | |
| startCount += 1; | |
| } | |
| // TODO: Determine if we were started from the app or from being booted | |
| return START_NOT_STICKY; | |
| } | |
| @Override | |
| public void onDestroy() { | |
| if (BuildConfig.DEBUG) | |
| Log.d(TAG, "Killing ranging service"); | |
| try { | |
| beaconManager.stopRanging(REGION); | |
| } catch (RemoteException e) { | |
| Log.e(TAG, "stopRanging failed", e); | |
| } | |
| beaconManager.disconnect(); | |
| } | |
| @Override | |
| public IBinder onBind(Intent intent) { | |
| // TODO: Return the communication channel to the service. | |
| throw new UnsupportedOperationException("Not implemented"); | |
| } | |
| void checkin(Beacon beacon) { | |
| final Context context = getApplicationContext(); | |
| // Attempt to request a checkin | |
| Observable.just(beacon) | |
| .skipWhile(throttle) | |
| .flatMap(b -> service.checkin(Geopit.getDeviceId(context), b.getProximityUUID())) | |
| .subscribeOn(Schedulers.io()) | |
| .observeOn(AndroidSchedulers.mainThread()) | |
| .subscribe(this::onCheckin, error -> Log.d(TAG, "Failed to check in", error)); | |
| } | |
| private void onCheckin(GeopitService.CheckinStatus checkinStatus) { | |
| // Broadcasts an Intent via LocalBroadcastManager for the app to respond to while open | |
| Observable.just(checkinStatus) | |
| .map(displayIntentBuilder) | |
| .subscribe(checkinBroadcaster); | |
| if (BuildConfig.DEBUG) { | |
| Log.d(TAG, "Checkin with action: " + checkinStatus.checkin.action); | |
| Log.d(TAG, "Activity count: " + startCount); | |
| } | |
| // Builds and displays a notification | |
| Observable.just(checkinStatus) | |
| .filter(status -> startCount <= 0) | |
| .filter(status -> status.checkin.action != null) | |
| .map(checkinNotificationBuilder) | |
| .subscribe(notificationDisplay); | |
| } | |
| private Application.ActivityLifecycleCallbacks lifecycleObserver = new Application.ActivityLifecycleCallbacks() { | |
| @Override | |
| public void onActivityCreated(Activity activity, Bundle savedInstanceState) { | |
| } | |
| @Override | |
| public void onActivityStarted(Activity activity) { | |
| // started | |
| startCount += 1; | |
| } | |
| @Override | |
| public void onActivityResumed(Activity activity) { | |
| } | |
| @Override | |
| public void onActivityPaused(Activity activity) { | |
| } | |
| @Override | |
| public void onActivityStopped(Activity activity) { | |
| startCount -= 1; | |
| } | |
| @Override | |
| public void onActivitySaveInstanceState(Activity activity, Bundle outState) { | |
| } | |
| @Override | |
| public void onActivityDestroyed(Activity activity) { | |
| } | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment