Getting user’s current location is the most important task in apps those provides services like food ordering, transportation, health tracking, social networking or lot more. This location information mainly based on getting user’s latitude & longitude. Using latitude & longitude values, you can easily determine the exact location of a user. It may seem a lot of programming efforts on doing this, but thankfully the android framework itself provides a location API called Fused Location Provider to shorten our job. So in this tutorial, we’ll be learning on getting user’s current location (latitude & longitude) using Java.
Latitude and Longitude
Latitude and longitude are angles that uniquely define points on a sphere. Together, the angles comprise a coordinate scheme that can locate or identify geographic positions on the surfaces of planets such as the earth.
Fused Location Provider
The fused location provider retrieves the device’s last known location. The fused location provider is one of the location APIs in Google Play services. It manages the underlying location technology and provides a simple API so that you can specify requirements at a high level, like high accuracy or low power. Some advantages of using this API are:
- It provides simple and easy to use APIs.
- Provides high accuracy over other options.
- Utilizes low power by choosing the most efficient way to access the location.
You can directly download the full Android Studio Project below, but I would suggest to read the article first for your better understanding.
Download Source Code for Detecting Location
Download the Android Studio source code of Detect Current Latitude & Longitude using Java in AndroidSize: 141.79 Kb
Add Necessary Dependencies
For using Fused Location Provider in your project you will have to add the below dependency in our app level build.gradle file
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
...
...
...
implementation 'com.google.android.gms:play-services-location:17.0.0'
}
The time I’m writing this article, version 17.0.0 is the stable version of this library. You should use the latest library always. You can find the latest library version from Release Notes.
Request Location Permissions
Apps that use location services must request location permissions. Android offers two location permissions: ACCESS_COARSE_LOCATION
and ACCESS_FINE_LOCATION
. The permission you choose determines the accuracy of the location returned by the API. We will use both of them to get the most relevant location information.
Add these permissions in your AndroidManifest.xml like below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.frsarker.locationfinder">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
It’s not all just by adding permissions into the manifest file. Critical permissions like Location must be requested in the runtime.
Request Location Permissions in Runtime
As you may know that from Android 6.0 (Marshmallow) you must request permissions for important access in the runtime. Cause it’s a security issue where while installing an application, user may not clearly understand about an important permission of their device. As we need location information of the user so we’ll need to implement the permission request also in runtime. But before that, let me clear the steps how we’ll request permission and when. The following methods will be interlinked.
private boolean checkPermissions() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true;
}
return false;
}
This method will tell us whether or not the user grant us to access ACCESS_COARSE_LOCATION
and ACCESS_FINE_LOCATION
. Now if the user didn’t grant the permissions to access his location, we will request him to allow.
private void requestPermissions() {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_ID
);
}
The PERMISSION_ID is an unique Integer value. By calling this method, a prompt will be displayed to user to allow Location Access by your App.
Then we will have to detect whether or not the user granted the permissions or not. Because if he allow, our App will have to start detecting the location information instantly.
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_ID) {
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
// Granted. Start getting the location information
}
}
}
Now user may granted our requested permissions, but nothing can be done if he turns off the Location of his device. So we need something to check if his device location is turned on or off.
private boolean isLocationEnabled(){
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER
);
}
Great. Now lets complete the other codes required for detecting user’s current location.
Detect Current Location using Fused Location Provider API
It’s the time we will merge everything and detect Current Location information – Latitude & Longitude. Code of my MainActivity.java below:
package com.frsarker.locationfinder;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.widget.TextView;
import android.widget.Toast;
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;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
public class MainActivity extends AppCompatActivity {
int PERMISSION_ID = 44;
FusedLocationProviderClient mFusedLocationClient;
TextView latTextView, lonTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latTextView = findViewById(R.id.latTextView);
lonTextView = findViewById(R.id.lonTextView);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
getLastLocation();
}
@SuppressLint("MissingPermission")
private void getLastLocation(){
if (checkPermissions()) {
if (isLocationEnabled()) {
mFusedLocationClient.getLastLocation().addOnCompleteListener(
new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
Location location = task.getResult();
if (location == null) {
requestNewLocationData();
} else {
latTextView.setText(location.getLatitude()+"");
lonTextView.setText(location.getLongitude()+"");
}
}
}
);
} else {
Toast.makeText(this, "Turn on location", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
} else {
requestPermissions();
}
}
@SuppressLint("MissingPermission")
private void requestNewLocationData(){
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(0);
mLocationRequest.setFastestInterval(0);
mLocationRequest.setNumUpdates(1);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mFusedLocationClient.requestLocationUpdates(
mLocationRequest, mLocationCallback,
Looper.myLooper()
);
}
private LocationCallback mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
Location mLastLocation = locationResult.getLastLocation();
latTextView.setText(mLastLocation.getLatitude()+"");
lonTextView.setText(mLastLocation.getLongitude()+"");
}
};
private boolean checkPermissions() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true;
}
return false;
}
private void requestPermissions() {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_ID
);
}
private boolean isLocationEnabled() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER
);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_ID) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocation();
}
}
}
@Override
public void onResume(){
super.onResume();
if (checkPermissions()) {
getLastLocation();
}
}
}
And finally that’s my activity_main.xml with Two TextViews for displaying the Latitude & Longitude.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/latTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Latitude: "/>
<TextView
android:id="@+id/lonTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Longitude: "/>
</LinearLayout>
Run it and check if it can display your current location or not.