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.