I am implementing a background service that updates the location based on the user's activity i.e if user is still it updates location after every 15 minutes and if user is moving it updates location after every 1 minute. I have created one background service but it is not working as intended. Here is a code that i have written but I couldn't able to locate the bug..
public class LocationUpdateService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<Status> {
protected static final String TAG = "LocationUpdateService";
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 4000;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
protected final static String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
protected final static String LOCATION_KEY = "location-key";
protected final static String LAST_UPDATED_TIME_STRING_KEY = "last-updated-time-string-key";
private ActivityDetectionBroadcastReceiver mBroadcastReceiver;
public static Boolean mRequestingLocationUpdates;
protected String mLastUpdateTime;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location mCurrentLocation;
public static boolean isEnded = false;
private ArrayList<LocationVo> mLocationData;
private Long activityRequest = (long)30000;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
buildGoogleApiClient();
mBroadcastReceiver = new ActivityDetectionBroadcastReceiver();
// Kick off the process of building a GoogleApiClient and requesting the LocationServices
// API.
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Within {@code onPause()}, we pause location updates, but leave the
// connection to GoogleApiClient intact. Here, we resume receiving
// location updates if the user has requested them.
Log.d("LOC", "Service init...");
isEnded = false;
mRequestingLocationUpdates = false;
mLastUpdateTime = "";
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
return Service.START_REDELIVER_INTENT;
}
/**
* Builds a GoogleApiClient. Uses the {@code #addApi} method to request the
* LocationServices API.
*/
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient===");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(ActivityRecognition.API)
.addApi(LocationServices.API)
.build();
createLocationRequest((long)30000);
}
@Override
public void onConnected(Bundle bundle) {
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, new IntentFilter(Constants.STRING_ACTION));
startLocationUpdates();
/* Intent intent = new Intent( this, ActivityRecognizedService.class );
PendingIntent pendingIntent = PendingIntent.getService( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates( mGoogleApiClient, 3000, pendingIntent );*/
}
@Override
public void onConnectionSuspended(int i) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended==");
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
/**
* Updates the latitude, the longitude, and the last location time in the UI.
*/
private void updateUI(Location location) {
// Toast.makeText(this, "Latitude: =" + mCurrentLocation.getLatitude() + " Longitude:=" + mCurrentLocation
// .getLongitude(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "Latitude:==" + mCurrentLocation.getLatitude() + "\n Longitude:==" + mCurrentLocation.getLongitude
());
//LocationDBHelper.getInstance(this).insertLocationDetails(mLocationData);
}
protected void createLocationRequest(Long timeSpan) {
mGoogleApiClient.connect();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(timeSpan);
mLocationRequest.setFastestInterval(timeSpan);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
/**
* Requests location updates from the FusedLocationApi.
*/
protected void startLocationUpdates() {
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, activityRequest, getActivityDetectionPendingIntent()).setResultCallback((ResultCallback<? super Status>) this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.i(TAG, " startLocationUpdates===");
isEnded = true;
}
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI(location);
//stopLocationUpdates();
// Toast.makeText(this, getResources().getString(R.string.location_updated_message),
// Toast.LENGTH_SHORT).show();
}
/**
* Removes location updates from the FusedLocationApi.
*/
protected void stopLocationUpdates() {
if (mRequestingLocationUpdates) {
mRequestingLocationUpdates = false;
Log.d(TAG, "stopLocationUpdates();==");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
public class ActivityDetectionBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ArrayList<DetectedActivity> detectedActivities = intent.getParcelableArrayListExtra(Constants.STRING_EXTRA);
// String activityString = "";
for (DetectedActivity activity : detectedActivities) {
//activityString += "Activity: " + getDetectedActivity(activity.getType()) + ", Confidence: " + activity.getConfidence() + "%\n";
switch (activity.getType()) {
case DetectedActivity.IN_VEHICLE: {
Log.e("ActivityRecogition", "In Vehicle: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)30000;
createLocationRequest((long) 30000);
startLocationUpdates();
}
break;
}
case DetectedActivity.ON_BICYCLE: {
Log.e("ActivityRecogition", "On Bicycle: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)30000;
startLocationUpdates();
createLocationRequest((long) 30000);
}
break;
}
case DetectedActivity.ON_FOOT: {
Log.e("ActivityRecogition", "On Foot: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)60000;
startLocationUpdates();
createLocationRequest((long) 60000);
}
break;
}
case DetectedActivity.RUNNING: {
Log.e("ActivityRecogition", "Running: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)45000;
startLocationUpdates();
createLocationRequest((long) 45000);
}
break;
}
case DetectedActivity.STILL: {
Log.e("ActivityRecogition", "Still: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)6000;
startLocationUpdates();
createLocationRequest((long) 6000);
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
builder.setContentText( "Are you still?" );
builder.setSmallIcon( R.mipmap.ic_launcher );
builder.setContentTitle( getString( R.string.app_name ) );
NotificationManagerCompat.from(getApplicationContext()).notify(0, builder.build());
}
break;
}
case DetectedActivity.TILTING: {
Log.e("ActivityRecogition", "Tilting: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)600000;
startLocationUpdates();
createLocationRequest((long) 600000);
}
break;
}
case DetectedActivity.WALKING: {
Log.e("ActivityRecogition", "Walking: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)120000;
startLocationUpdates();
createLocationRequest((long) 120000);
}
break;
}
case DetectedActivity.UNKNOWN: {
Log.e("ActivityRecogition", "Unknown: " + activity.getConfidence());
if (activity.getConfidence() >= 75) {
activityRequest = (long)100000;
startLocationUpdates();
createLocationRequest((long) 100000);
}
break;
}
default: {
activityRequest = (long)300000;
createLocationRequest((long) 300000);
break;
}
}
}
}
}
private PendingIntent getActivityDetectionPendingIntent() {
Intent intent = new Intent(this, ActivitiesIntentService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Log.e(TAG, "Successfully added activity detection.");
} else {
Log.e(TAG, "Error: " + status.getStatusMessage());
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
stopLocationUpdates();
}
}
I am calling this Service from main activity's onCreate()
methd using this line of code startService(new Intent(this, LocationUpdateService.class));
Now the problem with this code is that it udpates location after every minutes no matter what the activity of the device is. Please help me in getting the desired result. Thanks in advance.