I was using LocationManager to track the user current location, Now after changing location manager to FusedLocation API, the blue dot and circle is not shown even after setting map.setMyLocationEnabled(true)
. I can see the current location icon on top right corner in my map fragment but clicking on it does nothing. I reverted my code to LocationManager now i am able to see the blue dot pointing to my current location. what could be wrong using Fused Location API.
Blue dot and circle is not shown on MyLocation using android fused location api
Asked Answered
For targeting api-23 or higher
See this answer....
For targeting api-22 and lower:
This code works for me, it has the MyLocation
blue dot/circle, and it also places a Marker
on the current location using the Fused Location Provider.
Here is the entire Activity code I used:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import android.location.Location;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.OnMapReadyCallback;
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
LocationListener,
OnMapReadyCallback {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
LatLng latLng;
GoogleMap mGoogleMap;
SupportMapFragment mFragment;
Marker mCurrLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setMyLocationEnabled(true);
buildGoogleApiClient();
mGoogleApiClient.connect();
}
@Override
public void onPause() {
super.onPause();
//Unregister for location callbacks:
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
public void onConnected(Bundle bundle) {
Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
//place marker at current position
mGoogleMap.clear();
latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocation = mGoogleMap.addMarker(markerOptions);
}
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000); //5 seconds
mLocationRequest.setFastestInterval(3000); //3 seconds
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setSmallestDisplacement(0.1F); //1/10 meter
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
}
@Override
public void onLocationChanged(Location location) {
//remove previous current location marker and add new one at current position
if (mCurrLocation != null) {
mCurrLocation.remove();
}
latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocation = mGoogleMap.addMarker(markerOptions);
Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();
//If you only need one location, unregister the listener
//LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<fragment
class="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/map"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
Result:
This worked for me. However, I need to use the location stored in the LatLang object. When I try to access them, I get a null pointer exception. Any ideas? –
Archdeaconry
@bholagabbar If you need to you can store a reference to the current Location object returned in
onLocationChanged()
, which this code does using a LatLng. Be sure to check that it's not null whenever you use it, since a location might not have come in yet. Anything that depends on a location lock, kick it off in onLocationChanged() if need be. –
Lassalle I tried making latLang gloabl, but i still get nullpointerException. I didn't understand your way. Could you just elaborate? –
Archdeaconry
@bholagabbar The LatLng object will be null before the first location callback
onLocationChanged()
is called, and then non-null after. If you try to access latLng
in onCreate()
it won't work, because it hasn't gotten into onLocationChanged()
yet. –
Lassalle it gave me error:
java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.
but I have setup permissions in manifests <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
–
Regalado @MuhammadShahzad Are you testing on Android M (Android 6)? If so, you will need to prompt the user at runtime, see here: #33064212 –
Lassalle
Yes I'm testing on Android 6 –
Regalado
@Daniel There is a problem in your solution. If onStart gets called Before onMapready, the Google client will never call connect –
Yancey
@johny there is no onStart() in this answer.... it sounds like you just need to move some code from onStart() into onMapReady(). What do you have in your onStart() code? –
Lassalle
Yea forget what I said, I mixed :/ with an other example –
Yancey
@Yancey Ahh, no prob! –
Lassalle
@Daniel Nugent: can you tell me how to reduce the radius of that blue circle which is wide ,more specifically I want to reduce the circle so that I can get high accuracy –
Agile
@PratikVyas That blue circle comes from the framework, and it's based on the accuracy of the location that it currently has. I don't think there's a way to reduce the blue circle in app code. Basically, the framework just needs to get a location lock with better accuracy. –
Lassalle
@DanielNugent : Thanks for quick reply, can we prompt a user that it has good accuracy or bad accuracy using getAccuracy method of location manager, if so what will be identical value to be chacked during check –
Agile
You have to add the following permissions in manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
Wow... Thank you @MuhammadMoosa! I spent so much time trying to figure out why my location is not accurate in one app, WHILE when I debug my other app it was perfect... I checked permissions many times and the only one I was missing was
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
. I didn't even think that this permission is related to maps anyhow.. –
Trillion Actually you only need one. Either ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION, depending on your implementation. –
Brassbound
MarkerOptions().position(new LatLng(
location.getLatitude(), location.getLongitude()));
Try this,
if (location!=null) {
googleMap.clear();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(), location.getLongitude())).zoom(14).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
// create markerOptions
MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(
location.getLatitude(), location.getLongitude()));
// ROSE color icon
markerOptions.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
markerOptions.position(latLng);
// adding markerOptions
Marker marker = googleMap.addMarker(markerOptions);
dropPinEffect(marker);
}
© 2022 - 2024 — McMap. All rights reserved.
MyLocation
button, it shouldn't matter what you use. You don't have to add any code at all for that button and the blue mark to work. – LassalleSupportMapFragment
? – LassalleSupportMapFragment
– SuperstarmFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); map = mFragment.getMap(); map.setMyLocationEnabled(true);
– LassalleMyLocation
button, and blue dot, it doesn't really have anything to do with getting the current location in the code, since the map does all the work for that. – Lassallehttps://developer.android.com/training/location/receive-location-updates.html
in the same example project you created andonLocationChanged()
method point the marker to current location. – Superstar