React-Native之Android(6.0及以上)权限申请详解

作者:mochixuan 时间:2023-07-28 01:56:55 

为什么Android要申请权限

简单说下在Android6.0及6.0以上一些google认为涉及“危险和用户隐私”的一些权限不仅要做清单文件(android/app/src/AndroidMainfest.xml)里面申请,还有单独调用api,去让用户选择是否同意你申请这个权限。

例如:你想要你的app有读写手机外置内存卡权限,那么你需要在清单文件里面加下面两行看字母应该懂的吧。但如果你的(android/app/build.gradle)里的 android{defaultConfig {targetSdkVersion 23} } targetSdkVersion >= 23你需要动态去申请权限,我发现react-native init app里面的targetSdkVersion = 22这个,,,巧妙的躲过了,但有些手机系统是6.0或以上的手机targetSdkVersion 22是获取不到有些权限的,至少我知道的乐视就是无法逃脱,其他手机应该也有,而且这是一个android的安全机制,现在开发的app都应该尽量去遵守。

不多解释了想了解可以search一下


<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

效果

React-Native之Android(6.0及以上)权限申请详解 

React-Native之Android(6.0及以上)权限申请详解

React-Native之Android(6.0及以上)权限申请详解 

前提

(android/app/src/AndroidMainfest.xml) targetSdkVersion 改到 23或以上 ,为什么要改????看上面

开始

React-Native里面有PermissionsAndroid去动态申请权限,再说一句,动态申请同意一次就可以下次调用申请它不会再提醒用户选择了,如果拒绝了,可以再次申请,且在申请钱弹一个Dialog这个是手机系统的,我们只能提供一些解释, 下面用三个权限来做解释其实死是个 。

在低于Android 6.0的设备上,权限只要写在AndroidManifest.xml里就会自动获得,此情形下check和request 方法将始终返回true。


async function requestCameraPermission() {
try {
const granted = await PermissionsAndroid.request(
 PermissionsAndroid.PERMISSIONS.CAMERA,
 {
 'title': 'Cool Photo App Camera Permission',
 'message': 'Cool Photo App needs access to your camera ' +
    'so you can take awesome pictures.'
 }
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
 console.log("You can use the camera")
} else {
 console.log("Camera permission denied")
}
} catch (err) {
console.warn(err)
}
}

常用

check(permission)
返回一个promise,最终值为用户是否授权过的布尔值。

request(permission, rationale?)
弹出提示框向用户请求某项权限。返回一个promise,最终值为用户是否同意了权限申请的布尔值。

requestMultiple(permissions)
在一个弹出框中向用户请求多个权限。返回值为一个object,key为各权限名称,对应值为用户授权与否。

第一步

1. 在 android/app/src/AndroidMainfest.xml 添加


<!--获取读写外置存储权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--获取相机权限-->
<uses-permission android:name="android.permission.CAMERA"/>
<!--获取地址相关权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

第二步


//添加 PermissionsAndroid RN自带的
import { PermissionsAndroid } from 'react-native'

第三步


//给你们介绍下怎么用它的方法

//返回 Promise类型 里面是用户是否授权的布尔值
1. PermissionsAndroid.check(permission) //permission是String型

//返回String类型
'granted': 同意了
'denied' : 拒绝了
'never_ask_again' : 永久性拒绝下次再请求用户也看不到了,尴不尴尬
2. PermissionsAndroid.request(permission, rationale?) //permission是String型,rationale对象

//返回一个对象
3. PermissionsAndroid.requestMultiple(permissions) //permissions为String型数组

//就举一个例子 记得加上async异步
async requestReadPermission() {
 try {
  //返回string类型
  const granted = await PermissionsAndroid.request(
   PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
   {
    //第一次请求拒绝后提示用户你为什么要这个权限
    'title': '我要读写权限',
    'message': '没权限我不能工作,同意就好了'
   }
  )
  if (granted === PermissionsAndroid.RESULTS.GRANTED) {
   this.show("你已获取了读写权限")
  } else {
   this.show("获取读写权限失败")
  }
 } catch (err) {
  this.show(err.toString())
 }
}

