I want, get location every now and then via AlarmManager which turn on service with GPS.
AlarmManager works correctly, but I have a problem with the stop service.
First case:
I get location, but Service works every time.
ConnectivityReceiver.java - this is my AlarmManager
public final class ConnectivityReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, " onReceive work", Toast.LENGTH_SHORT).show();
Log.i("ADRIAN", "onRECEIVE ");
Intent serviceIntent = new Intent(context,LocationUpdaterService.class);
context.startService(serviceIntent);
}
LocationUpdaterService.java - Service
public class LocationUpdaterService extends Service implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
public LocationUpdaterService() {
}
#Override
public void onCreate() {
super.onCreate();
Log.i("ADRIAN", "Wlazlem do onCreate");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).
addConnectionCallbacks(this).
addOnConnectionFailedListener(this)
.build();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ADRIAN", "onStartCommand");
mGoogleApiClient.connect();
Toast.makeText(this, "Location services started", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onLocationChanged(Location location) {
System.out.println("MyLocationService.onLocationChanged");
String latitude = Double.toString(location.getLatitude());
String longitude = Double.toString(location.getLongitude());
Log.i("ADRIAN", "Lat:" + latitude + "Long: " + longitude);
// do your work here with location
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(10); // Update location every second
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
Location loc = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.i("ADRIAN", "onConnected");
}
Log.i("ADRIAN", "onConnected 2 ");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onDestroy() {
// String latitude = "null";
// String longitude = "null";
Toast.makeText(this, "Location services stopped", Toast.LENGTH_LONG).show();
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Location loc = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(loc != null) {
// latitude = Double.toString(loc.getLatitude());
// longitude = Double.toString(loc.getLongitude());
// Log.i("ADRIAN", "Lat:" + latitude + "Long: " + longitude);
}
}
Log.i("ADRIAN", "Location services stopped");
mGoogleApiClient.disconnect();
super.onDestroy();
}
}
Screen LOGCAT
Second case
When I added context.stopService(serviceIntent) then my application doesn't get location. I tried use SystemClock.sleep(10000); but it still works the same.
ConnectivityReceiver.java
public final class ConnectivityReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, " onReceive work", Toast.LENGTH_SHORT).show();
Log.i("ADRIAN", "onRECEIVE ");
Intent serviceIntent = new Intent(context,LocationUpdaterService.class);
context.startService(serviceIntent);
SystemClock.sleep(10000);
Log.i("ADRIAN", "STOP SERVICE");
context.stopService(serviceIntent);
}
LocationUpdaterService.java - the same as above.
SCREEN 2 LOGCAT
What am I doing wrong and How I can fix it?
onStartCommand ---> Service.START_STICKY
#Override
public void onDestroy() {
locationManager.removeUpdates(listener);
locationManager=null;
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
locationManager.removeUpdates(listener);
locationManager=null;
}
Related
How to send user location data to server every five second using restful API even app is closed in android?
Please help me
you can create a background service that it works when user lock screen or close your app from background
you must create service with this way:
first create a Service class like this:
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks {
public static double latitude;
public static double longitude;
private int retryGPS = 0;
private int retryNetwork = 0;
private Handler handler;
private Runnable runnable;
private GoogleApiClient mGoogleApiClient;
private LocationManager mLocationManager;
private LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER),
};
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 1;
private static final String TAG = "LocationService";
#Override
public void onCreate() {
buildGoogleApiClient();
initializeLocationManager();
locationRequest();
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
sendLocation();
}
};
sendLocation();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private void locationRequest() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
}
private void sendLocation() {
//TODO: you can use location here
handler.postDelayed(runnable,5000);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
if (!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
return START_STICKY;
}
#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) {
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
} else {
try {
Thread.sleep(3000);
onConnected(null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
if (mLocationManager != null) {
for (LocationListener mLocationListener : mLocationListeners) {
try {
mLocationManager.removeUpdates(mLocationListener);
} catch (Exception e) {
e.printStackTrace();
}
}
}
super.onDestroy();
}
private class LocationListener implements android.location.LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
Location mLastLocation;
public LocationListener(String provider) {
Log.d(TAG, "LocationListener: " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(final Location location) {
mLastLocation.set(location);
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.d(TAG, "onLocationChanged: { latitude: " + latitude + " ,longitude: " + longitude + " , accuracy: " + location.getAccuracy() + " }");
}
#Override
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + status);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
}
}
}
then register service in manifest:
<service
android:name=".service.LocationService"
android:enabled="true"
android:process=":process" />
then start service from any activity or fragment :
public static void mStopService(Context context) {
context.stopService(new Intent(context, LocationService.class));
}
public static void mStartService(Context context) {
context.startService(new Intent(context, LocationService.class));
}
if you want to make your code run even when the app is closed you need to use services, services can run in the background even if the app is closed, and you may need to use a broadcast receiver with the service to keep running it every time it finishes.
this is the Service:
public class myService extends Service {
public static int counter = 0;
public myReceiver myReceiver = new myReceiver();
#Override
public void onCreate() {
super.onCreate();
//this line register the Receiver for the first time
myService.this.registerReceiver(myReceiver, new IntentFilter("com.example.myApp"));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Here you have to put the code that gets the location and send it
}
#Override
public void onDestroy() {
super.onDestroy();
//here you sent a broadcast message to start the reciever
//note that the broadcast message that you send has to be unique writing you package name will be fine ex: com.example.myApp
Intent sendBroadCast = new Intent("com.example.myApp");
sendBroadcast(sendBroadCast);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
and this is the broadcast receiver:
public class myReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
if("com.example.myApp".equals(intent.getAction())){
//the handler is used as a timer here
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent myServ = new Intent(context, myService.class);
try {
context.startService(myServ);
}catch (Exception e){
}
}
},5000);
}
}
}
I am developing an application that is highly dependent on user location and geo fencing. I am trying to get the user location first and based on that further operations are carried out. Everything is working fine except for the fact that, some times I am getting wrong location values and unless and until I restart the app and in some cases, restart the phone, I don't get the correct value. I will post my Location Api codes below. If any changes required, please do let me know.
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
buildGoogleApiClient();
if (!statusOfGPS) {
displayPromptForEnablingGPS(this);
} else {
permissionAndLocationAccess();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Update location every second
if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
} else {
ProgressUtil.hideProgressDialog(prgd_progressDialog);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
lat = mLastLocation.getLatitude();
lon = mLastLocation.getLongitude();
Log.e("Lat and Lng", "onconn");
if (!String.valueOf(lat).equals("0.0")) {
latitudeVal = mLastLocation.getLatitude();
longitudeVal = mLastLocation.getLongitude();
sendLatLong(latitudeVal, longitudeVal);
Log.d("Lat and Lng", "in last loc");
Log.d("Lat and Lng", String.valueOf(latitudeVal) + longitudeVal);
new AsyncCaller().execute();
}
}
}
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
lat = location.getLatitude();
lon = location.getLongitude();
Log.e("Lat and Lng", "onchanged");
if (!String.valueOf(lat).equals("0.0")) {
latitudeVal = location.getLatitude();
longitudeVal = location.getLongitude();
ProgressUtil.hideProgressDialog(prgd_progressDialog);
Log.e("Lat and Lng", "onchanged0");
Log.e("Lat and Lng", String.valueOf(latitudeVal) + longitudeVal);
I am also using this class and in my case its working fine. You can check
public class BackgroundLocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
protected static final String TAG = "BackService";
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = GLOBAL_BACKGROUND_CHECK_TIME;
public GoogleApiClient mGoogleApiClient;
public LocationRequest mLocationRequest;
private PendingIntent mPendingIntent;
IBinder mBinder = new LocalBinder();
private class LocalBinder extends Binder {
public BackgroundLocationService getServerInstance() {
return BackgroundLocationService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
Intent mIntentService = new Intent(this, LocationUpdates.class);
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, PendingIntent.FLAG_UPDATE_CURRENT);
buildGoogleApiClient();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (mGoogleApiClient.isConnected()) {
Log.i(TAG + " onStartCmd", "Connected");
return START_STICKY;
}
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting()) {
Log.i(TAG + " onStartCmd", "GoogleApiClient not Connected");
mGoogleApiClient.connect();
}
NotificationManager notificationManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder notification = new NotificationCompat.Builder(this);
notification.setContentTitle("Title ");
notification.setContentText("\n Tracking BackGround ... ");
notification.setSmallIcon(R.drawable.big_marker);
notificationManager.notify(151458461, notification.build());
return START_STICKY;
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
createLocationRequest();
}
protected void createLocationRequest() {
Log.i(TAG, "createLocationRequest()");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(GLOBAL_BACKGROUND_CHECK_TIME);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void startLocationUpdates() {
Log.i(TAG, "Started Location Updates");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
}
public void stopLocationUpdates() {
Log.i(TAG, "Stopped Location Updates");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
startLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
String message = "Latitude : " + location.getLatitude() + "\n Longitude : " + location.getLongitude() +
"\n location Accuracy: " + location.getAccuracy() + "\n speed: " + location.getSpeed();
Log.d(TAG, "onLocationChanged: " + message);
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
#Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
}
}
I want to detect user trip and when trip is started, I have to get LatLng in every 5 seconds. I am using Google FusedLocationAPI and My problem is until My GPS is enabled then its calculating all distance but Once I disabled GPS the its stucked. How can I Show pending trip if user Disabled GPS in mid of trip ?
My Service class is :
public class TripStartedService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
public static long UPDATE_INTERVAL_IN_MILLISECONDS = 1000 * 5;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
public GoogleApiClient mGoogleApiClient;
public LocationRequest mLocationRequest;
private PendingIntent mPendingIntent;
IBinder mBinder = new TripStartedService.LocalBinder();
public static boolean isGPSOn = false;
#Override
public void onCreate() {
super.onCreate();
Intent mIntentService = new Intent(this, TripStartedIntent.class);
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, PendingIntent.FLAG_UPDATE_CURRENT);
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
Log.i("", "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
private void createLocationRequest() {
Log.i("TRIP_START_Request", "createLocationRequest()");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
Log.i("", "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i("", "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
#Override
public void onLocationChanged(Location location) {
String message = "Latitude : " + location.getLatitude() + "\n Longitude : " + location.getLongitude() + "\n Accuracy: " + location.getAccuracy();
Log.i("", "onLocationChanged: " + message);
}
private void startLocationUpdates() {
Log.i("", "Started Location Updates");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
LocationManager manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
isGPSOn = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (mGoogleApiClient.isConnected()) {
Log.i("GPS init" + " onStartCmd", "Connected");
return START_STICKY;
}
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting()) {
Log.i("Connceti" + " onStartCmd", "GoogleApiClient not Connected");
mGoogleApiClient.connect();
}
return START_STICKY;
}
private class LocalBinder extends Binder {
public TripStartedService getServerInstance() {
return TripStartedService.this;
}
}
#Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
}
public void stopLocationUpdates() {
Log.i("", "Stopped Location Updates");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
}
}
And My Calculation Class is
if (isGPSOn) {
try {
LocDatabaseHelper database = new LocDatabaseHelper(activity);
Timestamp timestamp_start = new Timestamp(System.currentTimeMillis());
Timestamp timestamp_end = new Timestamp(System.currentTimeMillis());
final int TRIP_START_ID = 0;
ContentValues contentValues = new ContentValues();
final ArrayList<TripDistanceModels> trip_list_values = database.getTripDistance();
try {
Location loc1 = new Location("");
loc1.setLatitude(Double.parseDouble(trip_list_values.get(0).getLatitude()));
loc1.setLongitude(Double.parseDouble(trip_list_values.get(0).getLongitude()));
Location loc2 = new Location("");
loc2.setLatitude(Double.parseDouble(trip_list_values.get(1).getLatitude()));
loc2.setLongitude(Double.parseDouble(trip_list_values.get(1).getLongitude()));
} catch (Exception e) {
e.printStackTrace();
}
contentValues.put(TRIP_STARTED_ID, TRIP_START_ID);
contentValues.put(TRIP_STARTED_LATTITUDE, start_trip_location.getLatitude());
contentValues.put(TRIP_STARTED_LONGITUDE, start_trip_location.getLongitude());
contentValues.put(TRIP_STARTED_TIMESTAMP, String.valueOf(timestamp_start));
contentValues.put(TRIP_END_TIMESTAMP, String.valueOf(timestamp_end));
database.tripInsertionOnDetect(TRIP_START_ID, start_trip_location.getLatitude(), start_trip_location.getLongitude(), timestamp_start, timestamp_end, "pending status");
Log.d("TRIP STARTRED", contentValues.toString());
final int trip_counts = database.getRowCountForTripStarted();
final int back_counts = database.getRowCountForBackground();
Log.e("TRip Database Rows Size", "" + trip_counts + "\t \tBackGroundTable Rows : " + back_counts + "\tGPS>>>: " + Boolean.toString(isGPSOn));
activity.stopService(new Intent(activity, BackgroundLocationService.class));
} catch (Exception e) {
e.printStackTrace();
}
}
If your gps is not enable then you can use cell tower location. it's not accurate. you can get near by location.
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
You should add a broadcast receiver to detect if the gps is enabled or disable :
private BroadcastReceiver gpsReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean isGpsEnabled = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
if (isGpsEnabled) {
//Here code when gps is enabled
} else {
//Here code when gps is disabled
}
}
}
}
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
registerReceiver(gpsReceiver, new IntentFilter("android.location.PROVIDERS_CHANGED"));
//here other code ...
return super.onStartCommand(intent, flags, startId);
}
I started Service from main activity like;-
Intent intent = new Intent(this, MyLocationService.class);
startService(intent);
MyLocationService class looks like:-
public class MyLocationService extends Service implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = MyLocationService.class.getSimpleName();
public static Location mCurrentLocation;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
#Override
public void onCreate() {
Log.e(TAG, "onCreate: ");
initiateGooglePlayService();
}
public void initiateGooglePlayService() {
Log.e(TAG, "initiateGooglePlayService: ");
if (isGooglePlayServicesAvailable()) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(10.0f);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand: ");
return super.onStartCommand(intent, flags, startId);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind: ");
return null;
}
private boolean isGooglePlayServicesAvailable() {
Log.e(TAG, "isGooglePlayServicesAvailable: ");
int status = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getApplicationContext());
return ConnectionResult.SUCCESS == status;
}
#Override
public void onConnected(Bundle bundle) {
Log.e(TAG, "onConnected: ");
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "onConnectionSuspended: ");
}
protected void startLocationUpdates() {
Log.e(TAG, "startLocationUpdates: ");
try {
PendingResult<Status> pendingResult;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
} catch (IllegalStateException ignored) {
}
}
#Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location.getLongitude());
if (mGoogleApiClient.isConnected()) {
mCurrentLocation = location;
Intent intent = new Intent("GPSLocationUpdates");
intent.putExtra("location", location);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
Toast.makeText(this, "location", Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed: ");
}
}
I never stop the service anywhere.
But still I am unable to get the control of onLocationChange().
My motive is that, I need continuous location to do some background operation. It worked in lollipop sometimes. But it is not working in Marshmallow and nougat and even kitkat also. I searched but could not get the proper idea. Please let me know, where i am going wrong. Any suggestion accepted.
I am using following dependency for location;-
compile 'com.google.android.gms:play-services-location:9.6.1'
You can use the HyperTrack SDK to get the location updates in the background. Get more insight about the reliability of SDK here in different conditions.
First Setup the SDK
After setting up the SDK you just need to set the Callback to receive the location updates.
HyperTrack.setCallback(new HyperTrackEventCallback() {
#Override
public void onEvent ( #NonNull final HyperTrackEvent event){
switch (event.getEventType()) {
case HyperTrackEvent.EventType.LOCATION_CHANGED_EVENT:
Log.d(TAG, "onEvent: Location Changed");
HyperTrackLocation hyperTrackLocation = event.getLocation();
LatLng latLng = hyperTrackLocation.getLatLng();
updateCurrentLocationMarker(event.getLocation());
break;
}
}
}
(Disclaimer: I work at HyperTrack.)
/**Check out my Github post i did the same for Taxi clone**/
Link ---> https://github.com/yash786agg/GPS/
Note: Remember to remove or comment the below mentioned code if you want the latitude
and latitude even when the application is in background.
if(networkUtilObj != null)
{
networkUtilObj.disconnectGoogleApiClient();
}
I am using fusedlocation api in a Service for updating gps location to server every few seconds.In the MainActivity I have written the code to open locationSettings.Then in onResume method I start the Service(GpsService.java).The Service class send Broadcast everytime location is updated and it is received in the onResume() method.But I only get the location coordinates once.sendAmblnceGps() method is where the location is send to the server.
GpsService.java:
public class GpsService extends Service implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
com.google.android.gms.location.LocationListener locationListener;
LocationRequest mLocationRequest;
private static final long INTERVAL = 100* 50;
private static final long FASTEST_INTERVAL = 100 * 20;
GoogleApiClient googleApiClient;
boolean connected;
public GpsService() {
super();
}
#Override
public void onCreate() {
super.onCreate();
GoogleApiClient.Builder googleApiClientbuilder=new GoogleApiClient.Builder(GpsService.this).addConnectionCallbacks(GpsService.this).addOnConnectionFailedListener(GpsService.this).addApi(LocationServices.API);
googleApiClient=googleApiClientbuilder.build();
googleApiClient.connect();
Toast.makeText(getApplicationContext(),"service created",Toast.LENGTH_SHORT).show();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(100);
}
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(
googleApiClient, mLocationRequest, locationListener);
Log.d("TAG", "Location update started ..............: ");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Service Command", "Started");
locationListener = new com.google.android.gms.location.LocationListener()
{
#Override
public void onLocationChanged(Location location) {
Intent intent = new Intent("location_updates");
intent.putExtra("lat", location.getLatitude());
intent.putExtra("longt", location.getLongitude());
Log.e("location", "lat:" + " " + Double.toString(location.getLatitude()) + " " + "Longt:" + " " + Double.toString(location.getLongitude()));
sendBroadcast(intent);
} };
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient,locationListener);
if(googleApiClient.isConnected()){
googleApiClient.disconnect();
}
Log.e("Service","Stopped");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.e("Connection failed","Service stopped");
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient,locationListener);
if(googleApiClient.isConnected()){
googleApiClient.disconnect();
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
createLocationRequest();
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
Log.e("Connection","suspended");
}
}
MainActivity.java:
#Override
protected void onResume() {
super.onResume();
if (locationManager == null) {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} else {
gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isConnected()) {
if (gps_enabled) {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Acquiring your current location");
progressDialog.setIndeterminate(true);
progressDialog.getWindow().setGravity(Gravity.CENTER);
progressDialog.show();
Log.e("starting", "service");
intent = new Intent(MainActivity.this, GpsService.class);
startService(intent);
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("starting", "broadcastservice");
latitude = Double.toString(intent.getDoubleExtra("lat", 0.0));
longitude = Double.toString(intent.getDoubleExtra("longt", 0.0));
if (isConnected()) {
sendAmblnceGps();
} else {
progressDialog.cancel();
Toast.makeText(getApplicationContext(), "Please enable internet connection", Toast.LENGTH_SHORT).show();
}
}
};
Log.e("registering", "broadcastservice");
registerReceiver(broadcastReceiver, new IntentFilter("location_updates"));
}
}
else {
Toast.makeText(getApplicationContext(),"Enable Internet Connection",Toast.LENGTH_SHORT).show();
}
}
}
You have specified mLocationRequest.setSmallestDisplacement(100);, so you need to move at least 100 meters from the location of the initial location update to have a new location update.