本篇文章同步发表在 HKT 线上教室 部落格,线上影音教学课程已上架至 Udemy 和 Youtube 频道。另外,想追踪更多相关技术资讯,欢迎到 脸书粉丝专页 按赞追踪喔~
范例名称:获取位置权限
开发人员:HKT (侯光灿)
程序语言:Kotlin
开发环境:Android Studio 4.1.2 & Android 11 & Kotlin 1.4.30
授权范围:使用时必须注明出处且不得为商业目的之使用
范例下载点:点我下载
在之前的介绍当中,我们主要的重心是放在,如何在滚动式列表上呈现药局资讯。而在接下来的重心,我们将会放在,如何在 Google Map 地图上,呈现药局地点与药局相关资讯。将会依序的跟大家介绍:
所以今天要先来跟大家介绍第一个部分,如何获取使用者位置权限,除了要在 AndroidManifest.xml 宣告外,因为「位置权限」被列属为危险权限,从 Android 6 (SDK 23)以上,需要特别额外跟使用询问获取,否则会因权限不足,而造成 APP 闪退。详细权限级别,可以查阅官网文件: Manifest.permission。
获取 APP 权限,主要分成这四个部分。
检查我们的APP,是否获得权限
是否要显示更多说明解释为何此权限对话视窗。收到 true,代表需要跟使用者显示更多说明解释为何此权限对话视窗,收到 false,代表不需额外显示给使用者说明。
要求用户给我们APP使用权限
覆写此方法,要求权限後,会收到用户决定是否给权限的结果 CallBack
获取位置权限,需要先在 AndroidManifest.xml 里,加入此宣告。位置权限有两种,一个是概略位置存取权(ACCESS_COARSE_LOCATION)和另一个精确位置存取(ACCESS_FINE_LOCATION),择一即可,我们选择精确定位权限。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
我们先新开一个空白的 Activity 页面,档名为 MapActivity,并在 AndroidManifest.xml 里将启动载入Activity,更改为此 Activity。
<activity android:name=".MapActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
透过 checkSelfPermission 方法,检查有无精准位置(ACCESS_FINE_LOCATION)权限,若没有则询问使用者要求获取权限,若获得 locationPermissionGranted 设定为 true。
private var locationPermissionGranted = false
...
...
...
private fun getLocationPermission() {
//检查权限
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
//已获取到权限
Toast.makeText(this, "已获取到位置权限,可以准备开始获取经纬度", Toast.LENGTH_SHORT).show()
locationPermissionGranted = true
//todo checkGPSState()
} else {
//询问要求获取权限
requestLocationPermission()
}
}
private fun requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.ACCESS_FINE_LOCATION
)
) {
AlertDialog.Builder(this)
.setMessage("此应用程序,需要位置权限才能正常使用")
.setPositiveButton("确定") { _, _ ->
ActivityCompat.requestPermissions(
this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION_PERMISSION
)
}
.setNegativeButton("取消") { _, _ -> requestLocationPermission() }
.show()
} else {
ActivityCompat.requestPermissions(
this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<out String>, grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_LOCATION_PERMISSION -> {
if (grantResults.isNotEmpty()) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//已获取到权限
locationPermissionGranted = true
//todo checkGPSState()
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
//权限被永久拒绝
Toast.makeText(this, "位置权限已被关闭,功能将会无法正常使用", Toast.LENGTH_SHORT).show()
AlertDialog.Builder(this)
.setTitle("开启位置权限")
.setMessage("此应用程序,位置权限已被关闭,需开启才能正常使用")
.setPositiveButton("确定") { _, _ ->
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivityForResult(intent, REQUEST_LOCATION_PERMISSION)
}
.setNegativeButton("取消") { _, _ -> requestLocationPermission() }
.show()
} else {
//权限被拒绝
Toast.makeText(this, "位置权限被拒绝,功能将会无法正常使用", Toast.LENGTH_SHORT).show()
requestLocationPermission()
}
}
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_LOCATION_PERMISSION -> {
getLocationPermission()
}
}
}
第一次呈现询问画面
若在第一次询问,选择「拒绝」,则会出现,我们自定义的对话视窗,可以在这个视窗跟用户说明为何需要权限。
若是选择「拒绝且不在询问」,将不会在出现询问视窗
HKT 线上教室
https://tw-hkt.blogspot.com/
Freepik
https://www.freepik.com/
Build location-aware apps
https://developer.android.com/training/location
Request App Permissions
https://developer.android.com/training/permissions/requesting
permissions API reference page
https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION
Location Data
https://developers.google.com/maps/documentation/android-sdk/location
Select Current Place and Show Details on a Map
https://developers.google.com/maps/documentation/android-sdk/current-place-tutorial
那今天【iThome 铁人赛】就介绍到这边罗~
顺带一提,KT 线上教室,脸书粉丝团,会不定期发布相关资讯,不想错过最新资讯,不要忘记来按赞,追踪喔!也欢迎大家将这篇文章分享给更多人喔。
我们明天再见罗!!!掰掰~
<<: 每个人都该学的30个Python技巧|技巧 23:方便的运算函式—pow()、divmod()、round()(字幕、衬乐、练习)
>>: Logger 与 Extension Generator for Kotlin
还记得我们在之前做过变化模式吗? 没错,就是滑鼠悬停之後会变色的那个。 我们今天呢,就是要来帮它们...
容器化是应用程序级别的虚拟化, 允许单个内核上有多个独立的用户空间实体, 而这些实体称为容器。 20...
在好几年前串接金流的时候,还有没定期定额的选项, 记得那时接触的是团体的捐款网站要串接定期定额的功能...
终於来到我们最後一个主题了,今天我们要介绍的是图形使用者介面(graphical user inte...
鬼牌,在此借用的意思是「可以成为任何一张牌」 Dynamic Components 可以当鬼牌 Dy...