java - 无法在谷歌地图 Activity 中导航,它总是会生成回到我当前的位置

标签 java android google-maps-android-api-3

我是 Android 开发新手,正在开发一个需要谷歌地图 Activity 的应用程序。 我面临的问题是,当我尝试平移(或滚动) map 时,我会立即重生到我最初设置的当前位置。 一点帮助就太好了,因为我现在陷入困境并且无法找到解决方案。 这是代码:-

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);
        }

    }
}

}

最佳答案

您可能有但未说明的一项要求是:

When the lastLocation becomes available and the user has not moved the map then center the map on the location. If the user has already moved the map then do not center the map. In either case, add a marker at the user's location.

在深入探讨之前,必须注意的是,Google map 提供了 功能与您想要实现的功能类似,尽管您仍然需要“移动相机”。该标记是一个蓝球,而不是典型的标记。请参阅myMap.setMyLocationEnabled(true)。就是这样!当您获得 map 权限后执行此操作。

但如果您不想使用它,那么这里是您需要的简单更改。

请记住,LocationManager getLastKnownLocation 可以返回 如果设备还没有,则为 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.
}

所以这开启了可能性 用户可以与 map 交互并最终到达最后一个位置。我理解这是您想要解决的问题。

(顺便说一句,在我看来,您正在将 android.location.LocationManager 的使用与 FusedLocationProviderApi (com.google.android.gms.location),所以我无法获取您的 由于 LocationListener 不兼容而需要编译的代码。 不幸的是,Google map 有两个 LocationListener 类,因此 为了确保您必须包含导入内容才能进一步了解。)

无论如何...

本地图第一次准备好(onMapReady)时, map 的相机 以(0,0)为中心。您可以获取相机目标位置(中心) 随时使用 LatLng tgtCtr = mMap.getCameraPosition().target;

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

声明一个类实例变量(与定义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
}

所以实际上唯一的困难是弄清楚“有 用户移动了 map 。”在这种情况下,基于最初的要求 您不会想移动 map 。

关于java - 无法在谷歌地图 Activity 中导航,它总是会生成回到我当前的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67744813/

相关文章:

java - 如何将 .jar 文件添加到 native 包?

java - JAXB 从 java 生成 nillable = "true"

java - 如何在 twitter4j 中创建模拟状态对象?

java - 如何在 JavaFX 中的 SplitPane Divider 上检测鼠标拖动事件

java - 添加 onReceivedSslError 时找不到符号错误

android - 整个应用程序中的 Facebook session - Android

android - 如何为 Android 应用程序创建自定义 gradle 插件

java - Android 谷歌地图 moveCamera 原因 "IllegalStateException: Illegal height"