kotlin.KotlinNullPointerException, при попытке добавить маркер на карту после результатов поиска в kotlin - PullRequest
0 голосов
/ 19 октября 2019

Я пытаюсь внедрить SDK автозаполнения поиска мест Google в мое приложение kotlin android.

Использую второй метод, указанный в официальной документации:

Использовать намерениезапустить автозаполнение активности

Вот мой код:


    private  var fromLocation: LatLng? = LatLng(0.0, 0.0)
    private  var toLocation: LatLng? = LatLng(0.0, 0.0)


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                val place: Place? = data?.let { Autocomplete.getPlaceFromIntent(it) }
                if (PLACE_PICKING_MODE == 1) {
                    fromLocation = place?.latLng
                    val theIcon = R.drawable.gps_default
                    placeMarkerOnMap(fromLocation, theIcon)
                    map.animateCamera(CameraUpdateFactory.newLatLngZoom(fromLocation, 17f))
                } else if (PLACE_PICKING_MODE == 2) {
                    toLocation = place?.latLng
                    val theIcon = R.drawable.gps_default
                    placeMarkerOnMap(toLocation, theIcon)
                    map.animateCamera(CameraUpdateFactory.newLatLngZoom(toLocation, 17f))
                }
            } else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
                // TODO: Handle the error.
                val status: Status = Autocomplete.getStatusFromIntent(data!!)
            } else if (resultCode == RESULT_CANCELED) {
                println("user Canceled")
            }
        }


        if (requestCode == REQUEST_CHECK_SETTINGS) {
            if (resultCode == Activity.RESULT_OK) {
                locationUpdateState = true
                startLocationUpdates()
            }
        }


    }

каждый раз, в конце концов, он заканчивается с ошибкой kotlin.KotlinNullPointerExceptio

ОБНОВЛЕНИЕ

Основываясь на ответе JJ Jacobs , я изменил несколько строк внутри IF statements, чтобы они были такими:

                if (PLACE_PICKING_MODE == 1) {
                    if (place != null) {
                        fromLocation = place.latLng!!
                    }
                    val theIcon = R.drawable.gps_default
                    placeMarkerOnMap(fromLocation, theIcon)
                    map.animateCamera(CameraUpdateFactory.newLatLngZoom(fromLocation, 17f))
                } else if (PLACE_PICKING_MODE == 2) {
                    if (place != null) {
                        toLocation = place.latLng!!
                    }
                    val theIcon = R.drawable.gps_default
                    placeMarkerOnMap(toLocation, theIcon)
                    map.animateCamera(CameraUpdateFactory.newLatLngZoom(toLocation, 17f))
                }

Но все же этовыдаёт мне ошибку:

Failure delivering result ResultInfo{who=null, request=4, result=-1, data=Intent { (has extras) }} to activity {com.innoventiq.arkbeh/com.innoventiq.arkbeh.MainActivity}: kotlin.KotlinNullPointerException

и указал мне на эти строки:

fromLocation = place.latLng!!

и

toLocation = place.latLng!!

1 Ответ

1 голос
/ 19 октября 2019

Глядя на полученный код ошибки, он должен точно определить, какая строка вызывает NullPointerException.

Если data = null (поскольку он имеет тип Intent с нулевым значением), place также будет null (блок data?.let{...} возвращает только null в этом случае). Это вызывает проблемы в 3 местах:

  1. В первом блоке if(PLACE_PICKING_MODE == 1), fromLocation теперь также будет null и ваш вызов placeMarkerOnMap со значением null для местоположения.
  2. Во втором блоке if та же проблема с toLocation
  3. При извлечении состояния из намерения, если data равно null, data!! выдает KotlinNullPointerException

Вам, вероятно, просто нужно сделать еще null проверок перед выполнением любой условной логики.

РЕДАКТИРОВАТЬ

Хороший способ сделатьnull проверка будет делать что-то вроде следующего

val place: Place? = data?.let { Autocomplete.getPlaceFromIntent(it) }

if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
    if (resultCode == RESULT_OK) {
        val place: Place? = data?.let { Autocomplete.getPlaceFromIntent(it) }
        place?.let { //One time null-check for place
            if (PLACE_PICKING_MODE == 1) {
                fromLocation = it.latLng
                val theIcon = R.drawable.gps_default
                placeMarkerOnMap(fromLocation, theIcon)
                map.animateCamera(CameraUpdateFactory.
                    newLatLngZoom(fromLocation, 17f))
            } else if (PLACE_PICKING_MODE == 2) {
                toLocation = it.latLng
                val theIcon = R.drawable.gps_default
                placeMarkerOnMap(toLocation, theIcon)
                map.animateCamera(CameraUpdateFactory.
                    newLatLngZoom(toLocation, 17f))
            }
        }
    } else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
        // TODO: Handle the error.
        val status: Status = Autocomplete.getStatusFromIntent(data!!)
    } else if (resultCode == RESULT_CANCELED) {
        println("user Canceled")
    }
}

Однако, если вы посмотрите на документацию, на которую вы ссылались в исходном вопросе, вы можете на самом деле избавиться от проверки data?.let{...}, потому что обычноФункция на самом деле устанавливает данные как необнуляемые. Сигнатура функции

override fun onActivityResult(int requestCode, int resultCode, Intent data)

фактически гарантирует, что намерение никогда не должно быть null, если вы не установите его в null в своем коде для ваших целей. Настоящая проблема должна заключаться в том, что place.latLng - это null и, вероятно, не должно быть. Но если это возможно в вашем окончательном приложении, вам нужно выполнить нулевую проверку и обработать ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...