Question

In android studio, I want to get the user current location when he clicks on a...

In android studio, I want to get the user current location when he clicks on a button after asking him for the permission, store its latitude and longitude on double variables and then do calculations depends on the user location, How can I do that in maps activity? I want on click to be outside onCreate, I want inside on click to get double lat = latlong.getlatutide not to call function getlocation

0 0
Add a comment Improve this question Transcribed image text
Answer #1

Firstly, location fetching is a very tedious task. It involves a lot of boilerplate code . To remove this boilerplate code, I have made a utility class named LocationFetcher.java

LocationFetcher.java

package com.pratik.appedia.HomeworkLib1;

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.Looper;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;

import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
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.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;

class LocationFetcher {

    private Context context;
    private Activity activity;
    private FusedLocationProviderClient mFusedLocationClient;
    private SettingsClient mSettingsClient;
    private LocationRequest mLocationRequest;
    private LocationSettingsRequest mLocationSettingsRequest;
    private LocationCallback mLocationCallback;
    private Location mCurrentLocation;
    private LocationFetchedListener locationFetchedListener;
    private LocationFetcherInterface locationFetcherInterface;


    LocationFetcher(Context context) {
        this.context = context;
        this.activity = (Activity) context;
    }

    void setLocationFetchedListener(LocationFetchedListener locationFetchedListener) {
        this.locationFetchedListener = locationFetchedListener;
    }

    void setLocationFetcherInterface(LocationFetcherInterface locationFetcherInterface) {
        this.locationFetcherInterface = locationFetcherInterface;
    }

    private void init() {
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
        mSettingsClient = LocationServices.getSettingsClient(context);
        createLocationCallback();
        createLocationRequest();
        buildLocationSettingsRequest();
        startLocationUpdates();
    }

    private void createLocationCallback() {
        mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);

                mCurrentLocation = locationResult.getLastLocation();
                if (mCurrentLocation != null) {
                    double lat = mCurrentLocation.getLatitude();
                    double longi = mCurrentLocation.getLongitude();
                    locationFetchedListener.onUserLatLongFetched(lat, longi);
                }
            }
        };
    }

    private void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    private void buildLocationSettingsRequest() {
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        mLocationSettingsRequest = builder.build();
    }

    private void startLocationUpdates() {
        mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
                .addOnSuccessListener(activity, new OnSuccessListener<LocationSettingsResponse>() {
                    @Override
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {

                        //noinspection MissingPermission
                        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                            locationFetcherInterface.onLocationPermissionsNeeded();
                            return;
                        }
                        mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                    }
                })
                .addOnFailureListener(activity, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        int statusCode = ((ApiException) e).getStatusCode();
                        switch (statusCode) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                try {
                                    // Show the dialog by calling startResolutionForResult(), and check the
                                    // result in onActivityResult().
                                    ResolvableApiException rae = (ResolvableApiException) e;
                                    rae.startResolutionForResult(activity, 100);
                                } catch (IntentSender.SendIntentException sie) {
                                    sie.printStackTrace();
                                }
                                break;
                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                break;
                        }
                    }
                });
    }

    void stopLocationUpdates() {
        mFusedLocationClient.removeLocationUpdates(mLocationCallback)
                .addOnCompleteListener(activity, new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                    }
                });

        if (mFusedLocationClient != null) {
            mFusedLocationClient.removeLocationUpdates(mLocationCallback);
        }
        mFusedLocationClient = null;
    }

    void getUserLatLong() {
        init();
    }

    public interface LocationFetchedListener {
        void onUserLatLongFetched(double latitude, double longitude);
    }

    public interface LocationFetcherInterface{
        void onLocationPermissionsNeeded();
    }

}

This utility class can then be used anywhere in the project. Consider the MapsActivity as below

MapsActivity.java

