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();
}
}
Related
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 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.
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;
}
In my project i create background service which is get location using google api client.
my problem is when app destroyed,service is running but google api client automatically disconnected and cannot get lat-lang. i don't want lost a connection.
This is my service class code
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
String lat, lon;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}else{
mGoogleApiClient.connect();
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(100); // Update location every second
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
lat = String.valueOf(mLastLocation.getLatitude());
lon = String.valueOf(mLastLocation.getLongitude());
}
updateUI();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
lat = String.valueOf(location.getLatitude());
lon = String.valueOf(location.getLongitude());
updateUI();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
buildGoogleApiClient();
}
synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
//setUpLocationClientIfNeeded();
if(!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting())
{
mGoogleApiClient.connect();
}
return START_STICKY;
}
void updateUI() {
Log.d("LatLongGPS", lat + "==========" + lon);
Toast.makeText(getApplicationContext(), "Service"+lat + "==========" + lon, Toast.LENGTH_LONG).show();
}
}
I am a newbie to Android and working on my very first application. I am working on a application which takes continuous location update and show that on google map. It means no matter whether application is in foreground or in background.
For the same I am using fusedlocation API's requestLocationUpdates. There are two version of the same viz:
With LocationListener when app is in foreground
With pendingIntent when app goes to background.
So as per my understanding I have to use both as I need continuous update.So I am using both in my application as I need continuous update.
But as a surprise I got that requestLocationUpdates with pendingIntent giving me location update in foreground as well. So I am very confused here and sometime giving Location as NULL .
Please tell me what is the exact behaviour of requestLocationUpdates with pendingIntent . Will it work for both foreground and bckground ? If yes then why I am getting the Location as NULL sometime.
Another problem when I was using Locationreveiver then I was able toget proper location update when app was in foreground and I was drawing a line on googlemap. But I noticed my line was not in sync with googlemap route. It was zig zag . So here I am confused If I am getting continuous update then why not m route is sync with google route .
I am attaching the complecode of my location class. Please help
public class LocationMapsActivity extends FragmentActivity implements
LocationListener,
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
ComponentCallbacks2,
GoogleApiClient.OnConnectionFailedListener {
//*******************************member variables*********************************************
private static final String TAG = "LocationActivity";
private static final long INTERVAL = 1000 *02; // 1000*60*1 = 1 minute
private static final long FASTEST_INTERVAL = 1000 *01 ;// 10 sec
public static LatLng mPrev = null;
private double mCurrentDistance = 0;
private double mTotalDistance = 0;
private double mCurrentSpeed = 0;
public static String stateOfLifeCycle = "";
public static boolean wasInBackground = false;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
Location mStartLocation;
GoogleMap googleMap;
//********************************************
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate ...............................");
wasInBackground = false;
stateOfLifeCycle = "Create";
//show error dialog if GoolglePlayServices not available
if (!isGooglePlayServicesAvailable()) {
finish();
}
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
setContentView(R.layout.activity_map_location);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
//*******************ComponentCallbacks2*************************
#Override
public void onTrimMemory(int level) {
if (stateOfLifeCycle.equals("Stop")) {
wasInBackground = true;
}
super.onTrimMemory(level);
Toast.makeText(getApplicationContext(),
"Application OnTrimmemory ", Toast.LENGTH_SHORT)
.show();
}
//****************Activity****************************
#Override
public void onStart() {
Toast.makeText(getApplicationContext(),"OnStart ", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStart fired ..............");
stateOfLifeCycle = "Start";
if (wasInBackground) {
Toast.makeText(getApplicationContext(),"Application came to foreground",Toast.LENGTH_SHORT).show();
wasInBackground = false;
}
super.onStart();
if(!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
}
//********************Activity************************
#Override
public void onStop() {
stateOfLifeCycle = "Stop";
Log.d(TAG, "onStop fired ..............");
stopLocationUpdates();
// mGoogleApiClient.disconnect();
super.onStop();
Toast.makeText(getApplicationContext(), "OnStop ", Toast.LENGTH_SHORT).show();
Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
}
//**************Activity******************************
#Override
protected void onPause() {
stateOfLifeCycle = "Pause";
super.onPause();
Toast.makeText(getApplicationContext(), "OnPause ", Toast.LENGTH_SHORT) .show();
}
//*******************Activity*************************
#Override
public void onResume() {
Toast.makeText(getApplicationContext(),"OnResume ", Toast.LENGTH_SHORT).show();
stateOfLifeCycle = "Resume";
super.onResume();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
//*****************Activity***************************
#Override
public void onDestroy()
{
wasInBackground = false;
stateOfLifeCycle = "Destroy";
super.onDestroy();
Toast.makeText(getApplicationContext(), "Application OnDestroy ", Toast.LENGTH_SHORT).show();
}
//******************OnMapReadyCallback**************************
#Override
public void onMapReady(GoogleMap map) {
googleMap = map;
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
//googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
//*******************GoogleApiClient.ConnectionCallbacks*************************
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
//*******************GoogleApiClient.ConnectionCallbacks*************************
#Override
public void onConnectionSuspended(int i) {
}
//*****************GoogleApiClient.ConnectionCallbacks***************************
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed: " + connectionResult.toString());
}
//*****************LocationListener***************************
// #Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
LatLng current = new LatLng(location.getLatitude(), location.getLongitude());
if(mPrev == null) //when the first update comes, we have no previous points,hence this
{
mPrev=current;
mStartLocation = location;
addMarker();
}
else {
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(current, 17);
googleMap.animateCamera(update);
PolylineOptions pOptions = new PolylineOptions()
.width(7)
.color(Color.BLUE)
.visible(true);// .geodesic(true)
pOptions.add(mPrev);
pOptions.add(current);
googleMap.addPolyline(pOptions);
mPrev = current;
current = null;
}
}
//********************************************
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
//********************************************
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
Log.d(TAG, "isGooglePlayServicesAvailable ...............: SUCCESS" );
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
//********************************************
protected void startLocationUpdates() {
//Get foreground location update
/* PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);*/
//Get background location update
String proximitys = "ACTION";
IntentFilter filter = new IntentFilter(proximitys);
getApplicationContext().registerReceiver(new LocationReceiver() , filter);
Intent intent = new Intent(proximitys);
// Intent intent = new Intent(this, LocationReceiver.class);
PendingIntent locationIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationIntent);
}
//********************************************
public void HandleLocationChanged(Location location) {
Log.d(TAG, "Firing HandleLocationChanged..............................................");
// Toast.makeText(getApplicationContext(), "HandleLocationChanged", Toast.LENGTH_LONG).show();
if(location == null)
{
Toast.makeText(getApplicationContext(), "location is null", Toast.LENGTH_LONG).show();
return;
}
mCurrentLocation = location;
LatLng current = new LatLng(location.getLatitude(), location.getLongitude());
if(mPrev == null) //when the first update comes, we have no previous points,hence this
{
mPrev=current;
mStartLocation = location;
addMarker();
}
else {
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(current, 17);
googleMap.animateCamera(update);
PolylineOptions pOptions = new PolylineOptions()
.width(7)
.color(Color.BLUE)
.visible(true);// .geodesic(true)
pOptions.add(mPrev);
pOptions.add(current);
googleMap.addPolyline(pOptions);
mPrev = current;
current = null;
}
}
//********************************************
public String getAddress( )
{
Geocoder geocoder = new Geocoder(this);
String addressLineTemp=null;
List<Address> addresses;
try {
addresses = geocoder.getFromLocation(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude(), 1);
if (addresses.size() > 0) {
addressLineTemp = addresses.get(0).getAddressLine(0);
}
} catch (IOException e) {
e.printStackTrace();
}
return addressLineTemp;
}
//********************************************
private void addMarker() {
MarkerOptions options = new MarkerOptions();
LatLng currentLatLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
options.position(currentLatLng);
Marker mapMarker = googleMap.addMarker(options);
mapMarker.setTitle(getAddress());
Log.d(TAG, "Marker added.............................");
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng,
13));
Log.d(TAG, "Zoom done.............................");
}
//********************************************
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
}
//********************************************
public class LocationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Log.d(TAG, "Firing LocationReceiver....onReceive..........................................");
Location location = (Location) intent.getExtras().get(LocationServices.FusedLocationApi.KEY_LOCATION_CHANGED);
HandleLocationChanged(location);
}
}