Синяя точка и круг не отображаются в MyLocation с использованием API-интерфейса Android Fuse Location

Я использовал LocationManager для отслеживания текущего местоположения пользователя. Теперь, после изменения диспетчера местоположений на API FusedLocation, синяя точка и круг не отображаются даже после установки map.setMyLocationEnabled(true). Я вижу значок текущего местоположения в верхнем правом углу фрагмента карты, но нажатие на него ничего не делает. Я вернул свой код в LocationManager, теперь я могу видеть синюю точку, указывающую на мое текущее местоположение. что может быть не так с использованием API Fused Location.


person flexdroid    schedule 15.05.2015    source источник
comment
Что касается кнопки MyLocation, не имеет значения, что вы используете. Вам вообще не нужно добавлять какой-либо код, чтобы эта кнопка и синяя метка работали.   -  person Daniel Nugent    schedule 15.05.2015
comment
@DanielNugent, но щелчок по кнопке MyLocation в правом верхнем углу не работает, и я не вижу указатель синего круга в моем текущем местоположении.   -  person flexdroid    schedule 15.05.2015
comment
Это странно. Можете ли вы показать часть своего кода? Вы используете SupportMapFragment?   -  person Daniel Nugent    schedule 15.05.2015
comment
Да, я использую SupportMapFragment   -  person flexdroid    schedule 15.05.2015
comment
Я только что начал новый пустой проект в Android Studio, и единственный код, который мне нужно было добавить, был следующим: mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); map = mFragment.getMap(); map.setMyLocationEnabled(true);   -  person Daniel Nugent    schedule 15.05.2015
comment
Чтобы получить текущее местоположение пользователя, вы используете Android FusedLocation API?   -  person flexdroid    schedule 15.05.2015
comment
Для кнопки MyLocation и синей точки на самом деле это не имеет никакого отношения к получению текущего местоположения в коде, так как карта делает всю работу для этого.   -  person Daniel Nugent    schedule 15.05.2015
comment
Это правда, но при использовании FusedLocationApi для получения текущего местоположения пользователя синяя точка исчезает, а кнопка MyLocation не работает. Попробуйте этот https://developer.android.com/training/location/receive-location-updates.html в том же примере проекта, который вы создали, и метод onLocationChanged() укажет маркеру на текущее местоположение.   -  person flexdroid    schedule 15.05.2015


Ответы (3)


Для таргетинга на API-23 или выше

См. этот ответ....

Для таргетинга на API 22 и ниже:

Этот код работает для меня, он имеет синюю точку/круг MyLocation, а также размещает Marker в текущем местоположении, используя Fused Location Provider.

Вот весь код действия, который я использовал:

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>

Результат:

MyLocationPlusFusedLocationProvider

person Daniel Nugent    schedule 15.05.2015
comment
Это сработало для меня. Однако мне нужно использовать местоположение, хранящееся в объекте LatLang. Когда я пытаюсь получить к ним доступ, я получаю исключение нулевого указателя. Есть идеи? - person bholagabbar; 30.11.2015
comment
@bholagabbar Если вам нужно, вы можете сохранить ссылку на текущий объект Location, возвращенный в onLocationChanged(), что этот код делает с использованием LatLng. Обязательно проверяйте, не является ли оно нулевым всякий раз, когда вы его используете, так как местоположение может еще не появиться. Все, что зависит от блокировки местоположения, отключите его в onLocationChanged(), если это необходимо. - person Daniel Nugent; 30.11.2015
comment
Я пытался сделать latLang gloabl, но все равно получаю исключение nullpointerException. Я не понял твоего пути. Не могли бы вы просто уточнить? - person bholagabbar; 30.11.2015
comment
@bholagabbar Объект LatLng будет нулевым до вызова первого обратного вызова местоположения onLocationChanged(), а затем ненулевым после. Если вы попытаетесь получить доступ к latLng в onCreate(), это не сработает, потому что он еще не попал в onLocationChanged(). - person Daniel Nugent; 30.11.2015
comment
это выдало мне ошибку: java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations. но у меня есть разрешения на настройку в манифестах <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - person Muhammad Shahzad; 19.12.2015
comment
@MuhammadShahzad Вы тестируете Android M (Android 6)? Если это так, вам нужно будет запросить пользователя во время выполнения, см. здесь: stackoverflow.com/questions/33063712/ - person Daniel Nugent; 19.12.2015
comment
Да, я тестирую на Android 6 - person Muhammad Shahzad; 19.12.2015
comment
@Daniel В вашем решении есть проблема. Если onStart вызывается до onMapready, клиент Google никогда не вызовет connect - person Johny19; 17.08.2016
comment
@johny в этом ответе нет onStart() .... похоже, вам просто нужно переместить некоторый код из onStart() в onMapReady(). Что у вас есть в вашем коде onStart()? - person Daniel Nugent; 17.08.2016
comment
Да забудьте, что я сказал, я смешал :/ с другим примером - person Johny19; 17.08.2016
comment
@ Johny19 Ааа, без проблем! - person Daniel Nugent; 17.08.2016
comment
@Daniel Nugent: не могли бы вы сказать мне, как уменьшить радиус этого широкого синего круга, точнее, я хочу уменьшить круг, чтобы получить высокую точность? - person Pratik Vyas; 11.10.2018
comment
@PratikVyas Этот синий круг исходит из фреймворка и основан на точности текущего местоположения. Я не думаю, что есть способ уменьшить синий кружок в коде приложения. По сути, фреймворку просто нужно получить блокировку местоположения с большей точностью. - person Daniel Nugent; 11.10.2018
comment
@DanielNugent: Спасибо за быстрый ответ, можем ли мы подсказать пользователю, что он имеет хорошую или плохую точность, используя метод getAccuracy диспетчера местоположений, если да, то какое идентичное значение будет проверено во время проверки. - person Pratik Vyas; 12.10.2018

Вы должны добавить следующие разрешения в манифест:

<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" />
person Muhammad Moosa    schedule 21.03.2016
comment
Вау... Спасибо, @MuhammadMoosa! Я потратил так много времени, пытаясь понять, почему мое местоположение не точно в одном приложении, В то время как, когда я отлаживаю свое другое приложение, оно было идеальным ... Я проверял разрешения много раз, и единственное, что мне не хватало, это <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>. Я даже не думал, что это разрешение как-то связано с картами.. - person chabislav; 29.04.2016
comment
На самом деле вам нужен только один. Либо ACCESS_COARSE_LOCATION, либо ACCESS_FINE_LOCATION, в зависимости от вашей реализации. - person mayid; 17.05.2020

MarkerOptions().position(new LatLng(
                            location.getLatitude(), location.getLongitude()));

Попробуй это,

   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);
            }
person Dwivedi Ji    schedule 22.07.2016