package com.pratik.appedia.HomeworkLib1;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback
        , View.OnClickListener
        , LocationFetcher.LocationFetchedListener, LocationFetcher.LocationFetcherInterface {

    private GoogleMap mMap;
    private LocationFetcher locationFetcher;
    private static final String TAG = MapsActivity.class.getSimpleName();
    private FloatingActionButton floatingActionButton;
    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        if(mapFragment != null)
            mapFragment.getMapAsync(this);
        floatingActionButton = findViewById(R.id.floatingActionButton);
        floatingActionButton.setOnClickListener(this);
        locationFetcher  = new LocationFetcher(this);
        locationFetcher.setLocationFetchedListener(this);
        locationFetcher.setLocationFetcherInterface(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.floatingActionButton) {
            locationFetcher.getUserLatLong();
        }
    }

    @Override
    public void onUserLatLongFetched(double latitude, double longitude) {
        // Do here whatever you want with your double values
        locationFetcher.stopLocationUpdates();
        Toast.makeText(getApplicationContext(),"Latitude = "+latitude+"\tLongitude = "+longitude,Toast.LENGTH_LONG).show();
        Log.d(TAG,"Latitude = "+latitude+"\tLongitude = "+longitude);
    }


    @Override
    public void onLocationPermissionsNeeded() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {
            new AlertDialog.Builder(this)
                    .setTitle(R.string.title_location_permission)
                    .setMessage(R.string.text_location_permission)
                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            ActivityCompat.requestPermissions(MapsActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    MY_PERMISSIONS_REQUEST_LOCATION);
                        }
                    })
                    .create()
                    .show();
        } else {
            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 (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (ContextCompat.checkSelfPermission(this,
                            Manifest.permission.ACCESS_FINE_LOCATION)
                            == PackageManager.PERMISSION_GRANTED) {
                        locationFetcher.getUserLatLong();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "Location has been denied. Sorry !", Toast.LENGTH_SHORT).show();
                }
            }

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode){
            case 100:
                if(resultCode == 0){
                    Toast.makeText(getApplicationContext(),"You didn't put your GPS on !",Toast.LENGTH_SHORT).show();
                } else{
                    locationFetcher.getUserLatLong();
                }
                Log.d(TAG,"Result code = "+resultCode);
                break;
        }
    }
}

All you need to do is

1. Create an object of LocationFetcher class

2. In the onClick method (which is outside onCreate) check the id of the view clicked. If it matches with the button id

then invoke the getUserLatLong() method of the LocationFetcher class using the object made in step 1.

3. Override the callback methods defined inside the LocationFetcher class .

a. We have an interface to listen for lack of permissions

b. We have an interface to listen for successful fetching of user location

4. The onUserLatLongFetched() method is called when the LocationFetcher successfully fetches the user location.

5. In this callback now you can play with your double values.

6. Advantage of this code is it is clean and concise and easy to maintain.

activity_maps.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/constraintLayout_Root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MapsActivity" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/floatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        android:clickable="true"
        android:focusable="true"
        android:src="@drawable/ic_my_location"
        map:layout_constraintBottom_toBottomOf="parent"
        map:layout_constraintEnd_toEndOf="parent"
        map:layout_constraintHorizontal_bias="1.0"
        map:layout_constraintStart_toStartOf="@+id/map"
        map:layout_constraintTop_toTopOf="parent"
        map:layout_constraintVertical_bias="1.0" />

</android.support.constraint.ConstraintLayout>

strings.xml

<resources>
    <string name="app_name">Chegg1</string>
    <string name="title_activity_maps">Map</string>
    <string name="ok">Ok</string>
    <string name="title_location_permission">Access to location</string>
    <string name="text_location_permission">We need to know your location for better functionality</string>
</resources>

Add a comment
Know the answer?
Add Answer to:
In android studio, I want to get the user current location when he clicks on a...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • On Android studio, how to call a phone number from a button? Like when the user...

    On Android studio, how to call a phone number from a button? Like when the user click on a buttom on the aplication, it direct him to a phone call thanks

  • If anyone here is a Java and Android Studio expert please I really need help fulfilling...

    If anyone here is a Java and Android Studio expert please I really need help fulfilling the requirements needed to make a Rock Paper Scissors game. I mainly need Java code to complete it I will post what I have so far I don't have much time left please if anyone can help me I would really appreciate it. Here's what the app is supposed to do... The player should be able to select either Rock, Paper, or Scissors.The app...

  • In Android Studio, I just can't find the errors to this problem, I have the following...

    In Android Studio, I just can't find the errors to this problem, I have the following code written down, what I need is just how to make a direct route/directions between 2 specific coordinates, specifically I need the coordinates (34.782, -86.569) to have a direct route to (34.781, -86.571) thank you Here is Code: package com.example ------ import android.support.v4.app.FragmentActivity; import android.os.Bundle; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; public class MapsActivity extends FragmentActivity implements OnMapReadyCallback...

  • I need help developing this app using java in android studio Assignment: Tic-Tac-Toe app User interface...

    I need help developing this app using java in android studio Assignment: Tic-Tac-Toe app User interface Operation The app allows the user to play a game of Tic-Tac-Toe. The user can click the New Game button at any time to start a new game. The app displays other messages to the user as the game progresses such as (1) whose turn it is, (2) if a player wins, and (3) if the game ends in a tie. Specifications The app...

  • (Android Studio) Create a camera app that allows the user to upload a picture from their...

    (Android Studio) Create a camera app that allows the user to upload a picture from their phone camera gallery, see the picture via summary page, and edit the picture as well. Clicking on "Insert picture here from camera photo gallery" in the add page will allow the user to upload a picture from their existing camera photo gallery on their phone. The user can choose where to save the picture, starting with Picture 1-5. Once they choose where to save...

  • I should show tables with info after clicking on the buttons in Android Studio. I still...

    I should show tables with info after clicking on the buttons in Android Studio. I still can not get what I should write inside OnClick function and how to use containers for printing tables. Please help me! import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.os.Bundle; import android.text.Layout; import android.view.LayoutInflater; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { LinearLayout container; ListView ListView1; ListView ListView2; ListView ListView3; @Override protected void onCreate(Bundle savedInstanceState)...

  • How can I add this function to my C# code?: Validate that if the user clicks...

    How can I add this function to my C# code?: Validate that if the user clicks the “OK” button, a “Seating Category” is selected, and at least one ticket is being purchased. If not, pop-up a dialog box asking the user to enter the needed data for the transaction. What we want to avoid is depicted in See Figure 3. Figure 3: This code asks for a seating category to be selected, how many tickets to be purchased, and if...

  • Any thoughts on this, i can get it to run but can't pass code around and...

    Any thoughts on this, i can get it to run but can't pass code around and the button doesnt move around. i didnt pass the student, or the app.java. What will you learn Combined use of Timer and the tracking of user interactions Deliverables app.java myJFrame.java myJPanel.java and other necessary Java files Contents The objective of the lab is to create a game in which the player has to click on a moving student-button to score. The student button has...

  • CS0007 Good day, I am in an entry-level Java class and need assistance completing an assignment....

    CS0007 Good day, I am in an entry-level Java class and need assistance completing an assignment. Below is the assignment criteria and the source code from the previous assignment to build from.  Any help would be appreciated, thank you in advance. Source Code from the previous assignment to build from shown below: Here we go! Let's start with me giving you some startup code: import java.io.*; import java.util.*; public class Project1 { // Random number generator. We will be using this...

  • If you’re using Visual Studio Community 2015, as requested, the instructions below should be exact but...

    If you’re using Visual Studio Community 2015, as requested, the instructions below should be exact but minor discrepancies may require you to adjust. If you are attempting this assignment using another version of Visual Studio, you can expect differences in the look, feel, and/or step-by-step instructions below and you’ll have to determine the equivalent actions or operations for your version on your own. INTRODUCTION: In this assignment, you will develop some of the logic for, and then work with, the...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT