android - 为什么我的 Android Kotlin 应用没有请求用户允许打开位置信息?
问题描述
我的应用程序没有请求用户允许打开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" />
除此之外,请按照官方文档以这种方式请求许可:
// 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
}
更新:要以编程方式打开位置请求用户的批准,如下所示:
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.
}
}
}
推荐阅读
- powershell - 如何通过网络等待权限被拒绝类型错误
- html - 在浏览器中显示不同大小的css网格
- node.js - TypeError:无法读取未定义 goormIDE 的属性“推送”
- ios - Swift:textField 侦听器不响应文本更改
- python - Linux 中的 Pandas 失败,Windows 中未发生 - 缺少 _data 属性
- javascript - 将值返回到另一个嵌套函数中的函数
- angular - 在 apache 托管服务器上运行 angular9 应用程序
- google-apps-script - 如何使用谷歌应用脚本从另一张表中选择数值?
- mysql - MYSQL 使用触发器使用更新行中的值更新另一行
- python - 最大的小日期