How to get user location in Android

Many apps in Android uses user’s location be it for ordering cabs or delivering food and items. Here, a simple android app which would return the user’s latitude and longitude is made. Once the latitude and longitude are known, the exact location on Google Maps can be seen using the following query:

https://www.google.com/maps/search/?api=1&query=,

Note: The app will run completely fine on an actual device but might show error on an emulator. So, please try to run it on an actual device!
Approach:

1. Acquiring Permissions:

  • Since using the user’s permission is a matter concerned with high privacy, first acquire the user’s permission to use their location by requesting them for it. From Android 6.0(Marshmallow), the concept of run-time permissions was rolled in and so the same will be used for getting permission.
  • Any of the following permissions can be used for this:
    1. ACCESS_COARSE_LOCATION: It provides location accuracy to within a city block.
      <uses-permission
        android:name="android.permission.ACCESS_COARSE_LOCATION"
       />
      
    2. ACCESS_FINE_LOCATION: It provides a more accurate location. To do this, it needs to do some heavy lifting so it’s recommended to use this only when we need an accurate location.
      <uses-permission
        android:name="android.permission.ACCESS_FINE_LOCATION"
       />
      

    You can implement either of it in your application.



  • In case the app needs to access user’s location while the app is running in background, we need to add the following permission along with the above ones:
    <uses-permission
      android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
     />
    
  • We need to add all these permissions in the AndroidManifest.xml. To access this file, select your project view as Android and click on:

    app->manifests->AndroidManifest.xml.

  • After adding all the permissions, this is how AndroidManifest.xml file looks like:

    AndroidManifest.xml

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
        package="com.example.locationtry">
      
        <uses-permission
          android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission
          android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        <uses-permission
          android:name="android.permission.ACCESS_BACKGROUND_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>

    chevron_right

    
    

  • Also, as Google’s PlayServices will be used to access the device’s location, add it in dependencies, in the Build.Gradle file:

    build.gradle (:app)

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    dependencies
    {
        implementation
          fileTree(dir
                   : 'libs', include
                   : [ '*.jar' ])
       
            implementation
              'androidx.appcompat:appcompat:1.1.0'
            implementation
              'androidx.constraintlayout:constraintlayout:1.1.3'
       
            <!-- implementing Google's
                 play-services-location -->
            implementation
              'com.google.android.gms:play-services-location:17.0.0'
              testImplementation 'junit:junit:4.12'
              androidTestImplementation 'androidx.test.ext:junit:1.1.1' 
              androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    }

    chevron_right

    
    

2. Designing the layout:
As the app is fairly simple, it would contain only the MainActivity and hence a single main layout. In the layout, add an ImageView and two TextViews which would be displaying user’s latitude and longitude. The latitude and longitude which would be displayed will be returned from the logic of our MainActivity which will be discussed next. Here’s how activity_main.xml looks like:

filter_none

edit
close

play_arrow

link
brightness_4
code

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:background="#4caf50">
  
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/gfg"
        android:paddingBottom="120dp"/>
  
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Latitude:"
        android:fontFamily="sans-serif-black"/>
  
    <TextView
        android:id="@+id/latTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#f5f5f5"
        android:text="Latitude will be here! "/>
  
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Longitude:"
        android:fontFamily="sans-serif-black"/>
  
    <TextView
        android:id="@+id/lonTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#f5f5f5"
        android:text="Longitude will be here! "/>
  
</LinearLayout>

chevron_right


Output:

3. Writing the logic:

  • To work on the main logic of our app, we will follow the following key points:
    • Check if the permissions we request are enabled.
    • Else request the permissions.
    • If permissions are accepted and location is enabled, get the last location of the user.
  • In order to get the last location of the user, make use of the Java public class FusedLocationProviderClient. It is actually a location service that combines GPS location and network location to achieve a balance between battery consumption and accuracy. GPS location is used to provide accuracy and network location is used to get location when the user is indoors.
  • In conjunction with FusedLocationProviderClient, LocationRequest public class is used to get the last known location. On this LocationRequest object, set a variety of methods such as set the priority of how accurate the location to be or in how many intervals, request of the location is to be made.
  • If a very high accuracy is required, use PRIORITY_HIGH_ACCURACY as an argument to the setPriority(int) method. For a city level accuracy(low accuracy), use PRIORITY_LOW_POWER.
  • Once the LocationRequest object is ready, set it on the FusedLocationProviderClient object to get the final location.

