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

为什么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"/>

效果

前提

(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点了再不睡,我就要猝死了,其实运行一下就知道什么意思了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android Rreact Native 常见错误总结

    Android Rreact Native 常见错误总结 1.invariant violation:expected a component class,got[object object] 创建自定义组件首字母要大写,否则会报错. 2.Module 0 is not a registered callable module. 将gradle升级成最新版本(cd Android 进入android目录执行:sudo ./gradlew clean) 或者通过android studio工具升级

  • React Native中Android物理back键按两次返回键即退出应用

    前言 本文主要给大家介绍了关于React Native中Android物理back键按两次返回键就会退出应用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 话不多说,直接上图: 测试代码 第16~22行 设置事件监听以及移除事件监听. componentWillMount(){ BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid); } componentWillUnmount()

  • React-Native实现ListView组件之上拉刷新实例(iOS和Android通用)

    在web应用中,上拉刷新加载更多,下拉刷新列表的操作非常常见,那么在React-Native中是如何实现呢,我们具体来看一下 ReactNative提供了RefreshControl下拉刷新组件,但是没有提供上拉刷新组件,上拉刷新在App中是很常用的. 今天我们来实现一个iOS和Android通用的上拉刷新功能. 下面简要介绍下我实现的思路. 思路: 1.常量定义: const moreText = "加载完毕"; //foot显示的文案 //页码 var pageNum = 1; /

  • react-native 封装选择弹出框示例(试用ios&android)

    在开发 App 的时候,经常会使用到对话框(又叫消息框.提示框.告警框). 在web开发中经常会用得到.今天就来介绍了一下react-native 封装弹出框 之前看到react-native-image-picker中自带了一个选择器,可以选择拍照还是图库,但我们的项目中有多处用到这个选择弹出框,所以就自己写了一下,最最重要的是ios和Android通用.先上动态效果图~ 一.封装要点 1.使用动画实现弹框布局及显示隐藏效果 2.通过一个boolean值控制组件的显示隐藏 3.弹框选项数组通过

  • 详解React Native监听Android回退按键与程序化退出应用

    详解React Native监听Android回退按键与程序化退出应用 前言 我们知道Android回退按键,会控制页面返回, 并且退出应用并非真正意义退出,仍在后台运行,所以在某些场景下需要监控android回退按键,那么在React Native中应该如何应用呢?我们具体来看看. BackAndroid 此模块用于监听硬件的back键操作. 看下具体代码: BackAndroid.addEventListener('hardwareBackPress', function() { if (!

  • React-Native Android 与 IOS App使用一份代码实现方法

    React-Native  Android 与 IOS 共用代码 React-Native 开发的App, 所有组件iOS & Android 共用, 共享一份代码 包括一些自定义的组件, 如NavigationBar, TabBar, SegmentedControl, 使用字体图标, 具有一定的参考意义 主要专注于布局, 共享组件/代码, 以及一些React自带的组件, 如: ScrollView, TouchableOpacity, View, Text, ListView, Image,

  • Android React Native原生模块与JS模块通信的方法总结

    Android React Native原生模块与JS模块通信的方法总结 前言: 在做React Native开发的时候避免不了的需要原生模块和JS之间进行数据传递,这篇文章将向大家分享原生模块向JS传递数据的几种方式. 方式一:通过Callbacks的方式 说起Callbacks大家都不陌生,它是最常用的设计模式之一.无论是Java,Object-c,C#,还是JavaScript等都会看到Callbacks的身影. 原生模块支持Callbacks类型的参数,该Callbacks对应JS中的f

  • Android原生项目集成React Native的方法

    开发环境准备 首先按照开发环境搭建教程来安装React Native在安卓平台上所需的一切依赖软件(比如npm). 在应用中添加JS代码 在项目的根目录中运行: $ npm init $ npm install --save react react-native $ curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig npm init创建了一个空的node模块

  • React Native学习之Android的返回键BackAndroid详解

    前言 最近在学习使用 React Native开发,iOS搞完,开始适配安卓,由于木有接触过安卓,所以碰到了很多问题,第一个问题,安卓的返回键BackAndroid问题, 我写了一个工具类,来搞定,其中用到了java原生代码与js交互;好吧,下面开始正式内容: 上代码: // BackAndroidTool // 功能: "安卓手机上的返回键" // Created by 小广 on 2016-05-10 下午. // Copyright © 2016年 All rights rese

  • React Native第三方平台分享的实例(Android,IOS双平台)

    本文主要介绍了React Native第三方平台分享的实例(Android,IOS双平台),分享给大家,具体如下: 源码已开源到Github,地址请点击:react-native-share[一行代码,双平台分享] 目前支持分享的平台有[QQ][QQ空间][微信][朋友圈][微博][FaceBook]  欢迎大家star,fork..... [ Android平台配置 ] 1. app目录下创建 libs 文件夹,添加依赖文件[直接复制源码中 libs 目录即可] 2. app / src /

随机推荐