I need to get location(By fusedlocation API) of user after ActivityRecognition Detect user state (Which calls every 3 mins), like IN_VEHICLE,ON_FOOT,RUNNING etc.
On each event i need user location after regular interval For example:
if user is still then setInterval(5*60*60*1000);
and check for next location
update in not before 5 hour. But ActivityRecognation Will call every 3 min.
if user is Running then setInterval(2*60*1000);
and check for next location update in not before/After 2 mins. But ActivityRecognation Will call every 3 min.
if user is running then send location every 1 mins if user is Driving then send location every 15 mins.
I tried to set boolean false in onConnected
to false and true at class level. But it always turn into true because whole Intent service is called after 3 mins.
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.
}
Issue I am current having
startLocationFirst
boolean until it comes from another ActivityRecognation State and keep updating location as set inside startLocationFirst
Here is IntentService With FusedLocation
public class Activity_Recognized_Service extends IntentService implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener {
/**
* Creates an IntentService. Invoked by your subclass's 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's 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);
}
}
I execute this code after adding few lines to same code as above.
IntentService
because DectectedActivity.getType()
return int. static int detectedActivity;
if (activity.getConfidence() >= 75 && activity.getType()!=detectedActivity)
That's it.Thanks to @Pablo Baxter who gave me some kind of logic to apply.I tested this on IntentService
but i need to test it on service so i can update locations.Will update soon.
EDIT
Here is a better example using only the code you have provided above:
Use this service when registering your 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's 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's 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 would be the IntentService to use instead of using the AsyncTask you were using:
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 as long as they are called within the onHandleIntent
.
I modified the handleDetectedActivity
code a bit so that on every activity update, a new location update doesn't occur.
First off, I would not suggest you use an IntentService
the way you are now, as the service will be killed once it exits onHandleIntent
, which would cause a lot of issues since you are relying on callbacks. All of this should be put into a Service
instead.
As for handling location updates based on activity recognition, I did find this nice library that simplifies this and is pretty easy to use. https://github.com/mrmans0n/smart-location-lib
Here is an example of how to use the library with location updates based on activity results.
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 dropped into a Service
in the onStart
function, with onStartCommand
handling changes based on the intent extras you provide. You can also use this library to get the last known location, and to get a single fix.
One last thing, I would recommend you get away from the AsyncTask
if you are passing contexts to it. Instead use the IntentService
, since the onHandleIntent
function is run in a background thread, and you can use the IntentService
's context to perform whatever tasks you need with it. You can pass the Location
object as an extra in the intent when you start your IntentService
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With