I want to get location
from background
and submit it to server
so which is the best option to do the same like Job scheduler
or Service
. and why ?. I also want to know about battery saved by job scheduler
while continuously we make web api
call.

- 359
- 2
- 13
-
you want to get location from the user`s device? – Luiz Fernando Salvaterra Apr 18 '17 at 13:02
-
@ Luiz Fernando Salvaterra -Yes. – Akshay More Apr 18 '17 at 13:03
-
If you are continuously listening for changes in location, then your app will drain the battery no matter it is job scheduler or service. – Mohammed Atif Apr 18 '17 at 13:05
-
@ Mohammed Atif: Yes, your are right but i want to know how to job scheduler save battery and and what is the different between service and job scheduler. – Akshay More Apr 18 '17 at 13:08
-
Here are references how to you get user location https://developer.android.com/training/location/retrieve-current.html or http://javapapers.com/android/android-location-tracker-with-google-maps/ – Pratibha sarve Apr 18 '17 at 13:08
2 Answers
This is my implementation, I don't use Job Scheduler
or Service
because it's not necessary. I use the Application
class so you will be able to get the location of user in all your app.
First, you need to create a LocationHelper
class, that will do all the work for you:
public class LocationHelper implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final int REQUEST_LOCATION_PERMISSION = 0;
private static final int REQUEST_RESOLVE_ERROR = 1;
private static GoogleApiClient mGoogleApiClient;
private Fragment mFragment;
private final Activity mActivity;
private final Callback mCallback;
private Location mLastLocation;
private boolean mResolvingError;
private LocationRequest mLocationRequest;
private boolean mRegisterLocationUpdates;
public interface Callback {
void onLastLocation(Location userLocation);
}
public LocationHelper(Fragment fragment, Callback callback) {
this(fragment.getActivity(), callback);
mFragment = fragment;
}
public LocationHelper(Activity activity, Callback callback) {
mActivity = activity;
mCallback = callback;
mLocationRequest = new LocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
obtainLastLocation();
}
private void obtainLastLocation() {
// Verifies if user give us permission to obtain its suggestionLocationV2.
if (ActivityCompat.checkSelfPermission(mActivity,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(mActivity,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
// Show an explanation to the user why we need its suggestionLocationV2.
requestPermissionRationale();
} else {
requestPermission();
}
// We don't have user permission to get its geo suggestionLocationV2, abort mission.
return;
}
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
return;
}
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (lastLocation != null) {
onLocationChanged(lastLocation);
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mRegisterLocationUpdates = true;
}
}
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
removeLocationUpdatesIfNeed();
mLastLocation = location;
DirectoryApp.getInstance().setLastLocation(mLastLocation);
if (mCallback != null) {
mCallback.onLastLocation(mLastLocation);
}
}
private void removeLocationUpdatesIfNeed() {
if (mRegisterLocationUpdates && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mRegisterLocationUpdates = false;
}
}
private void requestPermission() {
// Lets ask suggestionLocationV2 permission to user.
if (mFragment != null) {
mFragment.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_LOCATION_PERMISSION);
} else {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_LOCATION_PERMISSION);
}
}
private void requestPermissionRationale() {
new AlertDialog.Builder(mActivity)
.setMessage("We need the suggestionLocationV2 to provide you best results.")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermission();
}
})
.show();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult result) {
// If not already attempting to resolve an error.
if (!mResolvingError) {
if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(mActivity, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
GooglePlayServicesUtil.showErrorDialogFragment(result.getErrorCode(), mActivity,
null, REQUEST_RESOLVE_ERROR, null);
mResolvingError = true;
}
}
}
// The follow methods should be called in Activity or Fragment.
public void onStart() {
mGoogleApiClient.connect();
}
public void onStop() {
removeLocationUpdatesIfNeed();
mGoogleApiClient.disconnect();
}
public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == REQUEST_LOCATION_PERMISSION
&& grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted. Uhull lets get its suggestionLocationV2 now.
obtainLastLocation();
}
}
}
Note that when the location is changed, we call the Application class to set the new location, so in your Application class you have to create the methods :
public class Application extends MultiDexApplication {
private static App instance;
private Location mLastLocation;
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
public void setLastLocation(Location lastLocation) {
mLastLocation = lastLocation;
}
public Location getLastLocation() {
return mLastLocation;
}
And finally, when you have to use the location, on Fragment
or Activity
, just start and stop it using the right method`s.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationHelper = new LocationHelper(this, this);
}
@Override
public void onStart() {
super.onStart();
locationHelper.onStart();
}
@Override
public void onStop() {
super.onStop();
locationHelper.onStop();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
locationHelper.onRequestPermissionResult(requestCode, permissions, grantResults);
}

- 4,192
- 2
- 24
- 42
if you define "best option" as "most battery efficient way": try to minimize calls that activly connects the internet to read or transfer data.
Instead implement a broadcast receiver that tells your app that there is already internet-traffic going on. when you app receives the broadcast notification it can add ist own internet traffic. this way your app can avoid the battery overhead of connecting to the internet which is is very battery expensive.
For detail see "bundled tranfer" at https://developer.android.com/training/efficient-downloads/efficient-network-access.html

- 14,517
- 7
- 53
- 85