Android 批量申请权限(连续申请)

        封装了一个关于权限相关和开关的申请Demo,先贴出来视频效果,最开始的时候GPS开关没打开,没有位置权限,没开启蓝牙功能,点击按钮之后先后打开GPS开关,动态申请位置权限,打开GPS开关和蓝牙功能。

                                                          

       

      贴出核心代码:

      1.  首先先封装了一个动态权限请求的工具类,蓝牙功能的申请也写在其中:

class PermissionsUtils {
    companion object {
        fun checkGPS(context: Context): Boolean {
            val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
            return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
        }

        @RequiresApi(Build.VERSION_CODES.M)
        fun checkLocationPermission(activity: Activity): Boolean {
            return ContextCompat.checkSelfPermission(
                activity,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        }

        @RequiresApi(Build.VERSION_CODES.M)
        fun requestLocationPermissions(activity: Activity) {
            if (!checkLocationPermission(activity)) {
                activity.requestPermissions(
                    arrayOf(
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                    ), POSITION_PERMISSION_REQUEST_CODE
                )
            }
        }

        fun toggleLocationSetting(activity: Activity) {
            val intent = Intent()
            try {
                val packageURI = Uri.parse("package:" + activity.packageName)
                activity.startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI))
            } catch (e: Exception) {
                e.printStackTrace()
                intent.action = Settings.ACTION_APPLICATION_SETTINGS
                intent.putExtra("package", activity.packageName)
                activity.startActivity(intent)
            }
        }

        /**
         * 检查蓝牙状态
         */
        fun checkBluetooth(): Boolean {
            val adapter = BluetoothAdapter.getDefaultAdapter()
            return adapter.isEnabled
        }

        /**
         * 调用系统API去打开蓝牙
         */
        fun requestBluetooth(activity: Activity) {
            //会以Dialog的样式来显示系统级别的请求开启蓝牙Activity , 我们可以在onActivityResult()方法去处理返回值
            val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            activity.startActivityForResult(enableBtIntent, BLUETOOTH_REQUEST_CODE)
        }
    }
}

 2.   用一个map记录对哪些权限/开关发起过申请:

 //用来记录对哪些权限/开关发起过申请
    private var requestMaps: MutableMap = mutableMapOf()

3.   动态权限申请都是以弹窗的形式让用户选择允许还是拒绝,不管用户是选择哪一项, 在点击完成(如果同时申请多个权限,则需要所有权限全部点击完)后,必会触发onRequestPermissionsResult这个回调方法。在权限响应回调的地方 onRequestPermissionsResult、以及响应startActivityForResult打开系统级别对话框的回调onActivityResult中对map进行处理:

    /**
     *
     * 动态权限申请都是以弹窗的形式让用户选择允许还是拒绝;不管用户是选择哪一项,
     * 在点击完成(如果同时申请多个权限,则需要所有权限全部点击完)后,必会触发onRequestPermissionsResult这个回调方法
     *
     * **/
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
        when (requestCode) {
            AppConstants.POSITION_PERMISSION_REQUEST_CODE -> {
                isPermissionChecking = false
                requestMaps[AppConstants.TAG_LOCATION] = true
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(
                            this,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        )
                    ) {
                        isPermissionChecking = true
                        requestMaps[AppConstants.TAG_LOCATION] = true
                    } else {
                        checkHardWareState()
                    }
                } else {
                    checkHardWareState()
                }
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            AppConstants.GPS_REQUEST_CODE -> {
                //gps set dialog dismiss callback
                resetScreenState()
                requestMaps[AppConstants.TAG_GPS] = true
                checkHardWareState()
            }

            AppConstants.BLUETOOTH_REQUEST_CODE -> {
                requestMaps[AppConstants.TAG_BLUETOOTH] = true
                resetScreenState()
            }
        }
    }

       Demo地址:https://download.csdn.net/download/crystal_xing/11958667,做这个功能需求的时候发现,GoogleApiClient的写法已经被Google弃用,故用新写法也写了一份批量申请权限的Demo,一并打包。GPS开关的打开是因为使用了gms:play-services-location,Google定位。不用这个的话做不到用代码强行打开手机上的GPS开关。

官网文档:https://developer.android.google.cn/training/location/change-location-settings (中文镜像)

                  https://developer.android.com/training/location

 

你可能感兴趣的:(android,kotlin)