0

I have successfully implemented google maps and current location within my app. The only issue I am facing is, once the user has accepted the permissions and allows location, the fragment needs to be reloaded before current location will be implemented.

enter image description here

My location class:

public class LocationFragment extends Fragment implements OnMapReadyCallback {
    private LocationViewModel locationViewModel;
    private GoogleMap gMap;
    private MapView mapView;
    private Location currentLocation;
    private int LOCATION_PERMISSION_REQUEST_CODE = 1234;




    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        locationViewModel = ViewModelProviders.of( this ).get( LocationViewModel.class );
        View view = inflater.inflate( R.layout.fragment_location_customer, container, false );

        return view;
    }


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated( view, savedInstanceState );



        mapView = (MapView) view.findViewById( R.id.map );
        if (mapView != null)
        {
            mapView.onCreate( null );
            mapView.onResume();
            mapView.getMapAsync( this );

        }



    }

    @Override
    public void onMapReady(GoogleMap googleMap)
    {
        UiSettings uiSettings = googleMap.getUiSettings();

        gMap = googleMap;
        LatLng coffeys = new LatLng( 54.572720, -5.959151 );
        gMap.addMarker( new MarkerOptions().position( coffeys ).title( "Coffey's Butchers" ) );
        gMap.moveCamera( CameraUpdateFactory.newLatLngZoom( coffeys, 12 ) );
        uiSettings.setZoomControlsEnabled(true);
        enableLocation();
    }





    public void enableLocation()
    {
        int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
        if (permissionCheck != PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
        }
        if(permissionCheck == PackageManager.PERMISSION_GRANTED)
        {
            gMap.setMyLocationEnabled( true );
            final LocationListener locationListener = new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    // GPS may be turned off
                    if (location == null)
                    {
                        return;
                    }

                    Double lat = location.getLatitude();
                    Double lng = location.getLongitude();

                    currentLocation = location;
                    Toast.makeText( getActivity(), "Updated Location: " + lat + lng, Toast.LENGTH_SHORT ).show();

                }
            };

        }
    }

}

Is there anyway to get the current location to work as soon as access is allowed.

hata
  • 11,633
  • 6
  • 46
  • 69
Alice
  • 23
  • 1
  • 8

2 Answers2

0

Use requestPermissions() instead of ActivityCompat.requestPermissions(), override onRequestPermissionsResult() in your fragment and run the code that depends on the permission there if the permission is granted.

Check this question: How to check permission in fragment

Dark Byte
  • 81
  • 2
  • 2
0

Pre-requisite: EasyPermission library


Step 1: In manifest file add this permission

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

Step 2:

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //Create location callback when it's ready.
    createLocationCallback()

    //createing location request, how mant request would be requested.
    createLocationRequest()

    //Build check request location setting request
    buildLocationSettingsRequest()
    
    //FusedLocationApiClient which includes location 
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    //Location setting client
    mSettingsClient = LocationServices.getSettingsClient(this)

    //Check if you have ACCESS_FINE_LOCATION permission
    if (!EasyPermissions.hasPermissions(
            this@MainActivity,
            Manifest.permission.ACCESS_FINE_LOCATION)) {
        requestPermissionsRequired()
    }
    else{
        //If you have the permission we should check location is opened or not
        checkLocationIsTurnedOn()
    }
   
}

Step 3: Create required functions to be called in onCreate()

private fun requestPermissionsRequired() {
    EasyPermissions.requestPermissions(
        this,
        getString(R.string.location_is_required_msg),
        LOCATION_REQUEST,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
}

private fun createLocationCallback() {
    //Here the location will be updated, when we could access the location we got result on this callback.
    mLocationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            super.onLocationResult(locationResult)
            mCurrentLocation = locationResult.lastLocation
        }
    }
}

private fun buildLocationSettingsRequest() {
    val builder = LocationSettingsRequest.Builder()
    builder.addLocationRequest(mLocationRequest!!)
    mLocationSettingsRequest = builder.build()
    builder.setAlwaysShow(true)
}

private fun createLocationRequest() {
    mLocationRequest = LocationRequest.create()
    mLocationRequest!!.interval = 0
    mLocationRequest!!.fastestInterval = 0
    mLocationRequest!!.numUpdates = 1
    mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}

public fun checkLocationIsTurnedOn() { // Begin by checking if the device has the necessary location settings.
    mSettingsClient!!.checkLocationSettings(mLocationSettingsRequest)
        .addOnSuccessListener(this) {
            Log.i(TAG, "All location settings are satisfied.")
            startLocationUpdates()
        }
        .addOnFailureListener(this) { e ->
            val statusCode = (e as ApiException).statusCode
            when (statusCode) {
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                    try {
                        val rae = e as ResolvableApiException
                        rae.startResolutionForResult(this@MainActivity, LOCATION_IS_OPENED_CODE)
                    } catch (sie: IntentSender.SendIntentException) {
                    }
                }
                LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                    mRequestingLocationUpdates = false
                }
            }
        }
}

private fun startLocationUpdates() {
    mFusedLocationClient!!.requestLocationUpdates(
        mLocationRequest,
        mLocationCallback, null
    )
}

Step 4:

Handle callbacks in onActivityResult() after ensuring the location is opened or the user accepts to open it in.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        LOCATION_IS_OPENED_CODE -> {
            if (resultCode == AppCompatActivity.RESULT_OK) {
                Log.d(TAG, "Location result is OK")
            } else {
                activity?.finish()
            }
        }
}

Step 5: Get last known location from FusedClientApi

override fun onMapReady(map: GoogleMap) {
    mMap = map
    mFusedLocationClient.lastLocation.addOnSuccessListener {
        if(it!=null){
            locateUserInMap(it)
        }
    }

}
   private fun locateUserInMap(location: Location) {
    showLocationSafetyInformation()
    if(mMap!=null){
        val currentLocation = LatLng(location.latitude,location.longitude )
        addMarker(currentLocation)
    }
}


private fun addMarker(currentLocation: LatLng) {
    val cameraUpdate = CameraUpdateFactory.newLatLng(currentLocation)
    mMap?.clear()
    mMap?.addMarker(
        MarkerOptions().position(currentLocation)
            .title("Current Location")
    )
    mMap?.moveCamera(cameraUpdate)
    mMap?.animateCamera(cameraUpdate)
    mMap?.setMinZoomPreference(14.0f);
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
MustafaKhaled
  • 1,343
  • 9
  • 25