You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Google Map Activity启动后自动关闭崩溃的问题?

我帮你排查了代码里几个可能导致崩溃的核心问题,咱们一步步来修复:

问题分析与修复方案

1. 修复mapFragment空指针异常

你在onCreate里定义了局部的SupportMapFragment变量,但全局的mapFragment从未被赋值,导致onRequestPermissionsResult里调用mapFragment.getMapAsync(this)时直接触发空指针崩溃。

修改代码:

把onCreate里的局部变量赋值给全局变量:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_driver_map);
    
    // 修复:将局部变量改为全局变量赋值
    mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.driver_map);
    
    // 后续权限判断逻辑保持不变
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(DriverMapActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
    }else{
        mapFragment.getMapAsync(this);
    }
    
    // 其他初始化代码...
}

2. 替换过时的GoogleApiClient位置更新逻辑

GoogleApiClient的LocationServices.FusedLocationApi已经被官方废弃,继续使用会导致兼容性问题甚至崩溃,建议改用FusedLocationProviderClient的现代API实现位置更新。

修改步骤:

  • 移除GoogleApiClient相关的接口实现(GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener)
  • 添加LocationCallback处理位置更新
  • 用FusedLocationProviderClient替代旧API

核心修改代码:

// 移除原来的GoogleApiClient相关变量
// GoogleApiClient mGoogleApiClient;
// Location mLastLocation;
// LocationRequest mLocationRequest;

// 添加位置回调
private LocationCallback mLocationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(LocationResult locationResult) {
        if (locationResult == null || getApplicationContext() == null) {
            return;
        }
        for (Location location : locationResult.getLocations()) {
            // 更新地图视角
            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
            mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

            // 更新Firebase位置(先判断用户是否登录)
            FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
            if (currentUser != null) {
                String userId = currentUser.getUid();
                DatabaseReference ref = FirebaseDatabase.getInstance().getReference("DriversAvailable");
                GeoFire geofire = new GeoFire(ref);
                geofire.setLocation(userId, new GeoLocation(location.getLatitude(), location.getLongitude()));
            }
        }
    }
};

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    // 先检查权限
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
        return;
    }

    // 启用"我的位置"层
    mMap.setMyLocationEnabled(true);

    // 获取最后已知位置并移动相机
    fusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, location -> {
                if (location != null) {
                    LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
                    mMap.addMarker(new MarkerOptions().position(currentLatLng).title("我的当前位置"));
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 11));
                }
            });

    // 设置位置更新参数
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setInterval(1000);
    locationRequest.setFastestInterval(1000);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    // 开始位置更新
    fusedLocationClient.requestLocationUpdates(locationRequest, mLocationCallback, Looper.getMainLooper());
}

@Override
protected void onStop() {
    super.onStop();
    // 停止位置更新
    fusedLocationClient.removeLocationUpdates(mLocationCallback);

    // 移除Firebase位置(避免用户未登录时崩溃)
    FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
    if (currentUser != null) {
        String userId = currentUser.getUid();
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("DriversAvailable");
        GeoFire geofire = new GeoFire(ref);
        geofire.removeLocation(userId);
    }
}

3. 修复onStop的空指针风险

原来的代码直接调用FirebaseAuth.getInstance().getCurrentUser().getUid(),如果用户未登录(比如异常退出场景),getCurrentUser()会返回null,导致崩溃。上面的代码已经添加了用户非空判断,解决了这个问题。

4. 优化权限申请回调逻辑

确保权限通过后正确初始化地图,同时处理权限拒绝的场景:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == LOCATION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            if (mapFragment != null) {
                mapFragment.getMapAsync(this);
            }
        } else {
            Toast.makeText(getApplicationContext(), "需要位置权限才能显示地图,请开启权限后重试", Toast.LENGTH_LONG).show();
            finish(); // 权限拒绝时退出当前页面
        }
    }
}

这些修改主要解决了空指针异常、过时API的兼容性问题,同时优化了权限和位置更新的逻辑,应该能彻底解决你遇到的崩溃问题。

内容的提问来源于stack exchange,提问作者clinewton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:45:19