android fusedlocationclient 无法获取位置

问题描述 投票:0回答:1

我的 Android 项目在启动时需要用户的最后/当前位置,但由于某种原因我没有获得有效的位置。

我的主要活动检查权限如下:

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        permissionHelper = PermissionHelper(this)
        val drawerLayout: DrawerLayout = binding.drawerLayout
        val navView: NavigationView = binding.navView
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_home) as NavHostFragment
        val navController = navHostFragment.navController

        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.nav_home,
                R.id.nav_account, R.id.nav_pictures, R.id.nav_settings
            ), drawerLayout
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)

        NavigationUI.setupWithNavController(binding.navView, navController)

        navController.addOnDestinationChangedListener { _, destination, _ ->
            isCurrentLocationFragmentVisible = destination.id == R.id.nav_home
            if (isCurrentLocationFragmentVisible) {
                invalidateOptionsMenu()
            }
        }
        handleLocationAndWeather()
        currentLocationViewModel.weather.observe(this){
            currentLocation = LocationDto(it.location.cityName, it.location.locationIndex)

        }


    }

    private fun handleLocationAndWeather() {
        // Check if location permission is granted
        if (permissionHelper.isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)) {
            // Permission is granted, load weather data
            viewModel.updatePermissionState(LocationPermissionState.Granted)
            viewModel.loadCurrentLocationWeather()
        } else {
            // Permission not granted, request it
            permissionHelper.requestPermission(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                "Location permission is required to get weather data for your current location.",
                LOCATION_PERMISSION_REQUEST_CODE
            )
        }
    }
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        when (requestCode) {
            LOCATION_PERMISSION_REQUEST_CODE -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission granted, update state and load weather data
                    viewModel.updatePermissionState(LocationPermissionState.Granted)
                    viewModel.loadCurrentLocationWeather()
                } else {
                    // Permission denied, update state and handle accordingly
                    viewModel.updatePermissionState(LocationPermissionState.Denied)
                    viewModel.loadCurrentLocationWeather()
                    //TODO show toast here
                }
            }

        }
    }

它使用此类来处理与权限相关的内容:

class PermissionHelper(private val activity: Activity) {


    fun isPermissionGranted(permission: String): Boolean {
        return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED
    }


    fun requestPermission(permission: String, rationale: String, requestCode: Int) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
            showRationaleDialog(rationale) { _, _ ->
                ActivityCompat.requestPermissions(
                   activity,
                    arrayOf(permission),
                    requestCode
                )
            }
        } else {
            ActivityCompat.requestPermissions(
               activity,
                arrayOf(permission),
                requestCode
            )
        }
    }


    private fun showRationaleDialog(message: String, onPositiveClick: (DialogInterface, Int) -> Unit) {

        AlertDialog.Builder(activity)
            .setTitle("Location permission Required")
            .setMessage(message)
            .setPositiveButton("OK", onPositiveClick)
            .setNegativeButton("Cancel", null)
            .show()
    }
}

主 Activity 调用视图模型根据位置获取数据:

private val _locationPermissionState = MutableStateFlow<LocationPermissionState>(LocationPermissionState.Granted)
val locationPermissionState: StateFlow<LocationPermissionState> = _locationPermissionState

fun updatePermissionState(state : LocationPermissionState){
    _locationPermissionState.value = state
}
@SuppressLint("MissingPermission")
fun loadCurrentLocationWeather() {
    viewModelScope.launch {
        when (locationPermissionState.value) {
            LocationPermissionState.Granted -> {
                Log.d(TAG, "permission granted")
                locationGetter.client.lastLocation
                    .addOnSuccessListener { location ->
                        // Check if the location is not null before proceeding
                        if (location != null) {
                            Log.d(TAG, "location not null")
                            viewModelScope.launch {
                                weatherRepository.getWeather(
                                    location.latitude,
                                    location.longitude
                                )
                                    .map { locationWithWeatherDataDto ->
                                        val weatherData =
                                            convertWeatherDtoToWeatherModel(
                                                locationWithWeatherDataDto.weather
                                            )
                                        val locationData = LocationModel(
                                            locationWithWeatherDataDto.location.cityName,
                                            locationWithWeatherDataDto.location.locationIndex
                                        )
                                        LocationWeatherModel(
                                            location = locationData,
                                            weather = weatherData
                                        )
                                    }
                                    .collect {
                                        _weather.value = it
                                        Log.d(TAG, it.weather.cityName)
                                    }
                            }
                        } else {
                            // location is null show seattle
                            Log.d(TAG, "location is null")
                            viewModelScope.launch {
                                weatherRepository.getWeather("Chicago")
                                    .map { locationWithWeatherDataDto ->
                                        val weatherData =
                                            convertWeatherDtoToWeatherModel(locationWithWeatherDataDto.weather)
                                        val locationData = LocationModel(
                                            locationWithWeatherDataDto.location.cityName,
                                            locationWithWeatherDataDto.location.locationIndex
                                        )
                                        LocationWeatherModel(location = locationData, weather = weatherData)
                                    }
                                    .collect {
                                        _weather.value = it
                                        Log.d(TAG, it.weather.cityName)
                                    }
                            }
                        }
                    }
            }
            else -> {
                //location permission is denied
                viewModelScope.launch {
                    weatherRepository.getWeather("Seattle")
                        .map { locationWithWeatherDataDto ->
                            val weatherData =
                                convertWeatherDtoToWeatherModel(locationWithWeatherDataDto.weather)
                            val locationData = LocationModel(
                                locationWithWeatherDataDto.location.cityName,
                                locationWithWeatherDataDto.location.locationIndex
                            )
                            LocationWeatherModel(location = locationData, weather = weatherData)
                        }
                }
            }
        }
    }
}

我已经明白了

  locationGetter.client.lastLocation
                        .addOnSuccessListener { location ->
                            // Check if the location is not null before proceeding
                            if (location != null) {

始终为空,这让我相信我没有获得有效的位置。我已经在模拟器中设置了一个位置,所以我怀疑它没有最后一个位置。 任何反馈将不胜感激!

android kotlin location fusedlocationproviderapi android-fusedlocation
1个回答
0
投票

Lastlocation 不会打开定位子系统。仅当操作系统已知该位置时,它才会返回结果。 99% 以上的时间它都会返回 null。这是一种优化,并且添加它可能是操作系统的设计错误。使用 requestLocationUpdates 或 requestSingleLocation 在操作系统中实际打开位置检测。

© www.soinside.com 2019 - 2024. All rights reserved.