Kotlin — OnSharedPreferenceChangeListener

#android #kotlin #listener #application-settings

#Android #котлин #прослушиватель #приложение-настройки

Вопрос:

Я учусь разрабатывать свое первое приложение для Android. Я выбираю Kotlin просто потому, что… Я должен выбирать между Java и Kotlin, Google принял Kotlin в качестве официального языка, поэтому я использую его. Я написал много сообщений, прежде чем спросить об этом, но у меня ничего не работает. Я хочу выполнить функцию при изменении параметров в моем settings_activity. Кнопка переключения для переключения между видом со спутника GoogleMap на обычный вид. Как создать экземпляр OnSharedPreferenceChangeListener?

 class MapsActivity : AppCompatActivity(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener,
        GoogleMap.OnCameraIdleListener {

    private lateinit var map: GoogleMap
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var lastLocation: Location
    private lateinit var locationCallback: LocationCallback
    private lateinit var locationRequest: LocationRequest
    private var locationUpdateState = false
    private lateinit var MarkerOp: MarkerOptions
    private lateinit var Marker: Marker
    private lateinit var currentLatLng: LatLng

    companion object {
        private const val LOCATION_PERMISSION_REQUEST_CODE = 1
        private const val REQUEST_CHECK_SETTINGS = 2
    }

    var sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
        if (key == "satview") {
            var mysatview = sharedPreferences.getBoolean(key, false)
            if (mysatview) {
                map.mapType = GoogleMap.MAP_TYPE_HYBRID
            } else {
                map.mapType = GoogleMap.MAP_TYPE_NORMAL
            }
        }
    }

    private fun startLocationUpdates() {
        if (ActivityCompat.checkSelfPermission(
                this,
                android.Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                LOCATION_PERMISSION_REQUEST_CODE
            )
            return
        }

        fusedLocationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            null /* Looper */
        )
    }

    private fun createLocationRequest() {
        locationRequest = LocationRequest()
        locationRequest.interval = 10000
        locationRequest.fastestInterval = 5000
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY

        val builder = LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest)

        val clientPos = LocationServices.getSettingsClient(this)
        val taskPos = clientPos.checkLocationSettings(builder.build())

        taskPos.addOnSuccessListener {
            locationUpdateState = true
            startLocationUpdates()
        }

        taskPos.addOnFailureListener { exception ->
            if (exception 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().
                    exception.startResolutionForResult(
                        this@MapsActivity,
                        REQUEST_CHECK_SETTINGS
                    )
                } catch (sendEx: IntentSender.SendIntentException) {
                    // Ignore the error.
                }
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CHECK_SETTINGS) {
            if (resultCode == Activity.RESULT_OK) {
                locationUpdateState = true
                startLocationUpdates()
            }
        }
    }

    override fun onPause() {
        super.onPause()
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }

    public override fun onResume() {
        super.onResume()
        if (!locationUpdateState) {
            startLocationUpdates()
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //this.supportActionBar?.hide()
        setContentView(R.layout.activity_maps)
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        val mapFragment = supportFragmentManager
                .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

        locationCallback = object : LocationCallback() {
            override fun onLocationResult(p0: LocationResult) {
                super.onLocationResult(p0)

                lastLocation = p0.lastLocation
                currentLatLng = LatLng(lastLocation.latitude, lastLocation.longitude)
                if(::Marker.isInitialized) {
                    Marker.remove()
                }
                MarkerOp = (MarkerOptions()
                        .position(currentLatLng)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow))
                        .rotation(-map.cameraPosition.bearing)
                        )
                Marker = map.addMarker(MarkerOp)
            }
        }

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
        createLocationRequest()
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        val inflater: MenuInflater = menuInflater
        inflater.inflate(R.menu.menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle item selection
        when (item.itemId) {
            R.id.config -> {
                val intent = Intent(this, SettingsActivity::class.java)
                startActivity(intent)
                true
            }
            R.id.history -> {
                true
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onCameraIdle() {
        if(::MarkerOp.isInitialized) {
            MarkerOp.rotation(-map.cameraPosition.bearing)
        }
        if(::Marker.isInitialized) {
            Marker.remove()
            Marker = map.addMarker(MarkerOp)
        }
    }

    override fun onMapReady(googleMap: GoogleMap) {
        map = googleMap

        map.getUiSettings().setZoomControlsEnabled(true)
        map.setOnMarkerClickListener(this)
        map.setOnCameraIdleListener(this)

        val preferences = getPreferences(MODE_PRIVATE)
        preferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)

        if (ActivityCompat.checkSelfPermission(
                this,
                android.Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                LOCATION_PERMISSION_REQUEST_CODE
            )
            return
        }

        map.isMyLocationEnabled = true
    }

    override fun onMarkerClick(p0: Marker?) = false
}


 

Я не знаю, почему мое событие не активирует прослушиватель.
Спасибо за вашу помощь.

Комментарии:

1. java.lang.Boolean.getBoolean(key) всегда возвращает false, потому что возвращает true только в том случае, если вы передаете ему буквальную строку "true" . Если вам нужно значение общих настроек, замените его на sharedPreferences.getBoolean(key, false) . Недостаточно другого кода, чтобы узнать, что еще может пойти не так. Я не вижу никаких вызовов функций в вашем слушателе, поэтому я не знаю, как вы определяете, был ли он вызван или нет.

2. Спасибо за ответ. Я пройду весь свой класс, его будет проще отлаживать…

3. Пожалуйста, укажите, что именно происходит не так.

4. Привет. В моем settings_activity, когда я меняю «переключатель», прослушиватель не выполняет код для изменения отображения карты. Похоже, что слушатель не создан или неправильно. Если я проверяю значение во время запуска, оно работает хорошо, но не работает в реальном времени.