diff --git a/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java b/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java index e49cb3c2..a3a8ff25 100644 --- a/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java +++ b/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java @@ -154,6 +154,7 @@ public void onReceive(Context context, Intent intent) { mDelegate.onLocationChanged(location); return; } + case LocationService.MSG_ON_STATIONARY: { logger.debug("Received MSG_ON_STATIONARY"); bundle.setClassLoader(LocationService.class.getClassLoader()); @@ -162,6 +163,7 @@ public void onReceive(Context context, Intent intent) { mDelegate.onStationaryChanged(location); return; } + case LocationService.MSG_ON_ACTIVITY: { logger.debug("Received MSG_ON_ACTIVITY"); bundle.setClassLoader(LocationService.class.getClassLoader()); @@ -169,6 +171,7 @@ public void onReceive(Context context, Intent intent) { mDelegate.onActitivyChanged(activity); return; } + case LocationService.MSG_ON_ERROR: { logger.debug("Received MSG_ON_ERROR"); Bundle errorBundle = bundle.getBundle("payload"); @@ -177,16 +180,34 @@ public void onReceive(Context context, Intent intent) { mDelegate.onError(new PluginException(errorMessage, errorCode)); return; } + case LocationService.MSG_ON_SERVICE_STARTED: { logger.debug("Received MSG_ON_SERVICE_STARTED"); mDelegate.onServiceStatusChanged(LocationService.SERVICE_STARTED); return; } + case LocationService.MSG_ON_SERVICE_STOPPED: { logger.debug("Received MSG_ON_SERVICE_STOPPED"); mDelegate.onServiceStatusChanged(LocationService.SERVICE_STOPPED); return; } + + case LocationService.MSG_ON_ABORT_REQUESTED: { + logger.debug("Received MSG_ON_ABORT_REQUESTED"); + + if (mDelegate != null) { + // We have a delegate, tell it that there's a request. + // It will decide whether to stop or not. + mDelegate.onAbortRequested(); + } else { + // No delegate, we may be running in the background. + // Let's just stop. + stop(); + } + + return; + } } } }; diff --git a/src/main/java/com/marianhello/bgloc/LocationService.java b/src/main/java/com/marianhello/bgloc/LocationService.java index 173cd282..fd522f7e 100644 --- a/src/main/java/com/marianhello/bgloc/LocationService.java +++ b/src/main/java/com/marianhello/bgloc/LocationService.java @@ -92,6 +92,8 @@ public class LocationService extends Service implements ProviderDelegate { public static final int MSG_ON_SERVICE_STARTED = 105; + public static final int MSG_ON_ABORT_REQUESTED = 106; + public static final int SERVICE_STOPPED = 0; public static final int SERVICE_STARTED = 1; @@ -189,7 +191,12 @@ public void onCreate() { mResolver = ResourceResolver.newInstance(this); mLocationDAO = (DAOFactory.createLocationDAO(this)); - mPostLocationTask = new PostLocationTask(mLocationDAO); + mPostLocationTask = new PostLocationTask(mLocationDAO, new PostLocationTaskListener() { + @Override + public void onRequestedAbortUpdates() { + handleRequestedAbortUpdates(); + } + }); mSyncAccount = AccountHelper.CreateSyncAccount(this, SyncService.ACCOUNT_NAME, mResolver.getString(SyncService.ACCOUNT_TYPE_RESOURCE)); @@ -538,10 +545,12 @@ LocationService getService() { private class PostLocationTask { private final ExecutorService mExecutor; private final LocationDAO mLocationDAO; + private final PostLocationTaskListener mListener; - public PostLocationTask(LocationDAO dao) { + public PostLocationTask(LocationDAO dao, PostLocationTaskListener listener) { mLocationDAO = dao; mExecutor = Executors.newSingleThreadExecutor(); + mListener = listener; } public void shutdown() { @@ -612,7 +621,17 @@ private boolean postLocation(BackgroundLocation location) { return false; } - if (responseCode != HttpURLConnection.HTTP_OK && responseCode != HttpURLConnection.HTTP_CREATED) { + if (responseCode == 285) { + // Okay, but we don't need to continue sending these + + logger.debug("Location was sent to the server, and received an \"HTTP 285 Updates Not Required\""); + + if (mListener != null) + mListener.onRequestedAbortUpdates(); + } + + // All 2xx statuses are okay + if (responseCode >= 200 && responseCode < 300) { logger.warn("Server error while posting locations responseCode: {}", responseCode); return false; } @@ -621,6 +640,12 @@ private boolean postLocation(BackgroundLocation location) { } } + public void handleRequestedAbortUpdates() { + Bundle bundle = new Bundle(); + bundle.putInt("action", MSG_ON_ABORT_REQUESTED); + broadcastMessage(bundle); + } + /** * Broadcast receiver which detects connectivity change condition */ @@ -674,4 +699,9 @@ public interface ILocationTransform @Nullable BackgroundLocation transformLocationBeforeCommit(@NonNull Context context, @NonNull BackgroundLocation location); } + + public interface PostLocationTaskListener + { + void onRequestedAbortUpdates(); + } } diff --git a/src/main/java/com/marianhello/bgloc/PluginDelegate.java b/src/main/java/com/marianhello/bgloc/PluginDelegate.java index 9bbbb266..5511be7a 100644 --- a/src/main/java/com/marianhello/bgloc/PluginDelegate.java +++ b/src/main/java/com/marianhello/bgloc/PluginDelegate.java @@ -13,5 +13,6 @@ public interface PluginDelegate { void onStationaryChanged(BackgroundLocation location); void onActitivyChanged(BackgroundActivity activity); void onServiceStatusChanged(int status); + void onAbortRequested(); void onError(PluginException error); } diff --git a/src/oreo/java/com/marianhello/bgloc/sync/SyncAdapter.java b/src/oreo/java/com/marianhello/bgloc/sync/SyncAdapter.java index b9ab08b2..17ce4e5e 100644 --- a/src/oreo/java/com/marianhello/bgloc/sync/SyncAdapter.java +++ b/src/oreo/java/com/marianhello/bgloc/sync/SyncAdapter.java @@ -6,14 +6,17 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; import android.content.SyncResult; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.support.v4.app.NotificationCompat; +import android.support.v4.content.LocalBroadcastManager; import com.marianhello.bgloc.Config; import com.marianhello.bgloc.HttpPostService; +import com.marianhello.bgloc.LocationService; import com.marianhello.bgloc.NotificationHelper; import com.marianhello.bgloc.UploadingCallback; import com.marianhello.bgloc.data.ConfigurationDAO; @@ -24,7 +27,6 @@ import java.io.File; import java.io.IOException; -import java.net.HttpURLConnection; import java.util.HashMap; /** @@ -146,13 +148,27 @@ private boolean uploadLocations(File file, String url, HashMap httpHeaders) { try { int responseCode = HttpPostService.postFile(url, file, httpHeaders, this); - if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) { + + // All 2xx statuses are okay + boolean isStatusOkay = responseCode >= 200 && responseCode < 300; + + if (responseCode == 285) { + // Okay, but we don't need to continue sending these + + logger.debug("Location was sent to the server, and received an \"HTTP 285 Updates Not Required\""); + + Bundle bundle = new Bundle(); + bundle.putInt("action", LocationService.MSG_ON_ABORT_REQUESTED); + broadcastMessage(bundle); + } + + if (isStatusOkay) { builder.setContentText("Sync completed"); } else { builder.setContentText("Sync failed due server error"); } - return responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED; + return isStatusOkay; } catch (IOException e) { logger.warn("Error uploading locations: {}", e.getMessage()); builder.setContentText("Sync failed: " + e.getMessage()); @@ -187,4 +203,10 @@ public void uploadListener(int progress) { builder.setProgress(100, progress, false); notificationManager.notify(NOTIFICATION_ID, builder.build()); } + + private void broadcastMessage(Bundle bundle) { + Intent intent = new Intent(LocationService.ACTION_BROADCAST); + intent.putExtras(bundle); + LocalBroadcastManager.getInstance(getContext().getApplicationContext()).sendBroadcast(intent); + } } diff --git a/src/preoreo/java/com/marianhello/bgloc/sync/SyncAdapter.java b/src/preoreo/java/com/marianhello/bgloc/sync/SyncAdapter.java index ed9d0702..295801e5 100644 --- a/src/preoreo/java/com/marianhello/bgloc/sync/SyncAdapter.java +++ b/src/preoreo/java/com/marianhello/bgloc/sync/SyncAdapter.java @@ -6,14 +6,17 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; import android.content.SyncResult; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.support.v4.app.NotificationCompat; +import android.support.v4.content.LocalBroadcastManager; import com.marianhello.bgloc.Config; import com.marianhello.bgloc.HttpPostService; +import com.marianhello.bgloc.LocationService; import com.marianhello.bgloc.NotificationHelper; import com.marianhello.bgloc.UploadingCallback; import com.marianhello.bgloc.data.ConfigurationDAO; @@ -146,13 +149,27 @@ private boolean uploadLocations(File file, String url, HashMap httpHeaders) { try { int responseCode = HttpPostService.postFile(url, file, httpHeaders, this); - if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) { + + // All 2xx statuses are okay + boolean isStatusOkay = responseCode >= 200 && responseCode < 300; + + if (responseCode == 285) { + // Okay, but we don't need to continue sending these + + logger.debug("Location was sent to the server, and received an \"HTTP 285 Updates Not Required\""); + + Bundle bundle = new Bundle(); + bundle.putInt("action", LocationService.MSG_ON_ABORT_REQUESTED); + broadcastMessage(bundle); + } + + if (isStatusOkay) { builder.setContentText("Sync completed"); } else { builder.setContentText("Sync failed due server error"); } - return responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED; + return isStatusOkay; } catch (IOException e) { logger.warn("Error uploading locations: {}", e.getMessage()); builder.setContentText("Sync failed: " + e.getMessage()); @@ -187,4 +204,10 @@ public void uploadListener(int progress) { builder.setProgress(100, progress, false); notificationManager.notify(NOTIFICATION_ID, builder.build()); } + + private void broadcastMessage(Bundle bundle) { + Intent intent = new Intent(LocationService.ACTION_BROADCAST); + intent.putExtras(bundle); + LocalBroadcastManager.getInstance(getContext().getApplicationContext()).sendBroadcast(intent); + } }