2

I am trying to display my current location using Google Maps on Android Studio (Java, XML). But I am having some problems in fetching current location from FusedLocationProviderClient.getLastLocation(). Below are my related methods which are responsible for setting up the map with my current location.

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.eternityicon.pakrozgar">
    <uses-permission android:name="com.eternityicon.pakrozgar.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>

    <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/SplashTheme">
        <activity android:name=".VendorDashboardActivity" />
        <activity android:name=".CustomerDashboardActivity" />
        <activity android:name=".CustomerRegisterActivity" />
        <activity android:name=".UserRegisterActivity" />
        <activity android:name=".VendorRegisterActivity" />
        <activity android:name=".StartupActivity" />
        <activity android:name=".SplashActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/API_KEY" />
    </application>

</manifest>

activity_customer_dashboard.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    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"
    android:background="@drawable/gradient"
    android:id="@+id/drawyer_layout"
    tools:context=".CustomerDashboardActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/CDA_parentlayout">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <androidx.appcompat.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/whiteColor">
                <ImageView
                    android:id="@+id/customer_navButton"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="20dp"
                    app:srcCompat="@drawable/menu32"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="PakRozgar"
                    android:textSize="24dp"
                    android:fontFamily="@font/architects_daughter"/>
            </androidx.appcompat.widget.Toolbar>
            <fragment
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/customerMap"
                android:name="com.google.android.gms.maps.SupportMapFragment"
                tools:context=".CustomerDashboardActivity"/>
        </LinearLayout>
    </FrameLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/customer_dashboard_navigation"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_bar"
        app:headerLayout="@layout/menu_bar_header">
    </com.google.android.material.navigation.NavigationView>

</androidx.drawerlayout.widget.DrawerLayout>

Now, inside my CustomerDashboardActivity.java I am calling getLocationPermission() method from my OnCreate() method, which is used to get the user permissions.

    //Checking user permissions
    private void getLocationPermission(){
        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION};
        if(ContextCompat.checkSelfPermission(this.getApplicationContext(), FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
            if(ContextCompat.checkSelfPermission(this.getApplicationContext(),COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
                mLocationPermissionGranted = true;
                Log.d(TAG, "getLocationPermission: permissions are successful.");
            }
            else {
                ActivityCompat.requestPermissions(this,
                        permissions,
                        LOCATION_PERMISSION_REQUEST_CODE);
                Log.d(TAG, "getLocationPermission: error in getting permissions");
            }
        }
    }

It's related OnRequestPermissionsResult() handler is:

@Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            //super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            Log.d(TAG, "onRequestPermissionsResult: handling the event.");
            mLocationPermissionGranted = false;
            switch(requestCode){
                case LOCATION_PERMISSION_REQUEST_CODE:{
                    if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                        getDeviceLocation();
                    }
                    break;
                }
            }
        }

After these permission work is done, I am calling getDeviceLocation() method from my OnCreate() methods:

private void getDeviceLocation(){
    Log.d(TAG, "getDeviceLocation: getting the current location of device");
    try{
        //getLocationPermission();
        if(mLocationPermissionGranted){
            Task<Location> task = mFusedLocationProviderClient.getLastLocation();
            task.addOnSuccessListener(new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if(location != null){
                        Log.d(TAG, "onComplete: found Location!!!");
                        //Location currentLocation = (Location)task.getResult();
                        currentLocation = location;
                        Log.d(TAG, "onSuccess: FusedLocationProviderClient gave this location:\n"+currentLocation+"\n");
                        SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.customerMap);
                        mapFragment.getMapAsync(CustomerDashboardActivity.this);
                        /*moveCamera(new LatLng(30.1575,71.5249),
                                DEFAULT_ZOOM);*/
                    }
                    else {
                        Log.d(TAG, "onComplete: current loaction not found");
                        ShowToasts("Cannot get your location");
                    }
                }
            });
        }
    }
    catch (SecurityException x){
        ShowMessage("Error in getting device location",x.getMessage());
    }
}

The mFusedLocationProviderClient object, which I am using to get last location is defined inside my OnCreate() method as

mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

And my currentLocation variable is a global variable, declared as:

Location currentLocation;

Finally, my OnMapReady() handler is:

@Override
public void onMapReady(GoogleMap googleMap) {
    //LatLng latLng = new LatLng(-34, 151);//Location Sydney
    LatLng latLng = new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude());
    Log.d(TAG, "onMapReady: \nlat:"+currentLocation.getLatitude()+"\nlng:"+currentLocation.getLongitude());
    MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("You are here");
    googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));//bring camera to this location
    googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,DEFAULT_ZOOM));
    googleMap.addMarker(markerOptions);
    googleMap.setMyLocationEnabled(true);
    //mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM));
    Log.d(TAG, "onMapReady: map has been initialized and set!!");
}

According to what I have learnt from documentation, my getDeviceLocation() should be able to get current location and eventually it should be displayed on the map. However, the control flow shows a different scenario. mFusedLocationProviderClient does fetch the location, but it is fetching a fixed location (latitude:37.4219983, longitude:-122.084).

It means that the algorithm is working perfectly fine, but I am missing some important conceptual thing.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Hyder khan
  • 83
  • 1
  • 7

0 Answers0