Created
March 15, 2018 05:01
-
-
Save kedarmp/26b5697f257d5d0d9f8f2cefe9944ddc to your computer and use it in GitHub Desktop.
Sample Code to fetch location on Android using FusedLocationProviderClient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.domain.apps.smileyview; | |
import android.Manifest; | |
import android.annotation.SuppressLint; | |
import android.content.IntentSender; | |
import android.content.pm.PackageManager; | |
import android.location.Location; | |
import android.os.Bundle; | |
import android.support.annotation.NonNull; | |
import android.support.v4.app.ActivityCompat; | |
import android.support.v4.content.ContextCompat; | |
import android.support.v7.app.AlertDialog; | |
import android.support.v7.app.AppCompatActivity; | |
import android.util.Log; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
import com.google.android.gms.common.api.ResolvableApiException; | |
import com.google.android.gms.location.FusedLocationProviderClient; | |
import com.google.android.gms.location.LocationAvailability; | |
import com.google.android.gms.location.LocationCallback; | |
import com.google.android.gms.location.LocationRequest; | |
import com.google.android.gms.location.LocationResult; | |
import com.google.android.gms.location.LocationServices; | |
import com.google.android.gms.location.LocationSettingsRequest; | |
import com.google.android.gms.location.LocationSettingsResponse; | |
import com.google.android.gms.location.SettingsClient; | |
import com.google.android.gms.tasks.OnFailureListener; | |
import com.google.android.gms.tasks.OnSuccessListener; | |
import com.google.android.gms.tasks.Task; | |
//See https://github.com/codepath/android_guides/wiki/Retrieving-Location-with-LocationServices-API | |
public class LocationActivity extends AppCompatActivity { | |
private static final String TAG = "LocationActivity"; | |
TextView lastLocation, locUpdate; | |
FusedLocationProviderClient fusedClient; | |
private LocationRequest mRequest; | |
private LocationCallback mCallback; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_location); | |
lastLocation = findViewById(R.id.lastLoc); | |
locUpdate = findViewById(R.id.locUpdate); | |
mCallback = new LocationCallback() { | |
//This callback is where we get "streaming" location updates. We can check things like accuracy to determine whether | |
//this latest update should replace our previous estimate. | |
@Override | |
public void onLocationResult(LocationResult locationResult) { | |
if (locationResult == null) { | |
Log.d(TAG, "locationResult null"); | |
return; | |
} | |
Log.d(TAG, "received " + locationResult.getLocations().size() + " locations"); | |
for (Location loc : locationResult.getLocations()) { | |
locUpdate.append("\n"+ loc.getProvider() + ":Accu:(" + loc.getAccuracy() + "). Lat:" + loc.getLatitude() + ",Lon:" + loc.getLongitude()); | |
} | |
} | |
@Override | |
public void onLocationAvailability(LocationAvailability locationAvailability) { | |
Log.d(TAG, "locationAvailability is " + locationAvailability.isLocationAvailable()); | |
super.onLocationAvailability(locationAvailability); | |
} | |
}; | |
//permissions | |
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) | |
!= PackageManager.PERMISSION_GRANTED) { | |
//request permission. | |
//However check if we need to show an explanatory UI first | |
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) { | |
showRationale(); | |
} else { | |
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, | |
Manifest.permission.ACCESS_NETWORK_STATE}, 2); | |
} | |
} else { | |
//we already have the permission. Do any location wizardry now | |
locationWizardry(); | |
} | |
} | |
@SuppressLint("MissingPermission") | |
private void locationWizardry() { | |
fusedClient = LocationServices.getFusedLocationProviderClient(this); | |
//Initially, get last known location. We can refine this estimate later | |
fusedClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() { | |
@Override | |
public void onSuccess(Location location) { | |
if (location != null) { | |
String loc = location.getProvider() + ":Accu:(" + location.getAccuracy() + "). Lat:" + location.getLatitude() + ",Lon:" + location.getLongitude(); | |
lastLocation.setText(loc); | |
} | |
} | |
}); | |
//now for receiving constant location updates: | |
createLocRequest(); | |
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() | |
.addLocationRequest(mRequest); | |
//This checks whether the GPS mode (high accuracy,battery saving, device only) is set appropriately for "mRequest". If the current settings cannot fulfil | |
//mRequest(the Google Fused Location Provider determines these automatically), then we listen for failutes and show a dialog box for the user to easily | |
//change these settings. | |
SettingsClient client = LocationServices.getSettingsClient(LocationActivity.this); | |
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build()); | |
task.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
if (e instanceof ResolvableApiException) { | |
// Location settings are not satisfied, but this can be fixed | |
// by showing the user a dialog. | |
try { | |
// Show the dialog by calling startResolutionForResult(), | |
// and check the result in onActivityResult(). | |
ResolvableApiException resolvable = (ResolvableApiException) e; | |
resolvable.startResolutionForResult(LocationActivity.this, 500); | |
} catch (IntentSender.SendIntentException sendEx) { | |
// Ignore the error. | |
} | |
} | |
} | |
}); | |
//actually start listening for updates: See on Resume(). It's done there so that conveniently we can stop listening in onPause | |
} | |
@Override | |
protected void onResume() { | |
super.onResume(); | |
startLocationUpdates(); | |
} | |
@Override | |
protected void onPause() { | |
super.onPause(); | |
fusedClient.removeLocationUpdates(mCallback); | |
} | |
@SuppressLint("MissingPermission") | |
protected void startLocationUpdates() { | |
fusedClient.requestLocationUpdates(mRequest, mCallback, null); | |
} | |
protected void createLocRequest() { | |
mRequest = new LocationRequest(); | |
mRequest.setInterval(10000);//time in ms; every ~10 seconds | |
mRequest.setFastestInterval(5000); | |
mRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); | |
} | |
@Override | |
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { | |
switch (requestCode) { | |
case 2: { | |
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
Toast.makeText(this, "Thanks bud", Toast.LENGTH_SHORT).show(); | |
locationWizardry(); | |
} else { | |
Toast.makeText(this, "C'mon man we really need this", Toast.LENGTH_SHORT).show(); | |
} | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
private void showRationale() { | |
AlertDialog dialog = new AlertDialog.Builder(this).setMessage("We need this, Just suck it up and grant us the" + | |
"permission :)").setPositiveButton("Sure", (dialogInterface, i) -> | |
{ | |
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 2); | |
dialogInterface.dismiss(); | |
}) | |
.create(); | |
dialog.show(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment