android - 为什么我的 Android Kotlin 应用程序不请求用户的许可来打开位置?

标签 android kotlin permissions location

我的应用未向用户请求权限以打开 Location。当我手动打开 Location 时,我的应用程序按预期工作,但当我手动关闭 Location 时,它不会按预期工作,并且不会提示用户允许打开 Location 重新打开。

这是我的 Kotlin 代码:

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        when (requestCode) {
            REQUEST_CODE -> {
                if (grantResults.size > 0) {

                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
                    }

                }
            }
        }
    }


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

        selectedCounty = intent.getStringExtra("COUNTY")!!

        // Custom action bar code to return to list of counties
        val actionBar: ActionBar? = this.supportActionBar

        actionBar?.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM)
        actionBar?.setDisplayShowCustomEnabled(true)
        actionBar?.setCustomView(R.layout.custom_action_bar_1)
        val countiesLabel: TextView = findViewById<TextView>(R.id.countiesTextView)
        countiesLabel.text = selectedCounty
        val view : View? = actionBar?.customView
        actionBar?.setCustomView(view)

        sites.clear()

        db.collection("UKSites")
            .document("England")
            .collection("Counties")
            .document(selectedCounty!!)
            .collection(selectedCounty!!)
            .get()
            .addOnSuccessListener { documents ->
                for (document in documents) {

                    val site: Site =
                        Site(document.data["Name"].toString())

                    site.address.line1 = document.data["Address Line 1"].toString()
                    site.address.line2 = document.data["Address Line 2"].toString()
                    site.address.line3 = document.data["Address Line 3"].toString()
                    site.address.line4 = document.data["Address Line 4"].toString()
                    site.address.postcode = document.data["Postcode"].toString()
                    site.address.phoneNumber = document.data["Telephone"].toString()
                    site.address.siteURL = document.data["Site URL"].toString()
                    site.description = document.data["Description"].toString()
                    site.price = document.data["Price"] as Double
                    site.distance = 0
                    site.locationCoordinate.Longitude = document.data["Longitude"] as Double
                    site.locationCoordinate.Latitude = document.data["Latitude"] as Double

                    sites.add(site)

                }

                // Check permission
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {

                    ActivityCompat.requestPermissions(
                        this,
                        arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                        REQUEST_CODE
                    )

                } else {

                    BuildLocationRequest()
                    BuildLocationCallback()

                    // Create FusedProviderClient
                    fusedLocationProviderClient =
                        LocationServices.getFusedLocationProviderClient(this)


                    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                        ActivityCompat.requestPermissions(
                            this,
                            arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                            REQUEST_CODE
                        )


                    } else {

                        fusedLocationProviderClient.requestLocationUpdates(
                            locationRequest,
                            locationCallback,
                            Looper.myLooper()
                        )

                    }

                }
            }
            .addOnFailureListener { exception ->
                Log.w("Error", "Error getting documents: ", exception)

            }

    }

    private fun BuildLocationRequest() {
        locationRequest = LocationRequest()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 5000
        locationRequest.fastestInterval = 3000
        locationRequest.smallestDisplacement = 10f

    }

    private fun BuildLocationCallback() {
        locationCallback = object : LocationCallback() {

            override fun onLocationResult(p0: LocationResult?) {

                val currentCoordinate = p0!!.locations.get(p0.locations.size - 1)

                // Build URL for web request
                var distanceAPIURL : String = BASE_URL + "&origins="
                var siteLatitude: Double
                var siteLongitude: Double

                // add current location parameter to API URL
                distanceAPIURL += "${currentCoordinate.latitude},${currentCoordinate.longitude}"

                // add site destinations to API URL
                distanceAPIURL += "&destinations="

                // Build API request from site locations
                for (site in sites) {

                    siteLatitude  = site.locationCoordinate.Latitude!!
                    siteLongitude = site.locationCoordinate.Longitude!!

                    if (site == sites.first()) {

                        distanceAPIURL += "${siteLatitude}%2C${siteLongitude}"

                    } else {

                        distanceAPIURL += "%7C${siteLatitude}%2C${siteLongitude}"

                    }

                }

                // Add API KEY
                distanceAPIURL += GOOGLE_API_KEY

                // Make web requests to Google
                val distanceRequest = object : StringRequest(Method.POST, distanceAPIURL, Response.Listener { response ->

                    // Parse out distances from returned data
                    siteDistances = parseOutDistanceValues(response)

                    // Update distance information for each site
                    for (siteIndex in 0 until sites.size) {

                        sites[siteIndex].distance = siteDistances[siteIndex]

                    }

                    // Sort sites in ascending order of distance
                    sites = sortByDistance(sites)

                    // Recycler View code here
                    recyclerView = findViewById<View>(R.id.recyclerView) as RecyclerView

                    adapter = SiteAdapter(this@CountiesActivity, sites, selectedCounty!!)

                    val layoutManager = LinearLayoutManager(applicationContext)

                    recyclerView!!.layoutManager = layoutManager

                    recyclerView!!.itemAnimator = DefaultItemAnimator()

                    // Add a neat dividing line between items in the list
                    recyclerView!!.addItemDecoration(DividerItemDecoration(this@CountiesActivity, LinearLayoutManager.VERTICAL))

                    recyclerView!!.addItemDecoration(
                        ItemOffsetDecoration(
                            applicationContext,
                            0,
                            0
                        )
                    )

                    // set the adapter
                    recyclerView!!.adapter = adapter


                }, Response.ErrorListener { error ->

                    Log.d("ERROR", "Could not calculate distances to sites: ${error.localizedMessage}")

                }) {

                }

                Volley.newRequestQueue(applicationContext).add(distanceRequest)

            }
        }
    }

最佳答案

可能您没有在 AndroidManifest.xml 文件中添加权限。

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

除此之外,关注official documentation以这种方式请求许可:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
        android.Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {

    // Permission is not granted
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            android.Manifest.permission.ACCESS_FINE_LOCATION)) {
        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.
    } else {
        // No explanation needed, we can request the permission.
        ActivityCompat.requestPermissions(thisActivity,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                REQUEST_CODE)

        // REQUEST_CODE is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
} else {
    // Permission has already been granted
}

更新:turn on location programmatically像下面这样征求用户的同意:

val locationRequest = LocationRequest.create()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest.interval = 10000
locationRequest.fastestInterval = 10000 / 2

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

val task = LocationServices.getSettingsClient(this).checkLocationSettings(builder.build())

task.addOnSuccessListener { locationSettingsResponse ->
    // All location settings are satisfied. The client can initialize
    // location requests here.
    // ...
}

task.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, REQUEST_CHECK_SETTINGS)
        } catch (sendEx: IntentSender.SendIntentException) {
            // Ignore the error.
        }
    }
}

关于android - 为什么我的 Android Kotlin 应用程序不请求用户的许可来打开位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60062746/

相关文章:

ios - 提示询问用户是否要继续让您的应用程序收集后台位置 - 这种情况多久发生一次?

java - 为什么 RGBA 位图需要 3x3 数组来存储 1 个像素,如何避免这种情况?

android - 停止 Android Activity ,使用 noHistory ="true"

kotlin - 为什么 Flux.flatMap() 不等待内部发布者完成?

java - 在 VSCode 中使用 Kotlin

linux - Unix - 没有读取访问权限的执行访问示例?

Android:在 ListView 的 onItemClick 事件中使用 AlertDialog

android - 无法删除 cordova 插件

android - 如何将 mysql 数据库导入到 firebase 并在每次将记录实时插入表时将通知推送到用户的手机?

c - 我创建了自己的 Linux shell,但在登录时得到 "mctrl: Permission denied"?