Skip to content

Commit

Permalink
Merge pull request #171 from shankari/implement_runtime_permissions
Browse files Browse the repository at this point in the history
Minor fixes to location tracking with api 26
  • Loading branch information
shankari authored Mar 19, 2019
2 parents 166ae87 + a9abd31 commit 856258f
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 37 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "e-mission-data-collection",
"version": "1.0.5",
"version": "1.3.1",
"description": "Simple package that stores all the connection settings that need to be configured",
"cordova": {
"id": "e-mission-data-collection",
Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
id="edu.berkeley.eecs.emission.cordova.datacollection"
version="1.3.0">
version="1.3.1">

<name>DataCollection</name>
<description>Background data collection FTW! This is the part that I really
Expand Down
14 changes: 14 additions & 0 deletions src/android/location/ActivityRecognitionChangeIntentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ public ActivityRecognitionChangeIntentService() {

private static final String TAG = "ActivityRecognitionChangeIntentService";

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(this, TAG, "onStartCommand called with intent "+intent+" flags "+flags+" startId "+startId);
TripDiaryStateMachineForegroundService.handleStart(this, "Handling geofence event", intent, flags, startId);
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
Log.d(this, TAG, "onDestroy called");
TripDiaryStateMachineForegroundService.handleDestroy(this);
super.onDestroy();
}

@Override
protected void onHandleIntent(Intent intent) {
Log.d(this, TAG, "FINALLY! Got activity update, intent is "+intent);
Expand Down
14 changes: 13 additions & 1 deletion src/android/location/GeofenceExitIntentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,17 @@ public void onStart(Intent i, int startId) {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(this, TAG, "onStartCommand called with intent "+intent+" flags "+flags+" startId "+startId);
TripDiaryStateMachineForegroundService.handleStart(this, "Handling geofence event", intent, flags, startId);
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
Log.d(this, TAG, "onDestroy called");
TripDiaryStateMachineForegroundService.handleDestroy(this);
super.onDestroy();
}

@Override
protected void onHandleIntent(Intent intent) {
/*
Expand Down Expand Up @@ -67,11 +75,15 @@ protected void onHandleIntent(Intent intent) {
// https://github.com/e-mission/e-mission-data-collection/issues/128#issuecomment-250304943
if (parsedEvent.hasError()) {
Log.i(this, TAG, "Found error "+parsedEvent.getErrorCode()+
"will be handled by MODE_CHANGE transition");
" generating tracking error");
sendBroadcast(new ExplicitIntent(this, R.string.transition_tracking_error));
} else {
Log.i(this, TAG, "Got event with transition = "+parsedEvent.getGeofenceTransition()+
" but hasError = false, ignoring");
}
} else {
Log.w(this, TAG, "Got geofencing event with unknown transition "+
parsedEvent.getGeofenceTransition() + " ignoring...");
}
}
}
13 changes: 11 additions & 2 deletions src/android/location/LocationChangeIntentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import edu.berkeley.eecs.emission.cordova.tracker.Constants;
import edu.berkeley.eecs.emission.R;


import edu.berkeley.eecs.emission.cordova.tracker.ExplicitIntent;
import edu.berkeley.eecs.emission.cordova.tracker.sensors.PollSensorManager;
import android.app.IntentService;
Expand Down Expand Up @@ -41,9 +42,17 @@ public void onCreate() {
}

@Override
public void onStart(Intent i, int startId) {
public int onStartCommand(Intent i, int flags, int startId) {
Log.d(this, TAG, "onStart called with "+i+" startId "+startId);
super.onStart(i, startId);
TripDiaryStateMachineForegroundService.handleStart(this, "Handling geofence event", i, flags, startId);
return super.onStartCommand(i, flags, startId);
}

@Override
public void onDestroy() {
Log.d(this, TAG, "onDestroy called");
TripDiaryStateMachineForegroundService.handleDestroy(this);
super.onDestroy();
}

@Override
Expand Down
56 changes: 41 additions & 15 deletions src/android/location/TripDiaryStateMachineForegroundService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import de.appplant.cordova.plugin.notification.ClickActivity;
import edu.berkeley.eecs.emission.MainActivity;


import edu.berkeley.eecs.emission.cordova.unifiedlogger.Log;
import edu.berkeley.eecs.emission.cordova.unifiedlogger.NotificationHelper;

Expand All @@ -35,39 +36,64 @@ public IBinder onBind(Intent intent) {
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(this, TAG, "onStartCommand called with flags = " + flags +
" and startId = " + startId);
handleStart(this, "background trip tracking started", intent, flags, startId);

// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}

public static void handleStart(Service srv, String msg, Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.d(this, TAG, "onStartCommand called on oreo+, starting foreground service");
Log.d(srv, TAG, "onStartCommand called on oreo+, starting foreground service");
// Go to the foreground with a dummy notification
NotificationManager nMgr = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = NotificationHelper.getNotificationBuilderForApp(this,
nMgr, "background trip tracking started");
NotificationManager nMgr = (NotificationManager)srv.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = NotificationHelper.getNotificationBuilderForApp(srv,
nMgr, msg);
builder.setOngoing(true);

Intent activityIntent = new Intent(this, MainActivity.class);
Intent activityIntent = new Intent(srv, MainActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
PendingIntent activityPendingIntent = PendingIntent.getActivity(srv, 0,
activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(activityPendingIntent);


int ONGOING_TRIP_ID = 6646464;
startForeground(ONGOING_TRIP_ID, builder.build());
srv.startForeground(ONGOING_TRIP_ID, builder.build());
} else {
Log.d(this, TAG, "onStartCommand called on pre-oreo, ignoring");
Log.d(srv, TAG, "onStartCommand called on pre-oreo, ignoring");
}

// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}

@Override
public void onDestroy() {
handleDestroy(this);
}

public static void handleDestroy(Service srv) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.d(srv, TAG, "onDestroy called, removing notification");
srv.stopForeground(true);
} else {
Log.d(srv, TAG, "onDestroy called on pre-oreo, ignoring");
}
}

/*
Returns the correct pending intent to be passed to invoke a background service
when the app is in the background (which is almost 100% of the time in our case.
We need to use getService for pre-Oreo and getForegroundService for O+.
There are 4 usages of this pattern, so it is probably worth pulling out into a static function.
When we ever move the minAPI up to 26, we can move this back inline.
*/

public static PendingIntent getProperPendingIntent(Context ctxt, Intent innerIntent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.d(this, TAG, "onDestroy called, removing notification");
stopForeground(true);
return PendingIntent.getForegroundService(ctxt, 0, innerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
} else {
Log.d(this, TAG, "onDestroy called on pre-oreo, ignoring");
return PendingIntent.getService(ctxt, 0, innerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
}
9 changes: 9 additions & 0 deletions src/android/location/TripDiaryStateMachineReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.LocationManager;
import android.os.Build;
import android.preference.PreferenceManager;

import com.google.android.gms.common.api.GoogleApiClient;
Expand Down Expand Up @@ -115,19 +116,27 @@ public void onReceive(Context context, Intent intent) {
// we should only get here if the user has consented
Intent serviceStartIntent = getStateMachineServiceIntent(context);
serviceStartIntent.setAction(intent.getAction());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.i(context, TAG, "build is O+, using startForegroundService");
context.startForegroundService(serviceStartIntent);
} else {
Log.i(context, TAG, "build is < 0, using startService");
context.startService(serviceStartIntent);
}
}

public static void performPeriodicActivity(Context ctxt) {
/*
* Now, do some validation of the current state and clean it up if necessary. This should
* help with issues we have seen in the field where location updates pause mysteriously, or
* geofences are never exited.
*/
Log.i(ctxt, TAG, "START PERIODIC ACTIVITY");
checkLocationStillAvailable(ctxt);
validateAndCleanupState(ctxt);
initOnUpgrade(ctxt);
saveBatteryAndSimulateUser(ctxt);
Log.i(ctxt, TAG, "END PERIODIC ACTIVITY");
}

public static void checkLocationStillAvailable(Context ctxt) {
Expand Down
Loading

0 comments on commit 856258f

Please sign in to comment.