Get last location from FusedLocation in service - android

I' trying to getLastLocation() in my Service, witch is starting every minute. As I can see, fusedLocation requires Activity or Executor in .addOnSuccessListener(). How I can get it in Service?
LocationCheckService.class
public class LocationCheckService extends Service{
private FusedLocationProviderClient mFusedLocationClient;
#Override
public void onCreate() {
super.onCreate();
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
}
}
});
}
#SuppressLint("MissingPermission")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}

You don't need GoogleApiClient -
first in gradle add -
implementation 'com.google.android.gms:play-services-location:15.0.0'
In Android Manifest -
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
than create a service to get location update as -
public class LocationUpdateService extends Service {
private FusedLocationProviderClient client;
private LocationRequest locationRequest;
#Override
public void onCreate() {
super.onCreate();
client = LocationServices.getFusedLocationProviderClient(this);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(0);
locationRequest.setFastestInterval(0);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
client.requestLocationUpdates(locationRequest, locationCallback, null);
} catch (SecurityException ignore) {
Log.e("AppLocationService", "SecurityException - " + ignore.toString(), ignore);
}
return START_STICKY;
}
private final LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
List<Location> locationList = locationResult.getLocations();
if (locationList.size() != 0) {
Location location = locationList.get(0);
Log.e("AppLocationService", "Latitude - " +location.getLatitude()+", longitude - " +location.getLongitude() );
}
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
}
To get update in activity you can use LocalBroadCast OR same code you can use in Activity
NOTE : don't forget to take permission above 23

