除非再次初始化GoogleMap,否则位置为空

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了除非再次初始化GoogleMap,否则位置为空相关的知识,希望对你有一定的参考价值。

我想要实现的是显示用户的最后知道位置。如果GPS已禁用,请请求位置设置。当用户按下OK时,启用GPS并将地图相机移动到找到的位置。

当GPS已经启用时,它可以正常工作;但是,如果不是,地图相机就不会移动,因为该位置为空。

如果我在initMap()函数中的else语句(当location == null)之后添加displayLocation(),我可以使这个工作,但是对于这个解决方案感觉不对。

有人可以解释一下这里发生了什么吗?我非常感谢!

顺便说一下,我正在使用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.
            }
        }
    }
}

}

答案

状态更改时,您可以使用以下回调,

 private final LocationListener locationListener = new LocationListener() {

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderDisabled(String provider) {
            updateWithNewLocation(null);
        }

        @Override
        public void onLocationChanged(Location location) {
            updateWithNewLocation(location);
        }
    };

以上是关于除非再次初始化GoogleMap,否则位置为空的主要内容,如果未能解决你的问题,请参考以下文章

定义指针变量时,必须将指针变量初始化为NULL(为空),否则,指针变量会由于初始化位置的不确定

在OpenGL中,除非我再次重新指定顶点属性,否则为啥我的缓冲区对象不会绘制?

片段中的 GoogleMap 为空

除非setter是通用的,否则反序列化时JsonConvert不会初始化属性

没有显示地理位置的googleMap

除非用户向上滚动,否则保持溢出 div 滚动到底部