React-Native之Android(6.0及以上)許可權申請

mochixuan發表於2017-11-16

main0.jpg
main0.jpg

為什麼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"/>複製程式碼

效果

main.jpg
main.jpg

main1.jpg
main1.jpg

main2.jpg
main2.jpg

前提

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

開始

  • React-Native裡面有PermissionsAndroid去動態申請許可權,再說一句,動態申請同意一次就可以下次呼叫申請它不會再提醒使用者選擇了,如果拒絕了,可以再次申請,且在申請錢彈一個Dialog這個是手機系統的,我們只能提供一些解釋,下面用三個許可權來做解釋其實死是個

  • 第一步
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點了再不睡,我就要猝死了,其實執行一下就知道什麼意思了複製程式碼

沒時間解釋了,直接可以執行看效果解釋的也很清楚

React Native專案

相關文章