Последнее известное местоположение теряется, когда мы не в getLastLocation () - Android - PullRequest
3 голосов
/ 20 апреля 2020

Я пытаюсь создать метод, который получит последнее известное местоположение и назначит это значение глобальной переменной, которую я буду использовать позже. Я следую за этим обучением.

В конце я написал следующий код:

public void getCurrentLocation() {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    fusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            // Got last known location. In some rare situations this can be null.
            if (location != null) {
                // Logic to handle location object
                mCurrentLocation = new Location(location);
                System.out.println("In method getCurrentLocation: Latitude = " + location.getLatitude() + " Longitude = " + location.getLongitude());
                System.out.println("In method getCurrentLocation for mCurrentLocation: Latitude = " + mCurrentLocation.getLatitude() + " Longitude = " + mCurrentLocation.getLongitude());
                } else {
                Toast.makeText(MainActivity.this, "Can't get the current location", Toast.LENGTH_SHORT).show();
            }
        }
    });
}

Метод getCurrentLocation(), который я вызову в onCreate() метод MainActivity, и я могу видеть распечатки из метода, чтобы моя переменная получила местоположение, но если я попытаюсь использовать mCurrentLocation в каком-то другом контексте (например, я хочу go для последнее известное местоположение с использованием этой переменной) переменная будет null. Я не уверен, что мне нужно new Location(location), я добавил его, потому что я думал, что моя переменная будет указывать на null место в памяти после выхода из метода, но похоже, что это не так (я получаю тот же результат).

1 Ответ

2 голосов
/ 20 апреля 2020

Согласно официальной документации , Последнее известное местоположение может быть Нуль в случае:

  • Местоположение отключено в настройки устройства. Как он очищает кеш.
  • Устройство никогда не записывало свое местоположение. (Новое устройство)
  • Службы Google Play на устройстве перезапущены.

В этом случае вам следует requestLocationUpdates и получить новое местоположение на LocationCallback .

Следующими шагами ваше последнее известное местоположение никогда не будет нулевым.


Предварительное условие: Библиотека EasyPermission


Шаг 1: В файле манифеста добавьте это разрешение

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Шаг 2:

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //Create location callback when it's ready.
    createLocationCallback()

    //createing location request, how mant request would be requested.
    createLocationRequest()

    //Build check request location setting request
    buildLocationSettingsRequest()

    //FusedLocationApiClient which includes location 
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    //Location setting client
    mSettingsClient = LocationServices.getSettingsClient(this)

    //Check if you have ACCESS_FINE_LOCATION permission
    if (!EasyPermissions.hasPermissions(
            this@MainActivity,
            Manifest.permission.ACCESS_FINE_LOCATION)) {
        requestPermissionsRequired()
    }
    else{
        //If you have the permission we should check location is opened or not
        checkLocationIsTurnedOn()
    }

}

Шаг 3: Создайте необходимые функции для вызова в onCreate ()

private fun requestPermissionsRequired() {
    EasyPermissions.requestPermissions(
        this,
        getString(R.string.location_is_required_msg),
        LOCATION_REQUEST,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
}

private fun createLocationCallback() {
    //Here the location will be updated, when we could access the location we got result on this callback.
    mLocationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            super.onLocationResult(locationResult)
            mCurrentLocation = locationResult.lastLocation
        }
    }
}

private fun buildLocationSettingsRequest() {
    val builder = LocationSettingsRequest.Builder()
    builder.addLocationRequest(mLocationRequest!!)
    mLocationSettingsRequest = builder.build()
    builder.setAlwaysShow(true)
}

private fun createLocationRequest() {
    mLocationRequest = LocationRequest.create()
    mLocationRequest!!.interval = 0
    mLocationRequest!!.fastestInterval = 0
    mLocationRequest!!.numUpdates = 1
    mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}

public fun checkLocationIsTurnedOn() { // Begin by checking if the device has the necessary location settings.
    mSettingsClient!!.checkLocationSettings(mLocationSettingsRequest)
        .addOnSuccessListener(this) {
            Log.i(TAG, "All location settings are satisfied.")
            startLocationUpdates()
        }
        .addOnFailureListener(this) { e ->
            val statusCode = (e as ApiException).statusCode
            when (statusCode) {
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                    try {
                        val rae = e as ResolvableApiException
                        rae.startResolutionForResult(this@MainActivity, LOCATION_IS_OPENED_CODE)
                    } catch (sie: IntentSender.SendIntentException) {
                    }
                }
                LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                    mRequestingLocationUpdates = false
                }
            }
        }
}

private fun startLocationUpdates() {
    mFusedLocationClient!!.requestLocationUpdates(
        mLocationRequest,
        mLocationCallback, null
    )
}

Шаг 4:

Обработка обратных вызовов в onActivityResult () после подтверждения открытия местоположения или пользователя принимает его, чтобы открыть.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        LOCATION_IS_OPENED_CODE -> {
            if (resultCode == AppCompatActivity.RESULT_OK) {
                Log.d(TAG, "Location result is OK")
            } else {
                activity?.finish()
            }
        }
}

Шаг 5. Получите последнее известное местоположение от FusedClientApi

override fun onMapReady(map: GoogleMap) {
    mMap = map
    mFusedLocationClient.lastLocation.addOnSuccessListener {
        if(it!=null){
            locateUserInMap(it)
        }
    }

}
   private fun locateUserInMap(location: Location) {
    showLocationSafetyInformation()
    if(mMap!=null){
        val currentLocation = LatLng(location.latitude,location.longitude )
        addMarker(currentLocation)
    }
}


private fun addMarker(currentLocation: LatLng) {
    val cameraUpdate = CameraUpdateFactory.newLatLng(currentLocation)
    mMap?.clear()
    mMap?.addMarker(
        MarkerOptions().position(currentLocation)
            .title("Current Location")
    )
    mMap?.moveCamera(cameraUpdate)
    mMap?.animateCamera(cameraUpdate)
    mMap?.setMinZoomPreference(14.0f);
}

Надеюсь, это поможет.

Happy Coding ?

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