Android 10 定位权限问题

年后项目升级到了安卓10 (Api29), 这几天在写定位遇到了的定位权限以及回调问题,记录下

随着Android 对用户隐私和安全问题逐渐重视, 版本适配问题越来越多,对于开发者来说也是一件很头痛的事

Android Q (29) 新增后台定位权限: ACCESS_BACKGROUND_LOCATION ,

如果项目编译版本>=29 且想要使用前台定位则需要在AndroidManifest.xml 添加下面这句权限

    <!--定位权限 安卓9.0及以下用下-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!--定位权限,Android Q 新增后台定位权限-->
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

申请权限需要判断编译版本了

        //Android10以下申请定位权限
        String[] permissionsO = new String[]{
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION};

        //Android 10及以上申请定位权限
        String[] permissionsQ = new String[]{
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_BACKGROUND_LOCATION};

        String[] permissions = permissionsO;

        // 判断编译版本,如果大于等于29,就用permissionsQ
        if (Build.VERSION.SDK_INT >= 29) {
            permissions = permissionsQ;
        }

       

 

本以为这就完事了, 结果自测的时候在Android10上发现一个问题: 在申请权限的时候如果点击了 仅使用期间允许 的话会执行拒绝的回调, 正常的情况下, 我们一般会有这几种回调(允许, 拒绝,拒绝后不在询问)

//这是我基于RXpermission 自行封装的
PermissionUtil.requestLocation(new PermissionUtil.RequestPermission() {
            @Override
            public void onRequestPermissionSuccess() {
                //全部授权,开始定位
            }

            @Override
            public void onRequestPermissionFailure(List<String> permissions) {
                //拒绝,给个提示
               
            }

            @Override
            public void onRequestPermissionFailureWithAskNeverAgain(List<String> permissions) {
                //拒绝后不在询问,给个弹窗,是否去设置界面
            }
        }, new RxPermissions(this));

经过Debug 发现, 在Android10手机上如果点击仅使用期间执行的话,android.permission.ACCESS_BACKGROUND_LOCATION 这个权限返回的值是 -1 , 说明这个权限是没有申请成功的

 

所以,我的思路就是在onRequestPermissionFailure 这回调判断下,未授权的权限集合长度等于1,并且这个权限还是 "android.permission.ACCESS_BACKGROUND_LOCATION" , 说明另外两个定位已经授权了,

//基于RXpermission 自行封装的
PermissionUtil.requestLocation(new PermissionUtil.RequestPermission() {
            @Override
            public void onRequestPermissionSuccess() {
                //全部授权,开始定位
            }

            @Override
            public void onRequestPermissionFailure(List<String> permissions) {
           
               if (null != permissions && permissions.size()==1 && permissions.contains("android.permission.ACCESS_BACKGROUND_LOCATION")){
                   //仅在运行期间允许,这个也是可以去定位的,就是无法使用后台定位,如果要使用后台定位,可以在这里做个提示
                }else {
                    //拒绝授权,给个提示
                } 
               
            }

            @Override
            public void onRequestPermissionFailureWithAskNeverAgain(List<String> permissions) {

if (null != permissions && permissions.size()==1 && permissions.contains("android.permission.ACCESS_BACKGROUND_LOCATION")){
                   //仅在运行期间允许且不再询问
                }else {
                    //拒绝后不在询问,给个弹窗,是否去设置界面
                } 
                
            }
        }, new RxPermissions(this));

以上就是我遇到的问题和思路, 如果有更好的想法和意见,可以一起讨论哦

 

 

 

 

 

 

 

### 定位权限声明 在 Android 中,要使用定位功能,需要在 `AndroidManifest.xml` 文件中声明定位权限定位权限主要分为精准定位和粗略定位,精准定位一般通过卫星定位,粗略定位一般通过基站定位或 WiFi 定位,这两个权限都需要声明且需要动态申请。示例代码如下: ```xml <!-- 精准定位,一般通过卫星定位,需要动态申请权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <!-- 粗略定位,一般通过基站定位或WiFi定位,需要动态申请权限 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> ``` ### 运行时权限申请 从 Android 6.0(API 级别 23)开始,引入了运行时权限动态检测机制,定位权限属于危险权限,需要在运行时进行申请。以下是一个简单的代码示例,用于检查并申请定位权限: ```java import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; public class MainActivity extends AppCompatActivity { private static final int LOCATION_PERMISSION_REQUEST_CODE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 检查是否已经有定位权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // 如果没有权限,则申请权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); } else { // 已经有权限,可以开始定位操作 startLocation(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && (grantResults[0] == PackageManager.PERMISSION_GRANTED || grantResults[1] == PackageManager.PERMISSION_GRANTED)) { // 用户授予了定位权限,可以开始定位操作 startLocation(); } else { // 用户拒绝了定位权限,可以给出提示或进行其他处理 } } } private void startLocation() { // 这里可以实现具体的定位逻辑 } } ``` ### 权限检查 在使用定位功能之前,需要检查是否已经获得了定位权限。可以使用 `ContextCompat.checkSelfPermission` 方法进行检查: ```java if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // 已经有权限,可以开始定位操作 startLocation(); } else { // 没有权限,需要申请权限 } ``` ### 权限管理 当用户选择“不再询问”选项时,应引导用户手动授予权限,以确保应用程序可以正常使用相关功能。可以通过 `shouldShowRequestPermissionRationale` 方法判断是否需要向用户解释为什么需要该权限。示例代码如下: ```java if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) { // 向用户解释为什么需要定位权限 } else { // 用户选择了“不再询问”,引导用户手动授予权限 } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值