Update location based on device status

I need to get the location (via the fusedlocation API) of the user after ActivityRecognition Define the user state (which is called every 3 minutes), for example IN_VEHICLE, ON_FOOT, RUNNING, etc.

In each case, I need the user's location after a regular interval For example:

if the user is still setInterval(5*60*60*1000); and checks the next update location no earlier than 5 hours. But ActivityRecognation will ring every 3 minutes.

if the user ran setInterval(2*60*1000); , and check the next location update no earlier / after 2 minutes. But ActivityRecognation will ring every 3 minutes.

if the user is running, then send the location every 1 min. if the user drives, then send the location every 15 minutes.

I tried setting boolean false in onConnected to false and true at the class level. But this always becomes true, because after 3 minutes the whole Intent service is called.

 if (startLocationFirst){ requestLocatonSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); LocationAPIclient.connect();// RequestLocation and GoogleAPIClient won't call until device comes from another ActivityRecognation State running,walking etc. And keep Updating location every 5 hours. } 

The problem I'm current is

  • ActivityRecognation Gets the user state every 3 minutes, but should not go into startLocationFirst boolean until it comes from another ActivityRecognation state and updates the location as set inside startLocationFirst

Here is an IntentService with FusedLocation

 public class Activity_Recognized_Service extends IntentService implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener { /** * Creates an IntentService. Invoked by your subclass constructor. * * @param name Used to name the worker thread, important only for debugging. */ public static final String TAG = "###RECOGNISED SRVCE###"; Timer timer; GoogleApiClient LocationAPIclient; LocationRequest mLocationRequest; Location mCurrentLocation; boolean startLocationFirst=true; public Activity_Recognized_Service() { super("Activity_Recognized_Service"); } public Activity_Recognized_Service(String name) { super(name); } @Override protected void onHandleIntent(@Nullable Intent intent) { Log.d(TAG, "On Handle Intent"); if (ActivityRecognitionResult.hasResult(intent)) { Log.d(TAG, "ActivityRecognition Has Result"); ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); handleDetectedActivities(result.getProbableActivities()); Navigation_Drawer nav = new Navigation_Drawer(); nav.UserMovementResult(result); } } @Override public void onCreate() { super.onCreate(); Log.d(TAG,"On Create Calling"); if (LocationAPIclient == null) { Log.d(TAG, "Location API is NULL Value Of This "); LocationAPIclient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); } } private void handleDetectedActivities(List<DetectedActivity> probableActivities) { for (DetectedActivity activity : probableActivities) { switch (activity.getType()) { case DetectedActivity.IN_VEHICLE: Log.d(TAG, "In Vehicle " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("In Vehicle"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(10*60*1000,8*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); if (startLocationFirst){ Log.d(TAG,"Start Location Update For Car"); } } break; case DetectedActivity.ON_BICYCLE: Log.d(TAG, "On Bicycle " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("On Bicycle"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(7*60*1000,5*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.ON_FOOT: Log.d(TAG, "On Foot " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("On Foot"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); } break; case DetectedActivity.RUNNING: Log.d(TAG, "On Running " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Running"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.STILL: Log.d(TAG, "On Still " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Still"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds // requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.TILTING: Log.d(TAG, "On Tilting " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Tilting"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.WALKING: Log.d(TAG, "On Walking " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Let Walk"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds LocationAPIclient.connect(); } break; case DetectedActivity.UNKNOWN: Log.d(TAG, "UnKnown " + activity.getConfidence()); break; } } } public void setTimer(int Minutes) { Log.d(TAG, "=================================================="); Log.d(TAG, "Set Timeer Starts It will Run Every " + Minutes); int MilliSeconds = 60000 * Minutes; final Handler handler = new Handler(); timer = new Timer(); TimerTask doAsynchronousTask = new TimerTask() { @Override public void run() { handler.post(new Runnable() { public void run() { try { //CODE THAT YOU WANT TO EXECUTE AT GIVEN INTERVAL } catch (Exception e) { // TODO Auto-generated catch block } } }); } }; timer.schedule(doAsynchronousTask, 0, MilliSeconds); Log.d(TAG, "=================================================="); } @Override public void onConnected(@Nullable Bundle bundle) { Log.d(TAG, "On Connected Running"); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(LocationAPIclient); if (mCurrentLocation!=null){ Log.d(TAG,"Last Known Location Is not Null "); new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy())); } else { Log.d(TAG,"Last Known Location Is NULL Start Location Updates"); LocationServices.FusedLocationApi.requestLocationUpdates(LocationAPIclient,mLocationRequest,this); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onLocationChanged(Location location) { Log.d(TAG,"On Location Changed Calling"); mCurrentLocation=location; new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy())); Log.d(TAG,"Stopping Location Update"); // LocationServices.FusedLocationApi.removeLocationUpdates(LocationAPIclient,this); } public void requestLocatonSetting(int Interval,int FastestInterval,int LocationAccuracy){ mLocationRequest=new LocationRequest(); mLocationRequest.setInterval(Interval); mLocationRequest.setFastestInterval(FastestInterval); mLocationRequest.setPriority(LocationAccuracy); } } 
+7
java android google-api location activity-recognition
source share
2 answers

I am executing this code after adding several lines to the same code as above.

  • First, I declare a static int at the class level in the IntentService , because DectectedActivity.getType() returns an int. static int detectedActivity;
  • Then in I check if the state will be the same as the last, if (activity.getConfidence() >= 75 && activity.getType()!=detectedActivity)

It is he. Thanks to @Pablo Baxter for giving me some logic to apply. I tested this on an IntentService , but I need to test it on a service so that I can update locations. Coming soon.

+1
source share

EDIT

Here is a better example, using only the code you provided above:

Use this service when registering an ActivityRecognitionApi:

 public class LocationUpdateService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { public static final String TAG = "###RECOGNISED SRVCE###"; private GoogleApiClient apiClient; private PendingIntent pendingIntent; private DetectedActivity lastActivity; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { apiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); apiClient.connect(); pendingIntent = PendingIntent.getService(this, 1, new Intent(this, YourIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT); } @Override public int onStartCommand(Intent intent, int flag, int startId) { Log.d(TAG, "onStartCommand"); if (ActivityRecognitionResult.hasResult(intent)) { Log.d(TAG, "ActivityRecognition Has Result"); ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); handleDetectedActivity(result); /* You should really use LocalBroadcastManager to send events out to an activity for UI updates */ // Navigation_Drawer nav = new Navigation_Drawer(); // nav.UserMovementResult(result); } return START_STICKY; } @Override public void onConnected(@Nullable Bundle bundle) { Log.d(TAG, "On Connected Running"); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } Location location = LocationServices.FusedLocationApi.getLastLocation(apiClient); if (location!=null){ Log.d(TAG,"Last Known Location Is not Null "); Intent intent = new Intent(this, YourIntentService.class).putExtra("lastKnown", location); startService(intent); /* No more need for this! */ // new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy())); } else { Log.d(TAG,"Last Known Location Is NULL Start Location Updates"); updateLocationSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); // LocationServices.FusedLocationApi.requestLocationUpdates(apiClient,mLocationRequest,this); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } private void handleDetectedActivity(ActivityRecognitionResult result) { DetectedActivity mostProbableActivity = result.getMostProbableActivity(); switch (result.getMostProbableActivity().getType()) { case DetectedActivity.IN_VEHICLE: // Log.d(TAG, "In Vehicle " + activity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("In Vehicle"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST if (apiClient.isConnected()) { updateLocationSetting(10 * 60 * 1000, 8 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; case DetectedActivity.ON_BICYCLE: Log.d(TAG, "On Bicycle " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("On Bicycle"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(7 * 60 * 1000, 5 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; case DetectedActivity.ON_FOOT: Log.d(TAG, "On Foot " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75) { DetectedActivity nextHighest = result.getProbableActivities().get(1); if (nextHighest.getType() == DetectedActivity.RUNNING && nextHighest != lastActivity) { Log.d(TAG, "On Running " + mostProbableActivity.getConfidence()); //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Running"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = nextHighest; } } else if (nextHighest.getConfidence() >= 75 && nextHighest != lastActivity) { Log.d(TAG, "On Walking " + mostProbableActivity.getConfidence()); //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Let Walk"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = nextHighest; } } //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("On Foot"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); } break; case DetectedActivity.STILL: Log.d(TAG, "On Still " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Still"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(5 * 60 * 60 * 1000, 3 * 60 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; case DetectedActivity.TILTING: Log.d(TAG, "On Tilting " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Tilting"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; // case DetectedActivity.WALKING: // Log.d(TAG, "On Walking " + mostProbableActivity.getConfidence()); // if (mostProbableActivity.getConfidence() >= 75) { // //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Let Walk"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); // // if (apiClient.isConnected()) { // updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds // } // } // break; case DetectedActivity.UNKNOWN: Log.d(TAG, "UnKnown " + mostProbableActivity.getConfidence()); lastActivity = mostProbableActivity; break; } } private void updateLocationSetting(int Interval, int FastestInterval, int LocationAccuracy) { LocationRequest request = new LocationRequest(); request.setInterval(Interval); request.setFastestInterval(FastestInterval); request.setPriority(LocationAccuracy); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) { //TODO DO SOMETHING HERE! return; } LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, request, pendingIntent); } } 

And this will use the IntentService instead of using the AsyncTask that you used:

 public class YourIntentService extends IntentService { public YourIntentService() { super("YOUR_INTENT_SERVICE"); } @Override protected void onHandleIntent(@Nullable Intent intent) { if (intent != null) { if (LocationResult.hasResult(intent)) { LocationResult result = LocationResult.extractResult(intent); Location location = result.getLastLocation(); Log.d("YourIntentService", "Got new location: " + location); } else if (intent.hasExtra("lastKnown")) { Location location = intent.getParcelableExtra("lastKnown"); Log.d("YourIntentService", "Got last known location: " + location); } else if (LocationAvailability.hasLocationAvailability(intent)) { LocationAvailability locationAvailability = LocationAvailability.extractLocationAvailability(intent); Log.d("YourIntentService", "Location Availability: " + locationAvailability.isLocationAvailable()); } } } } 

This intent service can handle blocking network requests if they are called on onHandleIntent .

I changed the handleDetectedActivity code a handleDetectedActivity so that with every activity update a new location update would not occur.


First, I would not suggest you use the IntentService way you do now, since the service will be killed as soon as the onHandleIntent exits, which will cause a lot of problems because you rely on callbacks. All this should be placed in Service .

Regarding the processing of location updates based on activity recognition, I found this nice library that simplifies this and is pretty easy to use. https://github.com/mrmans0n/smart-location-lib

The following is an example of using a library with location updates based on performance.

 SmartLocation.with(this).location(new LocationBasedOnActivityProvider(new LocationBasedOnActivityProvider.LocationBasedOnActivityListener() { @Override public LocationParams locationParamsForActivity(DetectedActivity detectedActivity) { if (detectedActivity.getConfidence() >= 75) { LocationParams.Builder builder = new LocationParams.Builder(); switch (detectedActivity.getType()) { case DetectedActivity.IN_VEHICLE: builder.setInterval(/*Interval*/) .setAccuracy(/*Locaiton Accuracy*/); break; case DetectedActivity.ON_BICYCLE: /* So on and so forth.... */ break; } return builder.build(); } return null; } })).start(new OnLocationUpdatedListener() { @Override public void onLocationUpdated(Location location) { //Do what you need here. } }); 

This should be reset to Service in the onStart function, while onStartCommand processes the changes in accordance with the intentions you provide. You can also use this library to get the last known location, and get one fix.

Last, I would recommend you leave AsyncTask if you pass contexts to it. Use an IntentService , since the onHandleIntent function runs in the background thread, and you can use the IntentService context to perform whatever tasks you need. You can pass the Location object as an optional intent when starting the IntentService .

0
source share

All Articles