【发布时间】:2017-12-21 04:28:59
【问题描述】:
我想要实现的是显示用户最后知道的位置。如果 GPS 已禁用,请请求位置设置。当用户按下 OK 时,然后启用 GPS 并将地图相机移动到找到的位置。
当 GPS 已启用时,它会按预期工作;但是,如果不是,则地图相机不会移动,因为位置为空。
如果我在displayLocation() 函数内的else 语句(当location == null)之后添加initMap(),我可以完成这项工作,但是这个解决方案感觉有些不对劲。
有人能解释一下这里发生了什么吗?非常感谢!
顺便说一下,我使用的是MVP架构,所以当Activity启动时,第一个调用的函数是requestPermission()
class MainActivity : AppCompatActivity(), MainView, OnMapReadyCallback {
private val ZOOM_LEVEL = 12
private val ZOOM_DURATION = 2000
private val PERMISSION_REQUEST_CODE = 101
private val SETTINGS_REQUEST_CODE = 102
private val RC_SIGN_IN = 123
private lateinit var mMainPresent: MainPresenterImpl
private lateinit var mGoogleMap: GoogleMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mMainPresent = MainPresenterImpl(this)
mMainPresent.onCreate()
}
override fun onResume() {
super.onResume()
mMainPresent.onResume()
}
override fun onPause() {
super.onPause()
mMainPresent.onPause()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
PERMISSION_REQUEST_CODE -> {
if (grantResults.isEmpty() || grantResults[0] == PackageManager.PERMISSION_DENIED) {
finish()
} else {
initMap()
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
SETTINGS_REQUEST_CODE -> {
if (resultCode == Activity.RESULT_OK) {
initMap()
}
}
}
}
override fun onMapReady(googleMap: GoogleMap) {
mGoogleMap = googleMap
displayLocation()
}
override fun displayLoginMethods() {
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(!BuildConfig.DEBUG) // disables it for debug
.setAvailableProviders(
Arrays.asList<AuthUI.IdpConfig>(AuthUI.IdpConfig.Builder(AuthUI.FACEBOOK_PROVIDER).build(),
AuthUI.IdpConfig.Builder(AuthUI.PHONE_VERIFICATION_PROVIDER).build()))
.build(),
RC_SIGN_IN)
}
override fun requestPermission() {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_CODE)
}
} else {
requestLocationSettings()
}
}
override fun displayLocation() {
val mFusedLocationClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
try {
mGoogleMap.isMyLocationEnabled = true
mGoogleMap.uiSettings.isMyLocationButtonEnabled = true
mFusedLocationClient.lastLocation
.addOnSuccessListener(this) { location ->
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
val latitude = location.latitude
val longitude = location.longitude
val coordinate = LatLng(latitude, longitude)
mGoogleMap.addMarker(MarkerOptions().position(coordinate))
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(coordinate))
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(ZOOM_LEVEL.toFloat()), ZOOM_DURATION, null)
} else {
Log.d("displayLocation", "location = null")
}
}
} catch (e: SecurityException) {
Log.e("Exception: %s", e.message)
}
}
/**
* Initiates Google Map. Once it's ready it calls the onMapReady method
*/
override fun initMap() {
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
private fun createLocationRequest(): LocationRequest {
val locationRequest = LocationRequest()
locationRequest.interval = 10000
locationRequest.fastestInterval = 5000
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
return locationRequest
}
private fun requestLocationSettings() {
val builder = LocationSettingsRequest.Builder().addLocationRequest(createLocationRequest())
val client = LocationServices.getSettingsClient(this)
val task = client.checkLocationSettings(builder.build())
task.addOnSuccessListener(this) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
initMap()
}
task.addOnFailureListener(this) { e ->
if (e is ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
e.startResolutionForResult(this@MainActivity, SETTINGS_REQUEST_CODE)
} catch (sendEx: IntentSender.SendIntentException) {
// Ignore the error.
}
}
}
}
}
【问题讨论】:
标签: android google-maps gps location kotlin