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

Android Studio中OnMapReady方法内无法获取getter返回值的问题

问题原因

你遇到的空指针崩溃由以下几个问题共同导致:

  1. sosrecords 实例未初始化:你只声明了全局变量SosRecords sosrecords;,没有创建实例就直接调用setCallFor()、setLatitude()等方法,不仅会直接触发空指针,就算没触发,实例内部的Latitude、Longitude默认值也是null
  2. 时序逻辑错误:你在点击Proceed按钮后,先执行Firestore异步查询,之后才启动定位更新。定位回调onLocationResult是异步触发的,你在Firestore成功回调里取经纬度时,大概率还没收到定位结果,Latitude和Longitude还是null
  3. 包装类默认空值问题:SosRecords类中经纬度用的是包装类Double,没有设置初始值的情况下默认值为null,LatLng构造方法需要传入基本类型double,自动拆箱时遇到null就会抛出你收到的空指针报错
解决方案

步骤1:初始化SosRecords实例

在Activity的onCreate生命周期方法中初始化实例,并给经纬度设置默认值:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 你的原有布局加载等逻辑
    setContentView(R.layout.activity_main);
    
    // 新增初始化逻辑
    sosrecords = new SosRecords();
    // 设置默认经纬度,避免未获取定位时空值问题
    sosrecords.setLatitude(0.0);
    sosrecords.setLongitude(0.0);
    
    // 其他原有初始化逻辑
}

步骤2:调整时序+增加空值判断

把启动定位的逻辑放到Firestore查询之前,同时所有取经纬度的地方都增加空值判断,避免拆箱空指针:
首先修改按钮点击逻辑,先启动定位:

builder.setPositiveButton("Proceed", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // 先判断定位权限,启动定位
        if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
            checkSettingsAndStartLocationUpdates();
        }else{
            askLocationPermission();
            dialog.dismiss();
            return;
        }
        sosrecords.setCallFor(selectedOfficer);
        startclicked= false;
        // 不要手动调用onStart,这是系统生命周期方法,系统会自动触发
        // 原有Firestore查询逻辑保留
        if(FirebaseAuth.getInstance().getCurrentUser()!= null){
            DocumentReference df = FirebaseFirestore.getInstance().collection("Users").document(FirebaseAuth.getInstance().getCurrentUser().getUid());
            df.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                @Override
                public void onSuccess(DocumentSnapshot documentSnapshot) {
                    if(documentSnapshot.getString("FullName")!= null){
                        String id = reff.push().getKey();
                        Log.d(TAG, "asdasd"+id);
                        // 取经纬度前先做空判断
                        Double lat = sosrecords.getLatitude();
                        Double lon = sosrecords.getLongitude();
                        if(lat == null || lon == null){
                            Toast.makeText(MainActivity.this, "暂未获取到位置,请稍后重试", Toast.LENGTH_SHORT).show();
                            return;
                        }
                        SosRecords sosRecords = new SosRecords(documentSnapshot.getString("FullName"), documentSnapshot.getString("PhoneNumber"), documentSnapshot.getString("UserEmail"), lat, lon, sosrecords.getCallFor());
                        reff.child(id).setValue(sosRecords);
                        sosrecords.setRecordID(id);
                        btnStartSOS.setEnabled(false);
                        btnStopSOS.setEnabled(true);
                        Toast.makeText(MainActivity.this, "你已成功触发SOS请求!", Toast.LENGTH_SHORT).show();
                        LatLonLoop.run();
                        smf.getMapAsync(new OnMapReadyCallback() {
                            @Override
                            public void onMapReady(GoogleMap googleMap) {
                                // 这里同样做空判断
                                Double mapLat = sosrecords.getLatitude();
                                Double mapLon = sosrecords.getLongitude();
                                if(mapLat == null || mapLon == null){
                                    Toast.makeText(MainActivity.this, "暂未获取到位置,无法标记", Toast.LENGTH_SHORT).show();
                                    return;
                                }
                                LatLng latLng = new LatLng(mapLat, mapLon);
                                MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("当前位置");
                                googleMap.addMarker(markerOptions);
                                googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15));
                            }
                        });
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    FirebaseAuth.getInstance().signOut();
                    startActivity(new Intent(getApplicationContext(),Login.class));
                    finish();
                }
            });
        }
        dialog.dismiss();
    }
});

步骤3:实现实时更新位置标记(可选)

如果需要定位更新后自动刷新地图标记,可新增全局变量存储GoogleMap和Marker实例,在定位回调中更新标记:
首先新增全局变量:

private GoogleMap mMap;
private Marker currentMarker;

修改onMapReady逻辑:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    Double mapLat = sosrecords.getLatitude();
    Double mapLon = sosrecords.getLongitude();
    if(mapLat != null && mapLon != null){
        LatLng latLng = new LatLng(mapLat, mapLon);
        currentMarker = mMap.addMarker(new MarkerOptions().position(latLng).title("当前位置"));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15));
    }
}

修改定位回调onLocationResult逻辑:

@Override
public void onLocationResult(LocationResult locationResult) {
    if (locationResult == null) {
        return;
    }
    for (Location location : locationResult.getLocations()) {
        double lat = location.getLatitude();
        double lon = location.getLongitude();
        sosrecords.setLatitude(lat);
        sosrecords.setLongitude(lon);
        // 实时更新地图标记
        if(mMap != null){
            LatLng newLatLng = new LatLng(lat, lon);
            if(currentMarker == null){
                currentMarker = mMap.addMarker(new MarkerOptions().position(newLatLng).title("当前位置"));
            }else{
                currentMarker.setPosition(newLatLng);
            }
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(newLatLng,15));
        }
    }
}

内容的提问来源于stack exchange,提问作者WEI ZHUANG GOH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 04:45:07