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

Android Studio无法获取定位,调用getLatitude空指针异常如何解决

Android 实时定位空指针问题修复方案

错误原因

你遇到的空指针异常是调用fusedLocationClient.lastLocation时触发,该接口仅返回系统缓存的历史位置,无有效缓存时就会返回null,直接调用getLatitude()方法就会触发空引用异常,且该接口本身就不满足实时定位的需求。

修复步骤

你需要改用requestLocationUpdates主动发起实时定位请求,具体修改如下:

  1. 新增位置相关API导入
  2. 初始化定位请求配置与定位结果回调
  3. 替换原有缓存定位逻辑为主动实时定位
  4. 补全权限回调逻辑,新增生命周期资源释放避免内存泄漏

完整修改后代码

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Bundle
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.moapp.guardaroundd.R
import com.moapp.guardaroundd.databinding.FragmentMapBinding
import com.moapp.guardaroundd.utils.Constants.DEFAULT_ZOOM
import com.moapp.guardaroundd.utils.Constants.LOCATION_PERMISSION_REQUEST_CODE
import com.moapp.guardaroundd.utils.createAlertEnableLocation


class MapFragment : Fragment(), OnMapReadyCallback {

    private lateinit var mMap: GoogleMap
    private lateinit var binding: FragmentMapBinding
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private var mLocationPermissionsGranted = false
    // 新增:定位请求配置
    private lateinit var locationRequest: LocationRequest
    // 新增:定位结果回调
    private lateinit var locationCallback: LocationCallback


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentMapBinding.inflate(layoutInflater)

        val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity())
        // 初始化定位配置
        initLocationConfig()

        return binding.root
    }

    // 新增:初始化定位请求和回调逻辑
    private fun initLocationConfig() {
        locationRequest = LocationRequest.create().apply {
            // 定位间隔,单位毫秒,可按需调整
            interval = 5000
            // 最快定位间隔
            fastestInterval = 2000
            // 高精度定位模式,优先使用GPS
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        }
        // 定位结果回调
        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                super.onLocationResult(locationResult)
                val location = locationResult.lastLocation ?: return
                // 拿到实时定位后执行逻辑
                moveCamera(LatLng(location.latitude, location.longitude))
                mMap.isMyLocationEnabled = true
                // 如果只需要一次定位,拿到结果后就停止定位,降低功耗
                stopLocationUpdate()
            }
        }
    }

    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
        getLocationPermission()
    }

    private fun isLocationEnabled(): Boolean {
        val locationManager = activity?.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
        // 避免空指针强转崩溃
        return locationManager?.let {
            it.isProviderEnabled(LocationManager.GPS_PROVIDER) || it.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
        } ?: false
    }

    private fun moveCamera(latLng: LatLng) {
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM))
    }

    // 修改:替换原有缓存定位逻辑为实时定位请求
    private fun getLocation() {
        if (isLocationEnabled()) {
            if (ActivityCompat.checkSelfPermission(
                    requireContext(),
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                    requireContext(),
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                return
            }
            fusedLocationClient.requestLocationUpdates(
                locationRequest,
                locationCallback,
                Looper.getMainLooper()
            )
        } else {
            createAlertEnableLocation(requireContext())
        }
    }

    // 新增:停止定位请求
    private fun stopLocationUpdate() {
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }

    private fun getLocationPermission() {
        if (ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            mLocationPermissionsGranted = true
            getLocation()
        } else {
            ActivityCompat.requestPermissions(
                requireActivity(),
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                LOCATION_PERMISSION_REQUEST_CODE
            )
        }
    }

    // 修复:权限授权后主动调用定位
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        mLocationPermissionsGranted = false
        when (requestCode) {
            LOCATION_PERMISSION_REQUEST_CODE -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mLocationPermissionsGranted = true
                    getLocation()
                }
            }
        }
    }

    // 新增:页面不可见时停止定位,避免内存泄漏和不必要的功耗
    override fun onStop() {
        super.onStop()
        stopLocationUpdate()
    }
}

注意事项

  • 确保你module级的build.gradle文件中已经引入了定位依赖:
    implementation "com.google.android.gms:play-services-location:21.0.1"
    
    版本号可以替换为官方最新稳定版
  • 如果你的App适配Android 12及以上系统(targetSdk >= 31),需要在AndroidManifest.xml中补充对应定位权限声明,后台定位还需要额外申请ACCESS_BACKGROUND_LOCATION权限
  • 可根据业务需求调整定位间隔,不需要高频定位时尽量调大间隔减少功耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:15:02