Skip to content

Instantly share code, notes, and snippets.

@piyush-malaviya
Created May 17, 2019 04:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piyush-malaviya/b94d923e1311d2fe0f57b92c016740f0 to your computer and use it in GitHub Desktop.
Save piyush-malaviya/b94d923e1311d2fe0f57b92c016740f0 to your computer and use it in GitHub Desktop.
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.*;
public class LocationHelper implements GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {
private static final String TAG = LocationHelper.class.getSimpleName();
private static final int REQUEST_CODE_LOCATION_SETTING = 9876;
private Context context;
private GoogleApiClient googleApiClient;
private Location lastKnownLocation;
private LocationUpdateListener locationUpdateListener;
// location request parameter
private long interval = 0; // time in millisecond
private long fastestInterval = 0; // time in millisecond
private float smallestDisplacement = 0; // meter
private int priority = LocationRequest.PRIORITY_HIGH_ACCURACY;
private boolean isContinuousRequest = false;
private LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location.toString());
//Preferences.getInstance().saveLastLocation(location);
if (locationUpdateListener != null) {
locationUpdateListener.onLocationUpdate(location);
}
}
};
private GoogleApiClient.ConnectionCallbacks continuousRequest = new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
if (isLocationEnabled(context)) {
startLocationUpdates();
} else {
enableLocationRequest();
}
}
@Override
public void onConnectionSuspended(int cause) {
}
};
private GoogleApiClient.ConnectionCallbacks singleRequest = new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
if (isLocationEnabled(context)) {
getLastKnownLocation();
} else {
enableLocationRequest();
}
}
@Override
public void onConnectionSuspended(int cause) {
}
};
public LocationHelper(Context context) {
this.context = context;
}
public static boolean isLocationEnabled(Context context) {
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
return locationManager != null && locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
/*public boolean isLocationEnabled(Context context) {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return false;
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}*/
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
private void setupGoogleApiClient(GoogleApiClient.ConnectionCallbacks connectionCallbacks) {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionCallbacks)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
}
public LocationHelper setInterval(long interval) {
this.interval = interval;
return this;
}
public LocationHelper setFastestInterval(long fastestInterval) {
this.fastestInterval = fastestInterval;
return this;
}
public LocationHelper setSmallestDisplacement(float smallestDisplacement) {
this.smallestDisplacement = smallestDisplacement;
return this;
}
public LocationHelper setPriority(int priority) {
this.priority = priority;
return this;
}
public LocationHelper setLocationUpdateListener(LocationUpdateListener locationUpdateListener) {
this.locationUpdateListener = locationUpdateListener;
return this;
}
public void stop() {
if (googleApiClient != null && googleApiClient.isConnected()) {
stopLocationUpdates();
}
}
/**
* create location request
*
* @return instance of LocationRequest
*/
private LocationRequest createLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(interval);
mLocationRequest.setFastestInterval(fastestInterval);
mLocationRequest.setSmallestDisplacement(smallestDisplacement);
mLocationRequest.setPriority(priority);
return mLocationRequest;
}
public void requestSingleLocation() {
isContinuousRequest = false;
// set google api client
setupGoogleApiClient(singleRequest);
}
private void getLastKnownLocation() {
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (googleApiClient == null || !googleApiClient.isConnected()) {
setupGoogleApiClient(singleRequest);
return;
}
lastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (lastKnownLocation != null) {
if (locationUpdateListener != null) {
locationUpdateListener.onLocationUpdate(lastKnownLocation);
}
if (googleApiClient != null) {
googleApiClient.disconnect();
}
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, createLocationRequest(), new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (locationUpdateListener != null) {
locationUpdateListener.onLocationUpdate(location);
}
if (googleApiClient != null && googleApiClient.isConnected()) {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, locationListener);
pendingResult.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
Log.e(TAG, "onResult Single (Stop): " + status);
if (status == Status.RESULT_SUCCESS) {
if (googleApiClient != null && googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
}
});
}
}
});
}
}
public void requestContinuousLocation() {
isContinuousRequest = true;
// set google api client
setupGoogleApiClient(continuousRequest);
}
private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (googleApiClient != null && googleApiClient.isConnected()) {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, createLocationRequest(), locationListener);
pendingResult.setResultCallback(this);
}
}
private void stopLocationUpdates() {
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, locationListener);
pendingResult.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
Log.e(TAG, "onResult (Stop): " + status);
if (status == Status.RESULT_SUCCESS) {
if (googleApiClient != null && googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
}
});
}
@Override
public void onResult(@NonNull Status status) {
Log.e(TAG, "onResult: " + status);
}
public void enableLocationRequest() {
if (googleApiClient == null) {
return;
}
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(createLocationRequest());
builder.setAlwaysShow(true); //this is the key ingredient
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
if (context instanceof Activity) {
status.startResolutionForResult((Activity) context, REQUEST_CODE_LOCATION_SETTING);
}
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_LOCATION_SETTING && resultCode == Activity.RESULT_OK) {
if (isContinuousRequest) {
requestContinuousLocation();
} else {
requestSingleLocation();
}
return true;
}
return false;
}
public interface LocationUpdateListener {
void onLocationUpdate(Location location);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment