Skip to content

Instantly share code, notes, and snippets.

@PavithMadusara
Last active August 8, 2021 16:52
Show Gist options
  • Save PavithMadusara/f3908c2d66a29edf64f357b8d69896f3 to your computer and use it in GitHub Desktop.
Save PavithMadusara/f3908c2d66a29edf64f357b8d69896f3 to your computer and use it in GitHub Desktop.
Android Location Picker

implementation 'com.google.android.gms:play-services-maps:16.0.1'

import android.Manifest;
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.aupma.jiat.metro.R;
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.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class LocationPicker extends AppCompatActivity {

    public static final int SUCCESSFUL = 1;
    public static final int CANCELED = 0;

    private Button btnSelectLocation;
    private SupportMapFragment mapFragment;
    private Marker marker;
    //--------------------------------------------------------------------------------------------//

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

        assignViews();
        addListeners();
        loadMap();
        addMapListeners();
    }

    //--------------------------------------------------------------------------------------------//

    @Override
    protected void onStart() {
        super.onStart();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // Permission Denied atm
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, SUCCESSFUL);
        } else {
            // Have Permission
            zoomToCurrentLocation();

        }
    }

    //--------------------------------------------------------------------------------------------//

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == SUCCESSFUL) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Location Permission Granted
                zoomToCurrentLocation();
            } else {
                Toast.makeText(
                        this,
                        R.string.LOCATION_PICKER_ERROR_permission_denied,
                        Toast.LENGTH_SHORT
                ).show();
            }
        }
    }

    //--------------------------------------------------------------------------------------------//

    @Override
    public void onBackPressed() {
        setResult(CANCELED);
        super.onBackPressed();
    }


    //--------------------------------------------------------------------------------------------//

    private void assignViews() {
        btnSelectLocation = findViewById(R.id.btnSelectLocation);
    }

    //--------------------------------------------------------------------------------------------//

    private void addListeners() {
        btnSelectLocation.setOnClickListener(v -> {
            LatLng position = marker.getPosition();

            Intent intent = new Intent();
            intent.putExtra("latitude", position.latitude);
            intent.putExtra("longitude", position.longitude);

            setResult(RESULT_OK, intent);
            finish();
        });
    }

    //--------------------------------------------------------------------------------------------//

    private void addMapListeners() {
        mapFragment.getMapAsync((googleMap -> {
            googleMap.setOnCameraIdleListener(() -> {
                LatLng target = googleMap.getCameraPosition().target;
                addMarker(target);
            });
            googleMap.setOnCameraMoveListener(() -> marker.remove());
        }));
    }

    //--------------------------------------------------------------------------------------------//

    private void addMarker(LatLng markerPosition) {
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(markerPosition);

        mapFragment.getMapAsync((googleMap -> {
            if (marker != null) {
                marker.remove();
            }
            marker = googleMap.addMarker(markerOptions);
        }));
    }

    //--------------------------------------------------------------------------------------------//

    private void moveCamera(LatLng latLng) {
        CameraPosition.Builder builder = CameraPosition.builder();
        CameraPosition cameraPosition = builder.target(latLng).zoom(10).build();
        CameraUpdate update = CameraUpdateFactory.newCameraPosition(cameraPosition);

        mapFragment.getMapAsync((googleMap -> googleMap.animateCamera(update)));
    }

    //--------------------------------------------------------------------------------------------//

    @TargetApi(Build.VERSION_CODES.M)
    private void zoomToCurrentLocation() {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationCallback locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                Location lastLocation = locationResult.getLastLocation();
                LatLng latLng = new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude());
                moveCamera(latLng);
                addMarker(latLng);
            }
        };

        FusedLocationProviderClient providerClient = LocationServices
                .getFusedLocationProviderClient(getApplicationContext());

        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == (PackageManager.PERMISSION_GRANTED)) {
            providerClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
        }

    }

    //--------------------------------------------------------------------------------------------//

    private void loadMap() {
        mapFragment = new SupportMapFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.mapView, mapFragment, "map");
        transaction.commit();
    }

    //--------------------------------------------------------------------------------------------//


}
<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent"

    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/mapContainer"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="24dp"
        android:layout_marginBottom="8dp"
        android:background="@drawable/bg_card_shape"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/btnSelectLocation"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:backgroundTint="@color/colorPrimaryDark"
            android:text="@string/LOCATION_PICKER_map_location_select_btn"
            android:textColor="@android:color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />

        <ImageView
            android:id="@+id/imageView6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/mapView"
            app:layout_constraintEnd_toEndOf="@+id/mapView"
            app:layout_constraintStart_toStartOf="@+id/mapView"
            app:layout_constraintTop_toTopOf="@+id/mapView"
            app:srcCompat="@drawable/ic_search" />

        <com.google.android.gms.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginTop="24dp"
            android:layout_marginBottom="24dp"
            app:layout_constraintBottom_toTopOf="@+id/btnSelectLocation"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment