【问题标题】:Location is null unless GoogleMap is initialized again除非再次初始化 GoogleMap,否则位置为空
【发布时间】: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


    【解决方案1】:

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

     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);
            }
        };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 2020-11-23
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      相关资源
      最近更新 更多