android - Kotlin 在运行时请求位置权限问题
问题描述
import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.*
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
class DeviceScanActivity : AppCompatActivity() {
//Getting BluetoothAdapter from BluetoothManager
private fun PackageManager.missingSystemFeature(name: String): Boolean = !hasSystemFeature(name)
private var fusedLocationProvider: FusedLocationProviderClient? = null
private val locationRequest: LocationRequest = LocationRequest.create().apply {
interval = 30
fastestInterval = 10
priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
maxWaitTime= 60
}
private var locationCallback: LocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val locationList = locationResult.locations
if (locationList.isNotEmpty()) {
val location = locationList.last()
Toast.makeText(this@DeviceScanActivity, "Got Location: " + location.toString(), Toast.LENGTH_LONG).show()
}
}
}
private val bluetoothAdapter: BluetoothAdapter? by lazy(LazyThreadSafetyMode.NONE) {
val bluetoothManager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
bluetoothManager.adapter
}
companion object {
const val TAG: String = "Log"
private const val MY_PERMISSIONS_REQUEST_LOCATION = 99
}
private val BluetoothAdapter.isDisabled: Boolean get() = !isEnabled
private val REQUEST_ENABLE_BT = 1000
//On memory
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "DeviceScanActivity()")
fusedLocationProvider = LocationServices.getFusedLocationProviderClient(this)
checkLocationPermission()
packageManager.takeIf {
it.missingSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
}?.also {
Toast.makeText(this, "R.string.ble_not_supported", Toast.LENGTH_SHORT).show()
finish()
}
bluetoothAdapter?.takeIf { it.isDisabled }?.apply {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
finish()
}
override fun onResume() {
super.onResume()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
fusedLocationProvider?.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
}
}
override fun onPause() {
super.onPause()
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
fusedLocationProvider?.removeLocationUpdates(locationCallback)
}
}
private fun checkLocationPermission() {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
if(ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton(
"OK"
) { _, _ ->
//Prompt the user once explanation has been shown
requestLocationPermission()
}
.create()
.show()
} else {
requestLocationPermission()
}
}
}
private fun requestLocationPermission() {
Log.d(TAG, "requestLocationPermission()")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
),
MY_PERMISSIONS_REQUEST_LOCATION
)
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_PERMISSIONS_REQUEST_LOCATION
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
Log.d(TAG, "result()")
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
MY_PERMISSIONS_REQUEST_LOCATION -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
fusedLocationProvider?.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}
} else {
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
}
return
}
}
}
}
要使用 BLE 观察和广告,我已在 Manifests 授予权限,并尝试在运行时手动请求。
但是,我的代码看起来不像在调用 onRequestPermissionResult,因为它没有在 LogCat 上显示“result()”,并且广告/观察无法正常工作。我的代码有什么问题?
解决方案
推荐阅读
- c++ - 将相同的值分配给 const 变量是否会导致 C++ 中的 UB?
- ssl - Grails SOAP WS 仅在 DEBUG 模式下因握手失败而失败 (intellij)
- libvirt - 如何将驱动程序信息作为 KVM 传递以将 PCI 设备添加到 VM 实例
- ruby-on-rails - 使用资源的自定义 URL
- vba - 向特定记录发出打开表单以进行编辑
- android - 使用毕加索在 ImageView 中加载图像后,TextView(在 RelativeLayout 和 ImageView 中)被隐藏
- javascript - FlatList 列表项背景颜色
- fstar - 不在 Windows 上时如何获得有关 z3 查询的见解
- java - java.lang.NoSuchMethodError: com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.getOutputContext() 升级 Wildfly 后
- javascript - Box Node SDK 不使用 readStream 提取文件