Blue dot and circle is not shown on MyLocation using android fused location api
Asked Answered
S

3

14

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.

Superstar answered 15/5, 2015 at 6:41 Comment(8)
Regarding the 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.Lassalle
@DanielNugent, But click is not working on MyLocation button on top right corner and I am not seeing the blue circle pointer on my current location.Superstar
That is strange. Can you show some of your code? Are you using a SupportMapFragment?Lassalle
Yes, I am using SupportMapFragmentSuperstar
I just started a new blank project in Android Studio, and the only code I had to add was this: mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); map = mFragment.getMap(); map.setMyLocationEnabled(true);Lassalle
To get current user location are you using android FusedLocation API ?Superstar
For the MyLocation 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.Lassalle
Thats true but when used FusedLocationApi to get user current location the blue dot disappears and the MyLocation button does not work. Try this https://developer.android.com/training/location/receive-location-updates.html in the same example project you created and onLocationChanged() method point the marker to current location.Superstar
L
29

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:

MyLocationPlusFusedLocationProvider

Lassalle answered 15/5, 2015 at 8:46 Comment(14)
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: #33064212Lassalle
Yes I'm testing on Android 6Regalado
@Daniel There is a problem in your solution. If onStart gets called Before onMapready, the Google client will never call connectYancey
@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 exampleYancey
@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 accuracyAgile
@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 checkAgile
N
6

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" />
Nessy answered 21/3, 2016 at 18:59 Comment(2)
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
K
1
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);
            }
Krefeld answered 22/7, 2016 at 10:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.