You just need to include this in your build.gradle file:
implementation "com.google.android.gms:play-services-location:15.0.1"
or if you're not using latest gradle version:
compile "com.google.android.gms:play-services-location:15.0.1"
Note: It's recommended to use Google Play services version 15.0.1 or higher, which includes bug fixes for this class. More details here.
https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient
Answer from Reza on Stack OverflowVideos
You just need to include this in your build.gradle file:
implementation "com.google.android.gms:play-services-location:15.0.1"
or if you're not using latest gradle version:
compile "com.google.android.gms:play-services-location:15.0.1"
Note: It's recommended to use Google Play services version 15.0.1 or higher, which includes bug fixes for this class. More details here.
https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient
In your build.gradle (Module: app), you need to add the following dependency:
dependencies {
//...
compile 'com.google.android.gms:play-services:11.0.0'
}
and rebuild your app so it can download the needed dependencies. The class FusedLocationProviderClient is included in this package.
You just need to call mFusedLocationClient.removeLocationUpdates(mLocationCallback) in onPause() of your Activity. However, there is a bit more to it than just that.
Use member variables for the FusedLocationProviderClient and LocationRequest in your main activity:
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
public class MainActivity extends AppCompatActivity
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
FusedLocationProviderClient mFusedLocationClient;
LocationRequest mLocationRequest;
//..........
Use a member variable for the LocationCallback as well:
LocationCallback mLocationCallback = new LocationCallback(){
@Override
public void onLocationResult(LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
Log.i("MainActivity", "Location: " + location.getLatitude() + " " + location.getLongitude());
}
};
};
Then, assign mFusedLocationClient in onCreate() :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
requestLocationUpdates();
//...............
}
Then in onResume(), if theFusedLocationProviderClient is set up, then use it.
@Override
public void onResume() {
if (mFusedLocationClient != null) {
requestLocationUpdates();
}
}
public void requestLocationUpdates() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(120000); // two minute interval
mLocationRequest.setFastestInterval(120000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
}
And finally, in onPause(), call removeLocationUpdates():
@Override
public void onPause() {
super.onPause();
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
}
After getting location just remove mFusedLocationClient.removeLocationUpdates as he mentioned in above answers.
if (mFusedLocationClient != null)
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
Looper will be called requestLocationUpdates until you remove it.
In my problem, I did as I mention above. Below is my code.
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
// GPS location can be null if GPS is switched off
if (location != null) {
mLocation = location;
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
} else {
startLocationUpdates();
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(HomeActivity.this, "Error trying to get last GPS location", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
});
and below is my requestLocationUpdates so I will get a request until the location is available.
private void startLocationUpdates() {
mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "All location settings are satisfied.");
getPackageManager().checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, getPackageName());
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
getLastLocationNewMethod();
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Attempting to upgrade " +
"location settings ");
try {
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(HomeActivity.this, 0x1);
} 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.";
Log.e(TAG, errorMessage);
Toast.makeText(HomeActivity.this, errorMessage, Toast.LENGTH_LONG).show();
// mRequestingLocationUpdates = false;
}
getLastLocationNewMethod(); // this method is where I can get location. It is calling above method.
}
});
}
Note: For more information here is GitHub Repo LINK
This is similar to my other answer here, updated to use the recently introduced FusedLocationProviderClient class.
In order to use a FusedLocationProviderClient in conjunction with a Google Map:
Wait until the Google Map is ready
Request the Location permission at runtime if needed
Request location updates once the permission is granted
Update the Google Map once the user's location is obtained
First ensure that you're using at least version 11 of Google Play Services, as older versions don't have the FusedLocationProviderClient class (newer versions will work as well):
dependencies {
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.android.gms:play-services-location:17.0.0'
//........
}
Note that the FusedLocationProviderClient is present in version 11.0.2, but due to bugs in the initial implementation, it's recommended that you only use this class on 11.6.0 and later. From the documentation:
Note: It's recommended to use Google Play services version 11.6.0 or higher, which includes bug fixes for this class.
Add the location permissions in the AndroidManifest.xml file, inside the manifest tag and outside of the application tag:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Add the API key to the AndroidManifest.xml inside the application tag:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIza___YOUR_KEY_HERE______"/>
Kotlin
Here is the full Activity class in Kotlin:
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
lateinit var mGoogleMap: GoogleMap
var mapFrag: SupportMapFragment? = null
lateinit var mLocationRequest: LocationRequest
var mLastLocation: Location? = null
internal var mCurrLocationMarker: Marker? = null
internal var mFusedLocationClient: FusedLocationProviderClient? = null
internal var mLocationCallback: LocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val locationList = locationResult.locations
if (locationList.isNotEmpty()) {
//The last location in the list is the newest
val location = locationList.last()
Log.i("MapsActivity", "Location: " + location.getLatitude() + " " + location.getLongitude())
mLastLocation = location
if (mCurrLocationMarker != null) {
mCurrLocationMarker?.remove()
}
//Place current location marker
val latLng = LatLng(location.latitude, location.longitude)
val markerOptions = MarkerOptions()
markerOptions.position(latLng)
markerOptions.title("Current Position")
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA))
mCurrLocationMarker = mGoogleMap.addMarker(markerOptions)
//move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11.0F))
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
supportActionBar?.title = "Map Location Activity"
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mapFrag = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFrag?.getMapAsync(this)
}
public override fun onPause() {
super.onPause()
//stop location updates when Activity is no longer active
mFusedLocationClient?.removeLocationUpdates(mLocationCallback)
}
override fun onMapReady(googleMap: GoogleMap) {
mGoogleMap = googleMap
mGoogleMap.mapType = GoogleMap.MAP_TYPE_HYBRID
mLocationRequest = LocationRequest()
mLocationRequest.interval = 120000 // two minute interval
mLocationRequest.fastestInterval = 120000
mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
//Location Permission already granted
mFusedLocationClient?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper())
mGoogleMap.isMyLocationEnabled = true
} else {
//Request Location Permission
checkLocationPermission()
}
} else {
mFusedLocationClient?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper())
mGoogleMap.isMyLocationEnabled = true
}
}
private fun checkLocationPermission() {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton(
"OK"
) { _, _ ->
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(
this@MapsActivity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_PERMISSIONS_REQUEST_LOCATION
)
}
.create()
.show()
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_PERMISSIONS_REQUEST_LOCATION
)
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>, grantResults: IntArray
) {
when (requestCode) {
MY_PERMISSIONS_REQUEST_LOCATION -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
mFusedLocationClient?.requestLocationUpdates(
mLocationRequest,
mLocationCallback,
Looper.myLooper()
)
mGoogleMap.setMyLocationEnabled(true)
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
}
return
}
}// other 'case' lines to check for other
// permissions this app might request
}
companion object {
val MY_PERMISSIONS_REQUEST_LOCATION = 99
}
}
Java
Here is the full Activity class in Java:
public class MapsActivity extends AppCompatActivity
implements OnMapReadyCallback {
GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
Location mLastLocation;
Marker mCurrLocationMarker;
FusedLocationProviderClient mFusedLocationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
getSupportActionBar().setTitle("Map Location Activity");
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
@Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(120000); // two minute interval
mLocationRequest.setFastestInterval(120000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mGoogleMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mGoogleMap.setMyLocationEnabled(true);
}
}
LocationCallback mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
List<Location> locationList = locationResult.getLocations();
if (locationList.size() > 0) {
//The last location in the list is the newest
Location location = locationList.get(locationList.size() - 1);
Log.i("MapsActivity", "Location: " + location.getLatitude() + " " + location.getLongitude());
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
//move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11));
}
}
};
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MapsActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mGoogleMap.setMyLocationEnabled(true);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
activity_maps.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".map.MapsActivity">
<fragment android:id="@+id/map"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".map.MapsActivity"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The user will be prompted to accept the Location permission:
The location will be updated on app launch, and every two minutes:

Extra note regarding AndroidX
If you are using AndroidX, you might need to add these lines to your gradle.properties file (see here for more info):
android.useAndroidX=true
android.enableJetifier=true
For get current location. use below code .
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//Please allow Location Permission
return;
}
FusedLocationProviderClient fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
fusedLocationProviderClient.getCurrentLocation(PRIORITY_HIGH_ACCURACY, new CancellationToken() {
@Override
public boolean isCancellationRequested() {
return false;
}
@NonNull
@Override
public CancellationToken onCanceledRequested(@NonNull OnTokenCanceledListener onTokenCanceledListener) {
return null;
}
}).addOnSuccessListener(location -> {
currentLocation = location;
// use this current location
});