Я использовал LocationManager для отслеживания текущего местоположения пользователя. Теперь, после изменения диспетчера местоположений на API FusedLocation, синяя точка и круг не отображаются даже после установки map.setMyLocationEnabled(true)
. Я вижу значок текущего местоположения в верхнем правом углу фрагмента карты, но нажатие на него ничего не делает. Я вернул свой код в LocationManager, теперь я могу видеть синюю точку, указывающую на мое текущее местоположение. что может быть не так с использованием API Fused Location.
Синяя точка и круг не отображаются в MyLocation с использованием API-интерфейса Android Fuse Location
Ответы (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>
Результат:
person
Daniel Nugent
schedule
15.05.2015
Это сработало для меня. Однако мне нужно использовать местоположение, хранящееся в объекте LatLang. Когда я пытаюсь получить к ним доступ, я получаю исключение нулевого указателя. Есть идеи?
- person bholagabbar; 30.11.2015
@bholagabbar Если вам нужно, вы можете сохранить ссылку на текущий объект Location, возвращенный в
onLocationChanged()
, что этот код делает с использованием LatLng. Обязательно проверяйте, не является ли оно нулевым всякий раз, когда вы его используете, так как местоположение может еще не появиться. Все, что зависит от блокировки местоположения, отключите его в onLocationChanged(), если это необходимо.
- person Daniel Nugent; 30.11.2015
Я пытался сделать latLang gloabl, но все равно получаю исключение nullpointerException. Я не понял твоего пути. Не могли бы вы просто уточнить?
- person bholagabbar; 30.11.2015
@bholagabbar Объект LatLng будет нулевым до вызова первого обратного вызова местоположения
onLocationChanged()
, а затем ненулевым после. Если вы попытаетесь получить доступ к latLng
в onCreate()
, это не сработает, потому что он еще не попал в onLocationChanged()
.
- person Daniel Nugent; 30.11.2015
это выдало мне ошибку:
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
@MuhammadShahzad Вы тестируете Android M (Android 6)? Если это так, вам нужно будет запросить пользователя во время выполнения, см. здесь: stackoverflow.com/questions/33063712/
- person Daniel Nugent; 19.12.2015
Да, я тестирую на Android 6
- person Muhammad Shahzad; 19.12.2015
@Daniel В вашем решении есть проблема. Если onStart вызывается до onMapready, клиент Google никогда не вызовет connect
- person Johny19; 17.08.2016
@johny в этом ответе нет onStart() .... похоже, вам просто нужно переместить некоторый код из onStart() в onMapReady(). Что у вас есть в вашем коде onStart()?
- person Daniel Nugent; 17.08.2016
Да забудьте, что я сказал, я смешал :/ с другим примером
- person Johny19; 17.08.2016
@ Johny19 Ааа, без проблем!
- person Daniel Nugent; 17.08.2016
@Daniel Nugent: не могли бы вы сказать мне, как уменьшить радиус этого широкого синего круга, точнее, я хочу уменьшить круг, чтобы получить высокую точность?
- person Pratik Vyas; 11.10.2018
@PratikVyas Этот синий круг исходит из фреймворка и основан на точности текущего местоположения. Я не думаю, что есть способ уменьшить синий кружок в коде приложения. По сути, фреймворку просто нужно получить блокировку местоположения с большей точностью.
- person Daniel Nugent; 11.10.2018
@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
Вау... Спасибо, @MuhammadMoosa! Я потратил так много времени, пытаясь понять, почему мое местоположение не точно в одном приложении, В то время как, когда я отлаживаю свое другое приложение, оно было идеальным ... Я проверял разрешения много раз, и единственное, что мне не хватало, это
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
. Я даже не думал, что это разрешение как-то связано с картами..
- person chabislav; 29.04.2016
На самом деле вам нужен только один. Либо 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
MyLocation
, не имеет значения, что вы используете. Вам вообще не нужно добавлять какой-либо код, чтобы эта кнопка и синяя метка работали. - person Daniel Nugent   schedule 15.05.2015SupportMapFragment
? - person Daniel Nugent   schedule 15.05.2015SupportMapFragment
- person flexdroid   schedule 15.05.2015mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); map = mFragment.getMap(); map.setMyLocationEnabled(true);
- person Daniel Nugent   schedule 15.05.2015MyLocation
и синей точки на самом деле это не имеет никакого отношения к получению текущего местоположения в коде, так как карта делает всю работу для этого. - person Daniel Nugent   schedule 15.05.2015https://developer.android.com/training/location/receive-location-updates.html
в том же примере проекта, который вы создали, и методonLocationChanged()
укажет маркеру на текущее местоположение. - person flexdroid   schedule 15.05.2015