I provide one separate class for fetching location data using faused API. you can call this class into your service it gets latest location lat and long value.
public class GPSController implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{
OnLocationUpdateListener onLocationUpdateListener;
public final String TAG = getClass().getSimpleName();
private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
GoogleApiClient googleApiClient;
LocationRequest mLocationRequest;
Location mCurrentLocation;
private static long INTERVAL = 1000 * 10;
private static long FASTEST_INTERVAL = 1000 * 5;
FragmentActivity mActivity;
private boolean isLiveUpdate = false;
PendingResult<LocationSettingsResult> result;
/**
* Checking permission and connect with Google Location service
* #param activity
*/
public GPSController(FragmentActivity activity) {
this.mActivity = activity;
if(PermissionManager.checkPermission(mActivity,PermissionManager.ACCESS_LOCATION))
{
if (!isGooglePlayServicesAvailable()) {
CustomLogHandler.printInfolog("checking googleplayservice : ", "false");
((BaseActivity)mActivity).showAlertDialog(mActivity, mActivity.getString(R.string.app_name), mActivity.getString(R.string.play_service_not_found));
} else {
CustomLogHandler.printInfolog("checking googleplayservice : ", "true");
createLocationRequest();
initFuseAPI();
}
}
else
{
PermissionManager.askForPermission(PermissionManager.ACCESS_LOCATION,mActivity);
}
}
public void connectForLocation()
{
createLocationRequest();
initFuseAPI();
}
/**
* Turn on Live update of location on given interval
* #param value
* #param INTERVAL
* #param FASTEST_INTERVAL
*/
public void turnOnLiveUpdate(boolean value,long INTERVAL,long FASTEST_INTERVAL)
{
isLiveUpdate = value;
this.INTERVAL = INTERVAL;
this.FASTEST_INTERVAL = FASTEST_INTERVAL;
}
/**
* Turn off live update of location
*/
public void turnOffLiveUpdate()
{
isLiveUpdate = false;
}
/**
* Disconnect from Google location service
*/
public void disconnect()
{
try {
Log.d(TAG, "onStop fired ..............");
googleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " +googleApiClient.isConnected());
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Resume Location update service if stopped
*/
public void onResumeUpdate()
{
try {
if(googleApiClient != null) {
if (googleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
public void setLocatonUpdateListener(OnLocationUpdateListener onLocationUpdateListener)
{
this.onLocationUpdateListener = onLocationUpdateListener;
}
/**
* Create location update request
*/
protected void createLocationRequest() {
try {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Initialize google location service
*/
void initFuseAPI()
{
try
{
googleApiClient = new GoogleApiClient.Builder(mActivity)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Log.d(TAG, "initFuseAPI fired ..............");
googleApiClient.connect();
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Check Google location service is available or not
* #return
*/
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mActivity);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, mActivity, 0).show();
return false;
}
}
/**
* called when connected with google location service
* #param bundle
*/
#Override
public void onConnected( Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + googleApiClient.isConnected());
LocationManager manager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE );
boolean statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(statusOfGPS) {
startLocationUpdates();
}else
{
enableGpsService();
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed( ConnectionResult connectionResult) {
}
/**
* Location update received here
* #param location
*/
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
SetLocation();
}
void enableGpsService()
{
try
{
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult( LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
//already connected to GPS
startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by
// showing the user a dialog.
try {
status.startResolutionForResult(mActivity, PermissionManager.REQUEST_LOCATION);
startLocationUpdates();
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
//redirect user to setting screen, manually user can enble GPS
mActivity.startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
break;
}
}
});
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Request location update service
*/
public void startLocationUpdates()
{
try {
//check required even you checked it previously
if (PermissionManager.checkPermission(mActivity, PermissionManager.ACCESS_LOCATION))
{
fusedLocationProviderApi.requestLocationUpdates(googleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
} else {
PermissionManager.askForPermission(PermissionManager.ACCESS_LOCATION, mActivity);
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Stop location update
*/
public void stopLocationUpdates() {
try {
if(googleApiClient != null) {
fusedLocationProviderApi.removeLocationUpdates(
googleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* set location values received
*/
private void SetLocation()
{
try {
Log.d(TAG, "UI update initiated .............");
if (null != mCurrentLocation) {
onLocationUpdateListener.onLocationUpdate(mCurrentLocation);
/**isLiveUpdate = true for Live update **/
if (!isLiveUpdate) {
fusedLocationProviderApi.removeLocationUpdates(googleApiClient,this);
}
googleApiClient.disconnect();
//mCurrentLocation.getAccuracy()
//mCurrentLocation.getProvider()
} else {
Log.d(TAG, "location is null ...............");
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
public Location getLocation(){
return mCurrentLocation;
}
public static List<Address> getAddress(Double mLat, Double mLang, Context context)
{
List<Address> addresses = null;
try
{
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
addresses = geocoder.getFromLocation(mLat, mLang, 1);
}catch (Exception e)
{
e.printStackTrace();
}
return addresses;
}
/**
* For receive location update
*/
public interface OnLocationUpdateListener {
void onLocationUpdate(Location mCurrentLocation);
}
}
call into this service class like this ..
gpsController = new GPSController(getActivity());
gpsController.setLocatonUpdateListener(this);
if (gpsController != null)
gpsController.onResumeUpdate();
public void setLocatonUpdateListener(OnLocationUpdateListener onLocationUpdateListener) {
this.onLocationUpdateListener = onLocationUpdateListener;
}
and also implement this into class ..
implements GPSController.OnLocationUpdateListener
#Override
public void onLocationUpdate(Location mCurrentLocation) {
CURRENT_LET = String.valueOf(mCurrentLocation.getLatitude());// both string variable to store value
CURRENT_LANG = String.valueOf(mCurrentLocation.getLongitude());
}

This implementation in Java works in a service class, after the fusedLocationClient has been initialized:
fusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
Location last_known_loction = task.getResult();
latitude = last_known_loction.getLatitude();
longitude = last_known_loction.getLongitude();
}
});

Related

Use ActivityContext in service for Custom Listner

PrimaryDashBoard where i use LocatinListener and retrieve the location from the service
public class PrimaryDashboard extends AppCompatActivity implements LocationListener {
public LatLng myLatLng=new LatLng(0.0,0.0);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_primary_dashboard);
try {
Intent i = new Intent(this, LocationManager.class);
startService(i);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onLocationChanged(Location location) {
myLatLng=new LatLng(location.getLatitude(),location.getLongitude());
}
#Override
public void GPSDisabled(String errorMessage) {
}
#Override
public void GPSEnabled() {
}
}
Here is LocationListner
public interface LocationListener {
public void onLocationChanged(Location location);
public void GPSDisabled(String errorMessage);
public void GPSEnabled();
}
Here is my Service where i want to initilized the LocationListner and want to update the location values from the listners
public class LocationManager extends IntentService {
private static final String TAG = LocationManager.class.getSimpleName();
// Registered callbacks
public LocationListener locationUpdate;
public static final int REQUEST_CHECK_SETTINGS = 0x1;
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private Location mCurrentLocation;
private Boolean mRequestingLocationUpdates = false;
#SuppressLint("ServiceCast")
#Override
public int onStartCommand(#Nullable Intent intent, int flags, int startId) {
this.locationUpdate = (LocationListener) getApplicationContext();
mRequestingLocationUpdates = false;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getApplicationContext());
mSettingsClient = LocationServices.getSettingsClient(getApplicationContext());
createLocationCallback();
createLocationRequest();
buildLocationSettingsRequest();
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
startLocationUpdates();
}
return START_STICKY;
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
}
#SuppressLint("ServiceCast")
#Override
public void onCreate() {
super.onCreate();
}
public LocationManager() {
super("locationManager");
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
/**
* Creates a callback for receiving location events.
*/
private void createLocationCallback() {
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
mCurrentLocation = locationResult.getLastLocation();
PrefManager.getInstance(getApplicationContext()).setLastLatLng(Double.valueOf(locationResult.getLastLocation().getLatitude()), Double.valueOf(locationResult.getLastLocation().getLongitude()));
if (locationUpdate != null)
locationUpdate.onLocationChanged(locationResult.getLastLocation());
}
};
}
private void buildLocationSettingsRequest() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
}
private void startLocationUpdates() {
// Begin by checking if the device has the necessary location settings.
mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
#SuppressLint("MissingPermission")
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
LogCat.show("All location settings are satisfied.");
if (locationUpdate != null)
locationUpdate.GPSEnabled();
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
if (locationUpdate != null)
locationUpdate.GPSDisabled("Location settings are not satisfied. Attempting to upgrade location settings ");
LogCat.show("Location settings are not satisfied. Attempting to upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the
// result in onActivityResult().
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult((Activity) getApplicationContext(), REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
String errorMessage = "Location settings are inadequate, and cannot be " +
"fixed here. Fix in Settings.";
LogCat.show(errorMessage);
if (locationUpdate != null)
locationUpdate.GPSDisabled(errorMessage);
Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
mRequestingLocationUpdates = false;
}
}
});
}
}
This line of code create me a problem because it want Activity context, when it will not be a service and i pass activity Context it works perfect.
this.locationUpdate = (LocationListener) getApplicationContext();
Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to driver.com.driver.LocationComponents.LocationListener
java.lang.RuntimeException: Unable to create service driver.com.driver.LocationComponents.LocationManager: java.lang.ClassCastException: android.app.Application cannot be cast to driver.com.driver.LocationComponents.LocationListener
Firstly , Your application class does not implement the LocationListener interface so your are getting this error. You cannot get the Activity instance inside your intent service , because 1) It may no longer be active 2) Intent Service can be started from other services or broadcast receivers. In order to communicate the LocationListener methods with your activity , you need to use a LocalBroadcastManager.

How can I get my location at a certain time?

I would like to know how can I get my location (longitude and latitude,
I dont need a position on the map) at a certain time and in the most accurate way. For example when a disconnection between two devices happen.
I have seen many examples with the Google API but they are more focused on tracking rather than obtaining the coordinates at a certain time.
I have read in some sites that getLastKnownLocation isn`t very accurate.
Thanks in advance.
i make seperate class for get current location lat and long value.
used below class for location.
public class GPSController implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
{
OnLocationUpdateListener onLocationUpdateListener;
public final String TAG = getClass().getSimpleName();
private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
GoogleApiClient googleApiClient;
LocationRequest mLocationRequest;
Location mCurrentLocation;
private static long INTERVAL = 1000 * 10;
private static long FASTEST_INTERVAL = 1000 * 5;
FragmentActivity mActivity;
private boolean isLiveUpdate = false;
PendingResult<LocationSettingsResult> result;
/**
* Checking permission and connect with Google Location service
* #param activity
*/
public GPSController(FragmentActivity activity) {
this.mActivity = activity;
if(PermissionManager.checkPermission(mActivity,PermissionManager.ACCESS_LOCATION))
{
if (!isGooglePlayServicesAvailable()) {
CustomLogHandler.printInfolog("checking googleplayservice : ", "false");
((BaseActivity)mActivity).showAlertDialog(mActivity, mActivity.getString(R.string.app_name), mActivity.getString(R.string.play_service_not_found));
} else {
CustomLogHandler.printInfolog("checking googleplayservice : ", "true");
createLocationRequest();
initFuseAPI();
}
}
else
{
PermissionManager.askForPermission(PermissionManager.ACCESS_LOCATION,mActivity);
}
}
public void connectForLocation()
{
createLocationRequest();
initFuseAPI();
}
/**
* Turn on Live update of location on given interval
* #param value
* #param INTERVAL
* #param FASTEST_INTERVAL
*/
public void turnOnLiveUpdate(boolean value,long INTERVAL,long FASTEST_INTERVAL)
{
isLiveUpdate = value;
this.INTERVAL = INTERVAL;
this.FASTEST_INTERVAL = FASTEST_INTERVAL;
}
/**
* Turn off live update of location
*/
public void turnOffLiveUpdate()
{
isLiveUpdate = false;
}
/**
* Disconnect from Google location service
*/
public void disconnect()
{
try {
Log.d(TAG, "onStop fired ..............");
googleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " +googleApiClient.isConnected());
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Resume Location update service if stopped
*/
public void onResumeUpdate()
{
try {
if(googleApiClient != null) {
if (googleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
public void setLocatonUpdateListener(OnLocationUpdateListener onLocationUpdateListener)
{
this.onLocationUpdateListener = onLocationUpdateListener;
}
/**
* Create location update request
*/
protected void createLocationRequest() {
try {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Initialize google location service
*/
void initFuseAPI()
{
try
{
googleApiClient = new GoogleApiClient.Builder(mActivity)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Log.d(TAG, "initFuseAPI fired ..............");
googleApiClient.connect();
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Check Google location service is available or not
* #return
*/
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mActivity);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, mActivity, 0).show();
return false;
}
}
/**
* called when connected with google location service
* #param bundle
*/
#Override
public void onConnected( Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + googleApiClient.isConnected());
LocationManager manager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE );
boolean statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(statusOfGPS) {
startLocationUpdates();
}else
{
enableGpsService();
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed( ConnectionResult connectionResult) {
}
/**
* Location update received here
* #param location
*/
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
SetLocation();
}
void enableGpsService()
{
try
{
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult( LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
//already connected to GPS
startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by
// showing the user a dialog.
try {
status.startResolutionForResult(mActivity, PermissionManager.REQUEST_LOCATION);
startLocationUpdates();
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
//redirect user to setting screen, manually user can enble GPS
mActivity.startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
break;
}
}
});
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Request location update service
*/
public void startLocationUpdates()
{
try {
//check required even you checked it previously
if (PermissionManager.checkPermission(mActivity, PermissionManager.ACCESS_LOCATION))
{
fusedLocationProviderApi.requestLocationUpdates(googleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
} else {
PermissionManager.askForPermission(PermissionManager.ACCESS_LOCATION, mActivity);
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* Stop location update
*/
public void stopLocationUpdates() {
try {
if(googleApiClient != null) {
fusedLocationProviderApi.removeLocationUpdates(
googleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
/**
* set location values received
*/
private void SetLocation()
{
try {
Log.d(TAG, "UI update initiated .............");
if (null != mCurrentLocation) {
onLocationUpdateListener.onLocationUpdate(mCurrentLocation);
/**isLiveUpdate = true for Live update **/
if (!isLiveUpdate) {
fusedLocationProviderApi.removeLocationUpdates(googleApiClient,this);
}
googleApiClient.disconnect();
//mCurrentLocation.getAccuracy()
//mCurrentLocation.getProvider()
} else {
Log.d(TAG, "location is null ...............");
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
public Location getLocation(){
return mCurrentLocation;
}
public static List<Address> getAddress(Double mLat, Double mLang, Context context)
{
List<Address> addresses = null;
try
{
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
addresses = geocoder.getFromLocation(mLat, mLang, 1);
}catch (Exception e)
{
e.printStackTrace();
}
return addresses;
}
/**
* For receive location update
*/
public interface OnLocationUpdateListener {
void onLocationUpdate(Location mCurrentLocation);
}
}
then used in activity class like below...
private GPSController gpsController;
#Override
public void onStop() {
super.onStop();
if (gpsController != null)
gpsController.disconnect();
}
#Override
public void onPause() {
super.onPause();
if (gpsController != null)
gpsController.stopLocationUpdates();
}
#Override
public void onResume() {
super.onResume();
gpsController = new GPSController(getActivity());
gpsController.setLocatonUpdateListener(this);
if (gpsController != null)
gpsController.onResumeUpdate();
}
#Override
public void onLocationUpdate(Location mCurrentLocation) {
CURRENT_LET = String.valueOf(mCurrentLocation.getLatitude());
CURRENT_LANG = String.valueOf(mCurrentLocation.getLongitude());
loadMoreItems();
}
also pl note activity class implement this below interface ..
implements GPSController.OnLocationUpdateListener
and you can remove permission code if you not required.
add also add two permission into manifest file..
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

Location Updates using google play services and FusedLocationProviderClient

I want to get location updates on a "background service" using latest fused location provider client.I don't want to use the location listeners and Google API Client that all are using.
I also need to use location settings Api provided by google play services to check whether location setting are disable or enable on that "background service".Please help.
if we need to use fusion location api then we need to use Google API client, For the background service it is not an issue to use it, Following is the example which I used for getting location update in background, But one more thing as Google introduces 'DOZE' mode from 6.0 so I can not give surety give update when your device in 'DOZE' mode,
import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
/**
* Created By Dhaval Solanki
*/
public class ConnectionService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
String TAG = "ConnectionService";
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Location previousLocation;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
private Location mLastLocation;
private Context context;
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = getApplicationContext();
Log.i(TAG, "onStartCommand");
if (checkPermsion(context)) {
setupLocationService(context);
}
return Service.START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
ApplicationCLass.isServiceRunning = true;
}
#Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind");
ApplicationCLass.isServiceRunning = false;
return super.onUnbind(intent);
}
#Override
public void onDestroy() {
ApplicationCLass.isServiceRunning = false;
super.onDestroy();
}
private void setupLocationService(Context context) {
if (checkPlayServices()) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
createLocationRequest();
}
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest().create();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mGoogleApiClient.connect();
}
public boolean checkPermsion(Context context) {
int MyVersion = Build.VERSION.SDK_INT;
if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return false;
} else if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return false;
} else {
return true;
}
} else {
return true;
}
}
private boolean checkPlayServices() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if (result != ConnectionResult.SUCCESS) {
return false;
}
return true;
}
private void startLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (Prefs.getUserLat(context).trim().length() > 0 && Prefs.getUserLong(context).trim().length() > 0) {
} else {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
Prefs.setUserLat(context, String.valueOf(mLastLocation.getLatitude()));
Prefs.setUserLong(context, String.valueOf(mLastLocation.getLongitude()));
}
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "Connected to onConnected");
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connected to onConnectionSuspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connected to onConnectionFailed");
}
#Override
public void onLocationChanged(Location location) {
try {
Logger.print("onLocationChanged", "latitued :" + location.getLatitude() + " ,, Longitude " + location.getLongitude());
} catch (Exception e) {
e.printStackTrace();
}
}
}
One another alaram service continues runnning or not
import android.app.ActivityManager;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class AlarmService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
boolean isServiceRunning = false;
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (ConnectionService.class.getName().equals(service.service.getClassName())) {
isServiceRunning = true;
break;
}
}
Log.i("AlarmService", "Service is running " + isServiceRunning);
if(!isServiceRunning) {
startService(new Intent(getApplicationContext(),ConnectionService.class));
} else {
ConnectionService.checkConnectionAndConnect(getApplicationContext());
}
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public AlarmService() {
super("AlaramService");
}
}
And Finaly start service
private void checkAndStartService() {
final ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
new AsyncTask<Void, Void, Boolean>() {
boolean isServiceRunning = false;
#Override
protected Boolean doInBackground(Void... params) {
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (ConnectionService.class.getName().equals(service.service.getClassName())) {
isServiceRunning = true;
break;
}
}
return isServiceRunning;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
Log.i("onPostExecute", "Service running = " + aBoolean);
if (!aBoolean) {
startService(new Intent(ActivitySplash.this, ConnectionService.class));
Intent i = new Intent(ActivitySplash.this, AlarmService.class);
PendingIntent pi = PendingIntent.getService(ActivitySplash.this, 0, i, 0);
AlarmManager am = (AlarmManager) ActivitySplash.this.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi); // cancel any existing alarms
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60000, pi);
}
}
}.execute();
}
You can write the code for the intentService as given below. It has been considered that since it is running in the background, we would not show the permission dialogs.
public class GetLocationService extends IntentService
implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
public static String TAG = GetLocationService.class.getSimpleName();
private GoogleApiClient mGoogleApiClient;
public GetLocationService() {
super(TAG);
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* #param name Used to name the worker thread, important only for debugging.
*/
public GetLocationService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
Log.d(TAG, "disconnecting");
mGoogleApiClient.disconnect();
}
Log.d(TAG, "onHandleIntent");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationRequest locationRequestLow = LocationRequest.create();
locationRequestLow.setPriority(LocationRequest.PRIORITY_LOW_POWER);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_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.
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
} else {
Log.d(TAG, "permission denied");
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, location.toString());
}
}
You can extend the service class like
public class BackgroundLocationService extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener
You can check the full source code here BackgroundLocationService.java
For enable location settings
private void displayLocationSettingsRequest() {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000 / 2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(#NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(context, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException ignored) {
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
break;
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to
startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
//startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
displayLocationSettingsRequest();//keep asking
showToast("Location permission needed");
break;
}
break;
}
}
You can check location settings from Service and if location is off ,
LocationManager lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {}
if(!gps_enabled && !network_enabled) {
// notify user
// Either you can display a Notification(Recommended way) or you can show dialog with
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//It needs SYSTEM_ALERT_WINDOW permission. Add this permission in Manifest.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
}
Hi I have good understanding about location services and how we can use in it perfect way. See i'll give you idea about fused apis.
Just make sure follow the below steps. It is pretty nice and simple.
Step 1. Make this class
GoogleLocationService.java
public class GoogleLocationService {
private GoogleServicesCallbacks callbacks = new GoogleServicesCallbacks();
LocationUpdateListener locationUpdateListener;
Context activity;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;
public GoogleLocationService(Context activity, LocationUpdateListener locationUpdateListener) {
this.locationUpdateListener = locationUpdateListener;
this.activity = activity;
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
//Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addConnectionCallbacks(callbacks)
.addOnConnectionFailedListener(callbacks)
.addApi(LocationServices.API)
.build();
createLocationRequest();
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private class GoogleServicesCallbacks implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
if (connectionResult.getErrorCode() == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED) {
Toast.makeText(activity, "Google play service not updated", Toast.LENGTH_LONG).show();
}
locationUpdateListener.cannotReceiveLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
if (location.hasAccuracy()) {
if (location.getAccuracy() < 30) {
locationUpdateListener.updateLocation(location);
}
}
}
}
private static boolean locationEnabled(Context context) {
boolean gps_enabled = false;
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
ex.printStackTrace();
}
return gps_enabled;
}
private boolean servicesConnected(Context context) {
return isPackageInstalled(GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE, context);
}
private boolean isPackageInstalled(String packagename, Context context) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
public void startUpdates() {
/*
* Connect the client. Don't re-start any requests here; instead, wait
* for onResume()
*/
if (servicesConnected(activity)) {
if (locationEnabled(activity)) {
locationUpdateListener.canReceiveLocationUpdates();
startLocationUpdates();
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Unable to get your location.Please turn on your device Gps", Toast.LENGTH_LONG).show();
}
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Google play service not available", Toast.LENGTH_LONG).show();
}
}
//stop location updates
public void stopUpdates() {
stopLocationUpdates();
}
//start location updates
private void startLocationUpdates() {
if (checkSelfPermission(activity, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(activity, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, callbacks);
}
}
public void stopLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, callbacks);
}
}
public void startGoogleApi() {
mGoogleApiClient.connect();
}
public void closeGoogleApi() {
mGoogleApiClient.disconnect();
}
}
Step2. Make this interface
LocationUpdateListener.java
public interface LocationUpdateListener {
/**
* Called immediately the service starts if the service can obtain location
*/
void canReceiveLocationUpdates();
/**
* Called immediately the service tries to start if it cannot obtain location - eg the user has disabled wireless and
*/
void cannotReceiveLocationUpdates();
/**
* Called whenever the location has changed (at least non-trivially)
* #param location
*/
void updateLocation(Location location);
/**
* Called when GoogleLocationServices detects that the device has moved to a new location.
* #param localityName The name of the locality (somewhere below street but above area).
*/
void updateLocationName(String localityName, Location location);
}
Step 3. Make this Location service class
LocationService.java
public class LocationService extends Service {
private GoogleLocationService googleLocationService;
#Override
public void onCreate() {
super.onCreate();
//start the handler for getting locations
//create component
updateLocation(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
//get current location os user
private void updateLocation(Context context) {
googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
#Override
public void canReceiveLocationUpdates() {
}
#Override
public void cannotReceiveLocationUpdates() {
}
//update location to our servers for tracking purpose
#Override
public void updateLocation(Location location) {
if (location != null ) {
Timber.e("updated location %1$s %2$s", location.getLatitude(), location.getLongitude());
}
}
#Override
public void updateLocationName(String localityName, Location location) {
googleLocationService.stopLocationUpdates();
}
});
googleLocationService.startUpdates();
}
IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public LocationService getServerInstance() {
return LocationService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
//stop location updates on stopping the service
#Override
public void onDestroy() {
super.onDestroy();
if (googleLocationService != null) {
googleLocationService.stopLocationUpdates();
}
}
}
Edited Answer:
How to use service,
Start service in your main activity,like this
startService(new Intent(context, LocationService.class));
for stop,
stopService(new Intent(context, LocationService.class));
and declare in manifest like this,
<service
android:name=".service.location.LocationService"
android:enabled="true"></service>
Note: I have done this because i need location after killed the app.If you dont want service.Then,you can call directly below code in class where location need to be update and remove locationservice.
private GoogleLocationService googleLocationService;
googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
#Override
public void canReceiveLocationUpdates() {
}
#Override
public void cannotReceiveLocationUpdates() {
}
//update location to our servers for tracking purpose
#Override
public void updateLocation(Location location) {
if (location != null ) {
Timber.e("updated location %1$s %2$s", location.getLatitude(), location.getLongitude());
}
}
#Override
public void updateLocationName(String localityName, Location location) {
googleLocationService.stopLocationUpdates();
}
});
googleLocationService.startUpdates();
and call this onDestroy
if (googleLocationService != null) {
googleLocationService.stopLocationUpdates();
}
Remember Locationservice should be declare in manifest as well.
According to me this is the best solution.
Thanks hope this will help you
The question does not appear to be very specific. It seems like you're having trouble starting up with using location services.
The best idea would probably be checking out the Google samples (https://github.com/googlesamples/android-play-location) to better understand the mechanics.
I would probably start by implementing the simplest example (LocationUpdates). It uses the FusedLocationProvider and also checks if the settings are enabled, so it should fit your needs, or at least get you started.
If you really need to use a service you can check out LocationUpdatesForegroundService or LocationUpdatesPendingIntent. But I would strongly recommend to read and understand the first example before you do this.

Get LastKnownLocation in Android returns null

I am trying to fetch lastknown location but it is giving me null value. I tested whether GPS is enabled or not, it's returning true.
Even I went into Google Maps and pointed my location (thinking that location data might be cleared) but it still didn't work.
Here is my Code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
boolean isgps=locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Log.v("is GPs Enabled",isgps+"");
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
updateNewLocation(location);
}
private void updateNewLocation(Location location) {
TextView myLocationText=(TextView)findViewById(R.id.myLocation);
if(location!=null){
double lat=location.getLatitude();
double lng=location.getLongitude();
myLocationText.setText("lat:"+lat+"\nlong:"+lng);
Log.v("Location","lat:"+lat+"\nlong:"+lng);
}
}
hi why trying to use getLastKnownLocation.It return your previous latitude and longitude.Most probably it retrun you null.It takes time to update and it return previous lat lng.It could be very old or new old.Its not accurate and correct. So,Its better you go for new approach.
I'm just referring you google Fused api for location any kind of updation or current.Its very accurate.
How you can fused api in your project.See i'll give you small example.
Step 1. Make this class GoogleLocationService.java
public class GoogleLocationService {
private GoogleServicesCallbacks callbacks = new GoogleServicesCallbacks();
LocationUpdateListener locationUpdateListener;
Context activity;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;
public GoogleLocationService(Context activity, LocationUpdateListener locationUpdateListener) {
this.locationUpdateListener = locationUpdateListener;
this.activity = activity;
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
//Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addConnectionCallbacks(callbacks)
.addOnConnectionFailedListener(callbacks)
.addApi(LocationServices.API)
.build();
createLocationRequest();
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private class GoogleServicesCallbacks implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
if (connectionResult.getErrorCode() == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED) {
Toast.makeText(activity, "Google play service not updated", Toast.LENGTH_LONG).show();
}
locationUpdateListener.cannotReceiveLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
if (location.hasAccuracy()) {
if (location.getAccuracy() < 30) {
locationUpdateListener.updateLocation(location);
}
}
}
}
private static boolean locationEnabled(Context context) {
boolean gps_enabled = false;
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
ex.printStackTrace();
}
return gps_enabled;
}
private boolean servicesConnected(Context context) {
return isPackageInstalled(GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE, context);
}
private boolean isPackageInstalled(String packagename, Context context) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
public void startUpdates() {
/*
* Connect the client. Don't re-start any requests here; instead, wait
* for onResume()
*/
if (servicesConnected(activity)) {
if (locationEnabled(activity)) {
locationUpdateListener.canReceiveLocationUpdates();
startLocationUpdates();
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Unable to get your location.Please turn on your device Gps", Toast.LENGTH_LONG).show();
}
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Google play service not available", Toast.LENGTH_LONG).show();
}
}
//stop location updates
public void stopUpdates() {
stopLocationUpdates();
}
//start location updates
private void startLocationUpdates() {
if (checkSelfPermission(activity, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(activity, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, callbacks);
}
}
public void stopLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, callbacks);
}
}
public void startGoogleApi() {
mGoogleApiClient.connect();
}
public void closeGoogleApi() {
mGoogleApiClient.disconnect();
}
}
Step2. Make this interface
LocationUpdateListener.java
public interface LocationUpdateListener {
/**
* Called immediately the service starts if the service can obtain location
*/
void canReceiveLocationUpdates();
/**
* Called immediately the service tries to start if it cannot obtain location - eg the user has disabled wireless and
*/
void cannotReceiveLocationUpdates();
/**
* Called whenever the location has changed (at least non-trivially)
* #param location
*/
void updateLocation(Location location);
/**
* Called when GoogleLocationServices detects that the device has moved to a new location.
* #param localityName The name of the locality (somewhere below street but above area).
*/
void updateLocationName(String localityName, Location location);
}
Step 3. Use this piece of code where you want to get location
private GoogleLocationService googleLocationService;
googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
#Override
public void canReceiveLocationUpdates() {
}
#Override
public void cannotReceiveLocationUpdates() {
}
//update location to our servers for tracking purpose
#Override
public void updateLocation(Location location) {
if (location != null ) {
Timber.e("updated location %1$s %2$s", location.getLatitude(), location.getLongitude());
}
}
#Override
public void updateLocationName(String localityName, Location location) {
googleLocationService.stopLocationUpdates();
}
});
googleLocationService.startUpdates();
and call this onDestroy
if (googleLocationService != null) {
googleLocationService.stopLocationUpdates();
}
Thanks hope this help you.

Send GPS coordinates periodically

I am a windows application programmer and recently started learning android. I am planning to make an app that will send GPS coordinates periodically say after every 30 seconds after clicking "start" button and stop doing so by clicking "stop" button (I have already developed a web service accepting the data) . In windows I would use a timer and on every "tick" will find the GPS coordinates and send it. Please help in understanding how a similar thing can be done in android.
Please check how i'm using in my app and its working perfect.I'm using fused api for update location please follow few steps.
Step 1. Make this class
GoogleLocationService.java
public class GoogleLocationService {
private GoogleServicesCallbacks callbacks = new GoogleServicesCallbacks();
LocationUpdateListener locationUpdateListener;
Context activity;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;
public GoogleLocationService(Context activity, LocationUpdateListener locationUpdateListener) {
this.locationUpdateListener = locationUpdateListener;
this.activity = activity;
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
//Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addConnectionCallbacks(callbacks)
.addOnConnectionFailedListener(callbacks)
.addApi(LocationServices.API)
.build();
createLocationRequest();
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private class GoogleServicesCallbacks implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
if (connectionResult.getErrorCode() == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED) {
Toast.makeText(activity, "Google play service not updated", Toast.LENGTH_LONG).show();
}
locationUpdateListener.cannotReceiveLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
if (location.hasAccuracy()) {
if (location.getAccuracy() < 30) {
locationUpdateListener.updateLocation(location);
}
}
}
}
private static boolean locationEnabled(Context context) {
boolean gps_enabled = false;
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
ex.printStackTrace();
}
return gps_enabled;
}
private boolean servicesConnected(Context context) {
return isPackageInstalled(GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE, context);
}
private boolean isPackageInstalled(String packagename, Context context) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
public void startUpdates() {
/*
* Connect the client. Don't re-start any requests here; instead, wait
* for onResume()
*/
if (servicesConnected(activity)) {
if (locationEnabled(activity)) {
locationUpdateListener.canReceiveLocationUpdates();
startLocationUpdates();
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Unable to get your location.Please turn on your device Gps", Toast.LENGTH_LONG).show();
}
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Google play service not available", Toast.LENGTH_LONG).show();
}
}
//stop location updates
public void stopUpdates() {
stopLocationUpdates();
}
//start location updates
private void startLocationUpdates() {
if (checkSelfPermission(activity, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(activity, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, callbacks);
}
}
public void stopLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, callbacks);
}
}
public void startGoogleApi() {
mGoogleApiClient.connect();
}
public void closeGoogleApi() {
mGoogleApiClient.disconnect();
}
}
Step2. Make this interface
LocationUpdateListener.java
public interface LocationUpdateListener {
/**
* Called immediately the service starts if the service can obtain location
*/
void canReceiveLocationUpdates();
/**
* Called immediately the service tries to start if it cannot obtain location - eg the user has disabled wireless and
*/
void cannotReceiveLocationUpdates();
/**
* Called whenever the location has changed (at least non-trivially)
* #param location
*/
void updateLocation(Location location);
/**
* Called when GoogleLocationServices detects that the device has moved to a new location.
* #param localityName The name of the locality (somewhere below street but above area).
*/
void updateLocationName(String localityName, Location location);
}
Step 3. Call this on your oncreate
private GoogleLocationService googleLocationService;
googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
#Override
public void canReceiveLocationUpdates() {
}
#Override
public void cannotReceiveLocationUpdates() {
}
//update location to our servers for tracking purpose
#Override
public void updateLocation(Location location) {
if (location != null ) {
Timber.e("updated location %1$s %2$s", location.getLatitude(), location.getLongitude());
}
}
#Override
public void updateLocationName(String localityName, Location location) {
googleLocationService.stopLocationUpdates();
}
});
googleLocationService.startUpdates();
and call this onDestroy
if (googleLocationService != null) {
googleLocationService.stopLocationUpdates();
}
Hope this will help you to solve your problem.
Take a look to RxGpsService (An Android service to retrieve GPS locations and route stats using RxJava). It retrieves a RouteStats object which contains the current speed, distance, time elapsed and waypoints. Also you can play/stop the chrono in order to discard locations when chrono is stopped.

Categories

Resources