//核实
checkPermission() {
 try {
  //返回Promise类型
  const granted = PermissionsAndroid.check(
   PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
  )
  granted.then((data)=>{
   this.show("是否获取读写权限"+data)
  }).catch((err)=>{
   this.show(err.toString())
  })
 } catch (err) {
  this.show(err.toString())
 }
}

//请求多个
async requestMultiplePermission() {
 try {
  const permissions = [
   PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
   PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
   PermissionsAndroid.PERMISSIONS.CAMERA
  ]
  //返回得是对象类型
  const granteds = await PermissionsAndroid.requestMultiple(permissions)
  var data = "是否同意地址权限: "
  if (granteds["android.permission.ACCESS_FINE_LOCATION"] === "granted") {
   data = data + "是\n"
  } else {
   data = data + "否\n"
  }
  data = data+"是否同意相机权限: "
  if (granteds["android.permission.CAMERA"] === "granted") {
   data = data + "是\n"
  } else {
   data = data + "否\n"
  }
  data = data+"是否同意存储权限: "
  if (granteds["android.permission.WRITE_EXTERNAL_STORAGE"] === "granted") {
   data = data + "是\n"
  } else {
   data = data + "否\n"
  }
  this.show(data)
 } catch (err) {
  this.show(err.toString())
 }
}

完整代码


import React,{Component} from 'react'
import {
StyleSheet,
View,
Text,
TouchableOpacity,
ToastAndroid,
PermissionsAndroid,
} from 'react-native'

export default class PermissionAndroidView extends Component {

render() {
 return (
  <View style={styles.container}>
   <TouchableOpacity style={styles.button_view}
    onPress={this.requestReadPermission.bind(this)}>
    <Text style={styles.button_text}>申请读写权限</Text>
   </TouchableOpacity>
   <TouchableOpacity style={styles.button_view}
    onPress={this.requestCarmeraPermission.bind(this)}>
    <Text style={styles.button_text}>申请相机权限</Text>
   </TouchableOpacity>
   <TouchableOpacity style={styles.button_view}
    onPress={this.requestLocationPermission.bind(this)}>
    <Text style={styles.button_text}>申请访问地址权限</Text>
   </TouchableOpacity>
   <TouchableOpacity style={styles.button_view}
        onPress={this.checkPermission.bind(this)}>
    <Text style={styles.button_text}>查询是否获取了读写权限</Text>
   </TouchableOpacity>
   <TouchableOpacity style={styles.button_view}
        onPress={this.requestMultiplePermission.bind(this)}>
    <Text style={styles.button_text}>一次申请所以权限</Text>
   </TouchableOpacity>
  </View>
 )
}

show(data) {
 ToastAndroid.show(data,ToastAndroid.SHORT)
}

/*
* 弹出提示框向用户请求某项权限。返回一个promise,最终值为用户是否同意了权限申请的布尔值。
* 其中rationale参数是可选的,其结构为包含title和message)的对象。
* 此方法会和系统协商,是弹出系统内置的权限申请对话框,
* 还是显示rationale中的信息以向用户进行解释。
* */
async requestReadPermission() {
 try {
  //返回string类型
  const granted = await PermissionsAndroid.request(
   PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
   {
    //第一次请求拒绝后提示用户你为什么要这个权限
    'title': '我要读写权限',
    'message': '没权限我不能工作,同意就好了'
   }
  )
  if (granted === PermissionsAndroid.RESULTS.GRANTED) {
   this.show("你已获取了读写权限")
  } else {
   this.show("获取读写权限失败")
  }
 } catch (err) {
  this.show(err.toString())
 }
}

async requestCarmeraPermission() {
 try {
  const granted = await PermissionsAndroid.request(
   PermissionsAndroid.PERMISSIONS.CAMERA,
   {
    //第一次请求拒绝后提示用户你为什么要这个权限
    'title': '我要相机权限',
    'message': '没权限我不能工作,同意就好了'
   }
  )
  if (granted === PermissionsAndroid.RESULTS.GRANTED) {
   this.show("你已获取了相机权限")
  } else {
   this.show("获取相机失败")
  }
 } catch (err) {
  this.show(err.toString())
 }
}

async requestLocationPermission() {
 try {
  const granted = await PermissionsAndroid.request(
   PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
   {
    //第一次请求拒绝后提示用户你为什么要这个权限
    'title': '我要地址查询权限',
    'message': '没权限我不能工作,同意就好了'
   }
  )

if (granted === PermissionsAndroid.RESULTS.GRANTED) {
   this.show("你已获取了地址查询权限")
  } else {
   this.show("获取地址查询失败")
  }
 } catch (err) {
  this.show(err.toString())
 }
}

checkPermission() {
 try {
  //返回Promise类型
  const granted = PermissionsAndroid.check(
   PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
  )
  granted.then((data)=>{
   this.show("是否获取读写权限"+data)
  }).catch((err)=>{
   this.show(err.toString())
  })
 } catch (err) {
  this.show(err.toString())
 }
}

async requestMultiplePermission() {
 try {
  const permissions = [
   PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
   PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
   PermissionsAndroid.PERMISSIONS.CAMERA
  ]
  //返回得是对象类型
  const granteds = await PermissionsAndroid.requestMultiple(permissions)
  var data = "是否同意地址权限: "
  if (granteds["android.permission.ACCESS_FINE_LOCATION"] === "granted") {
   data = data + "是\n"
  } else {
   data = data + "否\n"
  }
  data = data+"是否同意相机权限: "
  if (granteds["android.permission.CAMERA"] === "granted") {
   data = data + "是\n"
  } else {
   data = data + "否\n"
  }
  data = data+"是否同意存储权限: "
  if (granteds["android.permission.WRITE_EXTERNAL_STORAGE"] === "granted") {
   data = data + "是\n"
  } else {
   data = data + "否\n"
  }
  this.show(data)
 } catch (err) {
  this.show(err.toString())
 }
}

}

