askIT

Android Location service - Get Latitude, Longitude and Accuracy with LocationProvider

save.png Download source code get_latitude_longitude_and_accuracy_with_locationprovider

This tutorial will show how to get the latitude, longitude and accuracy in Android with LocationProvider. It's very easy with Androids class LocationProvider to retrive information about the users latitute, longitude and accuracy.

latitudelongitude.png
Fig: Latitude Longitude app.


Step 1. Create new project

Create a New project in Android Studio.

new_project.png
Fig: New project

Set target android devices to Phone and tablet Api 24: Android 7.0.

min_sdk.png
Fig: Minimum SDK

Select empty activity.

empty_activity.png
Fig: Select Empty Activity

Let the name be MainActivity.

create_empty.png
Fig: Create empty activity


Step 2. Add Play Service to app

Go to build.gradle. Under dependencies add google play services location like this:
implementation 'com.google.android.gms:play-services-location:15.0.1'

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "latlong.nettport.com.latitudelongitude"
        minSdkVersion 24
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    implementation 'com.google.android.gms:play-services-location:15.0.1'
}

play-services-location.png
Fig: build.gradle


Step 3. PermissionsRequester class

Create a new class PermissionsRequester.

package latlong.nettport.com.latitudelongitude;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;

import java.lang.ref.WeakReference;

public class PermissionsRequester {
    private static final String[] PERMISSIONS = {
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
    };

    private final WeakReference<Activity> activityWeakReference;

    static PermissionsRequester newInstance(@NonNull Activity activity) {
        WeakReference<Activity> activityWeakReference = new WeakReference<>(activity);
        return new PermissionsRequester(activityWeakReference);
    }

    private PermissionsRequester(@NonNull WeakReference<Activity> activityWeakReference) {
        this.activityWeakReference = activityWeakReference;
    }

    boolean hasPermissions() {
        Activity activity = activityWeakReference.get();
        if (activity != null) {
            for (String permission : PERMISSIONS) {
                if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    void requestPermissions() {
        Activity activity = activityWeakReference.get();
        if (activity != null) {
            ActivityCompat.requestPermissions(activity, PERMISSIONS, 0);
        }
    }

}

Step 4. Request permissions in Android Manifest

Go to Manifest. Add permissions for
android.permission.INTERNET android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_COARSE_LOCATION android.permission.ACCESS_FINE_LOCATION

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="latlong.nettport.com.latitudelongitude">

    <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>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

</manifest>

Step 5. Add LocationProvider class

Create a class named LocationProvider

package latlong.nettport.com.latitudelongitude;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class LocationProvider implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

    public abstract interface LocationCallback {
        public void handleNewLocation(Location location);
    }

    public static final String TAG = LocationProvider.class.getSimpleName();

    /*
    * Define a request code to send to Google Play services
    * This code is returned in Activity.onActivityResult
    */

    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

    private LocationCallback mLocationCallback;
    private Context mContext;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    public LocationProvider(Context context, LocationCallback callback) {
        mGoogleApiClient = new GoogleApiClient.Builder(context)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationCallback = callback;

        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(10 * 1000)        // 10 seconds, in milliseconds
                .setFastestInterval(1 * 1000); // 1 second, in milliseconds

        mContext = context;
    }

    public void connect() {
        mGoogleApiClient.connect();
    }

    public void disconnect() {
        if (mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.i(TAG, "Location services connected.");

        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            // public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                        int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            Toast.makeText(mContext, "Permission missing", Toast.LENGTH_LONG).show();
            return;
        }
        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (location == null) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
        else {
            mLocationCallback.handleNewLocation(location);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        /*
        * Google Play services can resolve some errors it detects.
        * If the error has a resolution, try sending an Intent to
        * start a Google Play services activity that can resolve
        * error.
        */

        if (connectionResult.hasResolution() && mContext instanceof Activity) {
            try {
                Activity activity = (Activity)mContext;
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
                /*
                * Thrown if Google Play services canceled the original
                * PendingIntent
                */

            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {
            /*
            * If no resolution is available, display a dialog to the
            * user with the error.
            */

            Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        mLocationCallback.handleNewLocation(location);
    }
}

Step 6. Edit design

Go to res -> layout -> activity_main.xml. Add 6 TextView.

design.png
Fig: Design

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TableRow
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <TextView
                    android:id="@+id/textViewLatitude"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Latitude:" />

                <TextView
                    android:id="@+id/textViewLatitudeValue"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="..." />
            </TableRow>

            <TableRow
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <TextView
                    android:id="@+id/textViewLongitude"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Longitude:" />

                <TextView
                    android:id="@+id/textViewLongitudeValue"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="..." />
            </TableRow>

            <TableRow
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <TextView
                    android:id="@+id/textViewAccuracy"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Accuracy:" />

                <TextView
                    android:id="@+id/textViewAccuracyValue"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="..." />
            </TableRow>

        </TableLayout>

    </ScrollView>
</android.support.constraint.ConstraintLayout>

Step 7. Code MainActivity

Go to MainActivity. Make the class implements LocationProvider.LocationCallback. Then run permissionsRequester and mLocationProvider in onCreate.

package latlong.nettport.com.latitudelongitude;

import android.location.Location;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements LocationProvider.LocationCallback {
    private PermissionsRequester permissionsRequester;

    private TextView textViewLatitudeValue;
    private TextView textViewLongitudeValue;
    private TextView textViewAccuracyValue;

    private LocationProvider mLocationProvider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Find TextViews
        textViewLatitudeValue = (TextView) findViewById(R.id.textViewLatitudeValue);
        textViewLongitudeValue = (TextView) findViewById(R.id.textViewLongitudeValue);
        textViewAccuracyValue = (TextView) findViewById(R.id.textViewAccuracyValue);

        // Request permissions
        permissionsRequester = PermissionsRequester.newInstance(this);

        // Find my location
        mLocationProvider = new LocationProvider(this, this);
    }


    @Override
    protected void onStart() {
        super.onStart();

        if (!permissionsRequester.hasPermissions()) {
            Toast.makeText(this, "Please give permissions to get your location", Toast.LENGTH_LONG).show();
            permissionsRequester.requestPermissions();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mLocationProvider.connect();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mLocationProvider.disconnect();
    }

    public void handleNewLocation(Location location) {
        double currentLatitude = location.getLatitude();
        double currentLongitude = location.getLongitude();
        float currentAccuracy = location.getAccuracy();

        textViewLatitudeValue.setText(String.valueOf(currentLatitude));
        textViewLongitudeValue.setText(String.valueOf(currentLongitude));
        textViewAccuracyValue.setText(String.valueOf(currentAccuracy));
    }
}

Add comment

avatar_blank_60.png

Comment:

Name:

Email:

Comments

No comments yet. You can be the first one to comment. Just write your comment in the form and click on the submit button.