无法在谷歌地图活动中导航,它总是生成回我当前的位置



我是android开发的新手,正在开发一个需要谷歌地图活动的应用程序。我面临的问题是,当我试图平移(或滚动(地图时,我会立即重新定位到我最初设置的当前位置。如果能给我一点帮助就太好了,因为我正处于困境,无法找到解决方案。这是代码:-

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMapsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setScrollGesturesEnabled(true);
locationManager=(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
locationListener=new LocationListener() {
@Override
public void onLocationChanged(@NonNull Location location) {
centerOnMap(location,"Your Location");
}
};
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);
}
else{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListener);
Location lastKnownLocation=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
centerOnMap(lastKnownLocation,"Your Location");
}
}
public void centerOnMap(Location location,String address)
{
LatLng userLocation = new LatLng(location.getLatitude(),location.getLongitude());
mMap.addMarker(new MarkerOptions().position(userLocation).title(address));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull @org.jetbrains.annotations.NotNull String[] permissions, @NonNull @org.jetbrains.annotations.NotNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)==PackageManager.PERMISSION_GRANTED){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListener);
}
}
}

}

您可能有但没有说明的一个要求是:

lastLocation可用并且用户不移动地图,然后将地图放在该位置的中心。如果用户已经移动了地图,然后不将地图居中In无论是哪种情况,都在用户的位置添加一个标记。

在走得太远之前,必须注意的是,谷歌地图提供了功能类似于你试图实现的目标,尽管你仍然必须";移动照相机">。标记是一个蓝色的球,而不是典型的标记。参见myMap.setMyLocationEnabled(true)。就是这样!在获得地图权限后执行此操作。

但如果你不想使用它,下面是你需要的简单更改。

请记住,LocationManagergetLastKnownLocation可以返回如果设备还没有,则为null。所以我推荐一个小的改变一点不相关的-只需让位置侦听器完成所有工作,并消除这一特殊情况:

// this is where you initially check permissions and have them.
else{
locationManager.requestLocationUpdates (LocationManager.GPS_PROVIDER,0,0,locationListener);
// Here I removed the last location centering and let the
// location listener always handle it.
}

所以这开启了可能性用户可能正在与地图交互,并且最终到达最后的位置。我理解这就是你试图解决的问题。

(顺便说一句,在我看来,你把android.location.LocationManager的使用与FusedLocationProviderApi(com.google.android.gms.location(,所以我无法获得您的由于LocationListeners不兼容,需要编译的代码。不幸的是,谷歌地图有两个LocationListener类,所以为了确定你必须包括你的进口产品才能进一步了解。(

无论如何。。。

当地图首次准备就绪(onMapReady(时,地图的相机以CCD_ 10为中心。你可以得到相机的目标位置(中心(在任何时候使用CCD_ 11。

奇怪的是,要知道用户是否以任何方式与地图交互:滚动事件生成相机当触摸事件生成单独的事件时发生变化。摄像头更改不能独占使用,因为您的代码或用户可能缩放不会移动地图。你可以走这条路,但是为了这个答案的目的,为了简单起见,相机使用目标。

声明类实例变量(与定义mMap的区域相同(:

LatLng tgtCtr;

因此,在分配mMap之后,在您的onMapReady中执行:

tgtCtr = mMap.getCameraPosition().target;

所以假设你的代码在你发布的时候就存在(非常接近(,那么这些更改可能会有所帮助:

// This change simply restricts centering of the map on location
// update to only when user has not moved the map (scrolled).
@Override
public void onLocationChanged(@NonNull Location location) {
LatLng currentCtr = mMap.getCamaraPosition().target;

// This is not the ideal check since `double` comparisons 
// should account for epsilon but in this case of (0,0) it should work.

// Alternatively you could compute the distance of current
// center to (0,0) and then use an epsilon: 
//    see `com.google.maps.android.SphericalUtil.computeDistanceBetween`.

if (currentCtr.latitude == 0 && currentCtr.longitude == 0) {
centerOnMap(location,"Your Location");
}
}

保存为用户添加的标记似乎也是一个好主意位置-这是可选的,但可能会在防止多个标记时派上用场从添加到一个位置:

// Define a class instance variable
Marker myLocMarker = nulll;
// and then in centerOnMap
public void centerOnMap(Location location, String address)
{
// ... other code
if (myLocMarker == null) {
myLocMarker = mMap.addMarker(new MarkerOptions().position(userLocation).title(address));
}
// ... more code
}

因此,真正的唯一困难是弄清楚";具有用户移动了地图"在这种情况下,基于初始要求你不想移动地图。

正如您在评论部分提到的,使用FusedLocationProviderClient而不是LocationManager。在应用级渐变中添加implementation 'com.google.android.gms:play-services-location:17.0.0'。并且不要忘记为精细定位添加清单权限。

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
FusedLocationProviderClient mFusedLocationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setScrollGesturesEnabled(true);
getLastLocation();
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(@NonNull LatLng latLng) {
Location location = new Location(LocationManager.GPS_PROVIDER);
location.setLatitude(latLng.latitude);
location.setLongitude(latLng.longitude);
centerOnMap(location,"Your location");
}
});
}

@SuppressLint("MissingPermission")
private void getLastLocation() {
if (checkPermissions()) {
if (isLocationEnabled()) {
mFusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
Location location = task.getResult();
if (location == null) {
requestNewLocationData();
} else {
centerOnMap(location,"Your Location");
}
}
});
} else {
Toast.makeText(this, "Please turn on" + " your location...", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
} else {
requestPermissions();
}
}
@SuppressLint("MissingPermission")
private void requestNewLocationData() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5);
mLocationRequest.setFastestInterval(0);
mLocationRequest.setNumUpdates(1);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
private LocationCallback mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
Location mLastLocation = locationResult.getLastLocation();
centerOnMap(mLastLocation,"Your Location");
}
};
private boolean checkPermissions() {
return ActivityCompat.checkSelfPermission(this,   Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
private void requestPermissions() {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
private boolean isLocationEnabled() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
public void centerOnMap(Location location,String address)
{
LatLng userLocation = new LatLng(location.getLatitude(),location.getLongitude());
mMap.clear();
mMap.addMarker(new MarkerOptions().position(userLocation).title(address));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
getLastLocation();
}
}

}

最新更新