Let’s now look at MainActivity.java file.

MainActivity.java

filter_none

edit
close

play_arrow

link
brightness_4
code

package com.example.locationtry;
  
// importing the necessities
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 android.os.Looper;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.appcompat
    .app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import com.google.android
    .gms.tasks
    .OnCompleteListener;
import com.google.android
    .gms.tasks.Task;
import android.widget.TextView;
import android.widget.Toast;
import android.content.Context;
import android.content.Intent;
  
public class MainActivity
    extends AppCompatActivity {
  
    // initializing
    // FusedLocationProviderClient
    // object
    FusedLocationProviderClient
        mFusedLocationClient;
  
    // Initializing other items
    // from layout file
    TextView latitudeTextView, longitTextView;
    int PERMISSION_ID = 44;
  
    @Override
    protected void onCreate(
        Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        latitudeTextView = findViewById(R.id.lat);
        longitTextView = findViewById(R.id.lon);
  
        mFusedLocationClient
            = LocationServices
                  .getFusedLocationProviderClient(this);
  
        // method to get the location
        getLastLocation();
    }
  
    @SuppressLint("MissingPermission")
    private void getLastLocation()
    {
        // check if permissions are given
        if (checkPermissions()) {
  
            // check if location is enabled
            if (isLocationEnabled()) {
  
                // getting last
                // location from
                // FusedLocationClient
                // object
                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,
                        "Please turn on"
                            + " your location...",
                        Toast.LENGTH_LONG)
                    .show();
  
                Intent intent
                    = new Intent(
                        Settings
                            .ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(intent);
            }
        }
        else {
            // if permissions aren't available,
            // request for permissions
            requestPermissions();
        }
    }
  
    @SuppressLint("MissingPermission")
    private void requestNewLocationData()
    {
  
        // Initializing LocationRequest
        // object with appropriate methods
        LocationRequest mLocationRequest
            = new LocationRequest();
        mLocationRequest.setPriority(
            LocationRequest
                .PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(5);
        mLocationRequest.setFastestInterval(0);
        mLocationRequest.setNumUpdates(1);
  
        // setting LocationRequest
        // on FusedLocationClient
        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(
                          "Latitude: "
                          + mLastLocation
                                .getLatitude()
                          + "");
                  lonTextView
                      .setText(
                          "Longitude: "
                          + mLastLocation
                                .getLongitude()
                          + "");
              }
          };
  
    // method to check for permissions
    private boolean checkPermissions()
    {
        return ActivityCompat
                   .checkSelfPermission(
                       this,
                       Manifest.permission
                           .ACCESS_COARSE_LOCATION)
            == PackageManager.PERMISSION_GRANTED
  
            && ActivityCompat
                       .checkSelfPermission(
                           this,
                           Manifest.permission
                               .ACCESS_FINE_LOCATION)
                   == PackageManager.PERMISSION_GRANTED;
  
        // If we want background location
        // on Android 10.0 and higher,
        // use:
        /* ActivityCompat
                .checkSelfPermission(
                    this,
                    Manifest.permission
                        .ACCESS_BACKGROUND_LOCATION)
            == PackageManager.PERMISSION_GRANTED
        */
    }
  
    // method to requestfor permissions
    private void requestPermissions()
    {
        ActivityCompat.requestPermissions(
            this,
            new String[] {
                Manifest.permission
                    .ACCESS_COARSE_LOCATION,
                Manifest.permission
                    .ACCESS_FINE_LOCATION },
            PERMISSION_ID);
    }
  
    // method to check
    // if location is enabled
    private boolean isLocationEnabled()
    {
        LocationManager
            locationManager
            = (LocationManager)getSystemService(
                Context.LOCATION_SERVICE);
  
        return locationManager
                   .isProviderEnabled(
                       LocationManager.GPS_PROVIDER)
            || locationManager
                   .isProviderEnabled(
                       LocationManager.NETWORK_PROVIDER);
    }
  
    // If everything is alright then
    @Override
    public void
    onRequestPermissionsResult(
        int requestCode,
        @NonNull String[] permissions,
        @NonNull 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();
        }
    }
}

chevron_right


Output:

Note: In order to see this location in Google Maps, just formulate the query as:

https://www.google.com/maps/search/?api=1&query=37.4219983, -122.084

This will look like:

Attention reader! Don’t stop learning now. Get hold of all the important Java and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.