Many apps in Android uses user’s locations be it for ordering cabs or delivering food and items. Here, a simple android app that 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 an error on an emulator. So, please try to run it on an actual device!
Approach
Step 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:
ACCESS_COARSE_LOCATION: It provides location accuracy within a city block.
<uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION”/>
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” />
In case the app needs to access the user’s location while the app is running in the 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 the AndroidManifest.xml file looks like:
XML
<? xml version = "1.0" encoding = "utf-8" ?> package = "com.example.getuserlocation" > < uses-permission android:name = "android.permission.ACCESS_COARSE_LOCATION" /> < uses-permission android:name = "android.permission.ACCESS_FINE_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/Theme.GetUserLocation" > < 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 > |
Also, as Google’s PlayServices will be used to access the device’s location, add it in dependencies, in the Build.Gradle (app) file:
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’
Step 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 the 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:
XML
<? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:background = "#4caf50" android:gravity = "center" android:orientation = "vertical" > < ImageView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:paddingBottom = "120dp" android:src = "@drawable/gfgimage" /> < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:fontFamily = "sans-serif-black" android:text = "Latitude:" /> < TextView android:id = "@+id/latTextView" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Latitude will be here! " android:textColor = "#f5f5f5" /> < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:fontFamily = "sans-serif-black" android:text = "Longitude:" /> < TextView android:id = "@+id/lonTextView" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Longitude will be here! " android:textColor = "#f5f5f5" /> </ LinearLayout > |
Output:
Step 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 the 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 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 the MainActivity.java file.
Java
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 androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; 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 { // 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.latTextView); longitTextView = findViewById(R.id.lonTextView); 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 { latitudeTextView.setText(location.getLatitude() + "" ); longitTextView.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(); latitudeTextView.setText( "Latitude: " + mLastLocation.getLatitude() + "" ); longitTextView.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 request for 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(); } } } |
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 this: