由于使用 GPS 获取当前位置较晚导致应用程序崩溃
Posted
技术标签:
【中文标题】由于使用 GPS 获取当前位置较晚导致应用程序崩溃【英文标题】:App Crash due to lateinit of late getting current location with GPS 【发布时间】:2021-11-05 05:05:29 【问题描述】:我正在尝试获取当前位置,但是应用程序崩溃是因为应用程序发现了 lateinit 属性尚未初始化,因为该应用程序尚未请求 GPS 的用户许可以获取当前位置。
下面是代码:
class FirstFragment : Fragment(), OnMapReadyCallback
private var _binding: FragmentFirstBinding? = null
private val binding get() = _binding!!
private lateinit var currentLocation: Location
private lateinit var fusedLocationProvider: FusedLocationProviderClient
private val permissionCode = 101
private lateinit var googleMap: GoogleMap
private val MasjidZahir = com.google.android.gms.maps.model.LatLng(6.1046784,100.3716608)
private val Jabil = com.google.android.gms.maps.model.LatLng(5.3267065,100.2820637)
private val TARUCKL = com.google.android.gms.maps.model.LatLng(3.2162302,101.7267724)
private val TARUCPG = com.google.android.gms.maps.model.LatLng(5.4532105,100.2826858)
private val MARINA = com.google.android.gms.maps.model.LatLng(1.3149938,103.890498)
private var locationArrayList: ArrayList<com.google.android.gms.maps.model.LatLng>? = null
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
fusedLocationProvider = LocationServices.getFusedLocationProviderClient(requireActivity())
fetchLocation()
override fun onActivityCreated(savedInstanceState: Bundle?)
super.onActivityCreated(savedInstanceState)
val map = binding.mapView
mapView.onCreate(savedInstanceState)
mapView.onResume()
mapView.getMapAsync(this)
locationArrayList = ArrayList()
locationArrayList!!.add(MasjidZahir)
locationArrayList!!.add(Jabil)
locationArrayList!!.add(TARUCKL)
locationArrayList!!.add(TARUCPG)
locationArrayList!!.add(MARINA)
private fun fetchLocation()
if (ActivityCompat.checkSelfPermission(requireContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(requireContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(requireActivity(), arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), permissionCode)
return
val task = fusedLocationProvider.lastLocation
task.addOnSuccessListener location ->
if(location != null)
currentLocation = location
Toast.makeText(this.context, currentLocation.latitude.toString() + " "
+ currentLocation.longitude.toString(), Toast.LENGTH_SHORT).show()
override fun onMapReady(map: GoogleMap)
googleMap = map
for(i in locationArrayList!!.indices)
googleMap.addMarker(MarkerOptions().position(locationArrayList!![i]).title("Marker $i"))
googleMap.animateCamera(CameraUpdateFactory.zoomTo(18.0f))
googleMap.moveCamera(CameraUpdateFactory.newLatLng(locationArrayList!![i]))
// Here is the problem
val latLng = com.google.android.gms.maps.model.LatLng(currentLocation.latitude, currentLocation.longitude)
val markerOptions = MarkerOptions().position(latLng).title("Current Location")
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16.0f))
googleMap.addMarker(markerOptions)
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
)
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when(requestCode)
permissionCode -> if (grantResults.isEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
fetchLocation()
如何防止应用崩溃,或者让 onMapReady() 先等待用户的权限请求,然后再将当前位置标记放到地图上?
【问题讨论】:
此处 currentLocation 属性未初始化 【参考方案1】:两件事
在这种情况下不要使用lateinit
,因为您试图在获得无法保证您会得到的东西之前访问属性
改为可空
private var currentLocation: Location? = null
然后在访问它之前进行空检查
if(currentLocation != null)
第二次移动你在地图上放置地图标记的位置,而不是在onMapReady
中,你还应该让你的googleMap
属性为空,因为你可能会遇到接收到位置的情况在地图准备好之前,如果您已经有位置,您可以在 onMapReady 中设置位置,或者在获得位置时设置它,因为地图在您获得位置之前就已经准备好了
【讨论】:
你需要currentLocation?.let
之类的东西,或者在if语句之前加上val currentLocation = currentLocation
,因为它是一个属性。以上是关于由于使用 GPS 获取当前位置较晚导致应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
Android:如何使用 GPS 提供程序获取离线当前位置?