const styles = StyleSheet.create({
container: {
 flex: 1,
 padding: 10,
},
button_view: {
 margin:4,
 borderRadius: 4,
 backgroundColor: '#8d4dfc',
 alignItems: 'center',
},
button_text: {
 padding: 6,
 fontSize: 16,
 fontWeight: '600'
}
})

// 12点了再不睡,我就要猝死了,其实运行一下就知道什么意思了

来源:https://juejin.im/post/5a0c51d3f265da431e164df9

标签:React,Native,Android
0
投稿

猜你喜欢

  • Android学习之AppWidget笔记分享

    2022-04-10 21:25:46
  • spring retry实现方法请求重试的使用步骤

    2021-12-31 15:11:11
  • java的接口解耦方式

    2023-04-17 00:36:45
  • C#中TreeView节点的自定义绘制方法

    2023-04-01 10:37:19
  • 带你入门Java的泛型

    2023-06-08 02:48:24
  • 理解C#中的枚举(简明易懂)

    2023-01-23 01:34:47
  • SpringBoot参数校验的最佳实战教程

    2023-11-28 21:13:47
  • Android Bitmap像素级操作详解

    2022-01-28 15:01:51
  • 一行java代码实现高斯模糊效果

    2023-02-07 17:31:34
  • Spring boot项目使用thymeleaf模板过程详解

    2022-10-20 22:30:58
  • SpringBoot整合Kafka工具类的详细代码

    2022-07-03 14:12:13
  • mybatisPlus返回Map类型的集合

    2022-01-31 13:37:07
  • java web实现分页查询实例方法

    2022-12-18 18:07:57
  • Android BroadcastReceiver广播机制概述

    2022-12-08 12:21:05
  • JPA Specification常用查询+排序实例

    2023-11-23 04:56:32
  • Java与Kotlin互调原理讲解

    2023-08-19 00:07:41
  • Java中synchronized锁的深入理解

    2023-08-18 01:36:55
  • 基于C#实现FTP下载文件

    2021-07-09 20:10:01
  • c# HttpClient设置超时的步骤

    2023-05-07 10:42:29
  • Flutter WebView 预加载实现方法(Http Server)

    2023-06-25 23:14:35
  • asp之家 软件编程 m.aspxhome.com