following service is created to continuously update user location. User's location has to be tracked even app is in background, device is idle or screen is off or application is removed/killed from recent list.
But somehow this code doesn't work. Location update stopped after some time automatically and on some devices it doesn;t even work I can't understand why, and I have turned everything from blue to purple.
gradle : 2.3.3 Play service and Map verion : 11.0.4 compile sdk version : 25
## but I am running this app on Android 6.0.1 MarshmallowPlease help me out of this. Thanks in advance.
public class ServiceLocationNew extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final long INTERVAL = 10000;
private static final long FASTEST_INTERVAL = 10000;
private static final long FUSED_DISTANCE = 5;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
Location mLastLocation;
@Override
public void onCreate() {
super.onCreate();
buildApiClient();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (mGoogleApiClient == null) {
buildApiClient();
}
if (!isGooglePlayServicesAvailable()) {
stopSelf();
}
createLocationRequest();
return START_STICKY;
}
public void buildApiClient() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
return false;
}
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setSmallestDisplacement(FUSED_DISTANCE);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setSmallestDisplacement(FUSED_DISTANCE);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
startLocationUpdates();
}
protected void startLocationUpdates() {
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);
}
protected void stopLocationUpdates() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
@Override
public void onConnected(Bundle bundle) {
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;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
updateUI();
}
if (mGoogleApiClient.isConnected()) {
if (mLocationRequest != null) {
startLocationUpdates();
} else {
createLocationRequest();
}
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
updateUI();
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
public static float distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
float dist = (float) (earthRadius * c);
return dist;
}
private void updateUI() {
if (mCurrentLocation != null) {
//calculate distance between current and last location
double dLon = (Double.parseDouble(mLastLocation.getLongitude) - mCurrentLocation.getLongitude());
double y = Math.sin(dLon) * Math.cos(Double.parseDouble(mLastLocation.getLatitude));
double x = Math.cos(mCurrentLocation.getLatitude()) * Math.sin(Double.parseDouble(mLastLocation.getLatitude)) - Math.sin(mCurrentLocation.getLatitude()) * Math.cos(Double.parseDouble(mLastLocation.getLatitude)) * Math.cos(dLon);
double brng = Math.toDegrees((Math.atan2(y, x)));
brng = (360 - ((brng + 360) % 360));
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(mCurrentLocation.getLatitude() - mLastLocation.getLatitude());
double dLng = Math.toRadians(mCurrentLocation.getLongitude() - mLastLocation.getLongitude());
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
float distance = (float) (earthRadius * c);
if (distance >= CV.LOCATION_DISTANCE) {
Tblname.Insert(mCurrentLocation);
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
}
}