Flutter Android权限问题
如何在Flutter管理好Android的權(quán)限
前言
從Android 6.0開始,權(quán)限不再是只是寫在AndroidManifest.xml中申請,部分權(quán)限需要通過運(yùn)行時(shí)申請,這可能相對于前端開發(fā)者來說,比較陌生,所以要尤其注意這個(gè)問題。所幸Flutter有相關(guān)的插件供我們使用,本次筆者將通過公司的真實(shí)項(xiàng)目來實(shí)現(xiàn)Flutter在Android中的權(quán)限適配問題。
效果預(yù)覽
AndroidManifest的權(quán)限申請
permission的安裝時(shí)的動態(tài)權(quán)限申請
permission_handler的動態(tài)權(quán)限申請
環(huán)境
開發(fā)環(huán)境
| Android SDK | minSdkVersion:21 compileSdkVersion:29 |
| Gradle | 6.5 |
| 測試機(jī)型 | 華為榮耀 Play4T 系統(tǒng)Android 10 |
插件
在pubspec.yaml文件中添加如下插件,作用分別為 運(yùn)行時(shí)權(quán)限插件,安裝時(shí)權(quán)限插件,加載進(jìn)度條toast的UI插件
permission_handler: 5.1.0+2
permission: 0.1.7
oktoast: 2.3.2
代碼實(shí)現(xiàn)
Android配置
在android文件夾的AndroidManifest.xml文件中加入相對應(yīng)的配置,以下只是示例,具體情況具體分析
<!--允許程序打開網(wǎng)絡(luò)套接字--><uses-permission android:name="android.permission.INTERNET" /><!--允許程序設(shè)置內(nèi)置sd卡的讀寫權(quán)限--><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!--允許程序獲取網(wǎng)絡(luò)狀態(tài)--><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!--允許程序訪問CellID或WiFi熱點(diǎn)來獲取粗略的位置--><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!--允許程序打開相機(jī)--><uses-permission android:name="android.permission.CAMERA" />注意事項(xiàng):最好要在main debug profile三個(gè)文件里面的AndroidManifest.xml都要加上
代碼封裝
在main函數(shù)入口,先申請一些權(quán)限。
注意一個(gè)問題,就是一定要在runApp()方法調(diào)用之前使用,因?yàn)檫@是在安裝APP時(shí),先申請一些運(yùn)行時(shí)權(quán)限
至于OkToast的配置請參考 pub.dev
這里面使用到的是permission插件,這個(gè)插件最多只能同時(shí)申請到3個(gè)(一般要先把重要的權(quán)限在這里先申請到),而且有一個(gè)很致命的問題:那就是在PermissionName枚舉中定義了很多關(guān)于權(quán)限的枚舉變量。如果Android系統(tǒng)的版本比較低,有些權(quán)限并沒有在這個(gè)版本的系統(tǒng)需要申請,會出現(xiàn)閃退拋異常的現(xiàn)象。筆者就接到用戶投訴在Android 6.0的中興手機(jī)上出現(xiàn)閃退的情況,但是筆者公司并沒有Android 7.0以下的測試機(jī)型,所以這種問題非常難以在自測階段捕捉原因,所以這點(diǎn)尤其注意。大體上來說,試過的地理位置、相機(jī)、還有存儲權(quán)限這個(gè)是沒什么問題,且在App中非常重要的,于是優(yōu)先在安裝階段就要盡可能獲取到授權(quán)。
首先封裝一個(gè)消息提示組件 base_tip.dart,這個(gè)組件的效果類似Android 原生的Toast
封裝權(quán)限工具類 permission_helper.dart 這個(gè)組件用來檢查權(quán)限與申請權(quán)限、申請權(quán)限成功跟失敗的接口回調(diào),及結(jié)果返回等。
import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:water_app/widget/base/base_tip.dart';class PermissionHelper {static VoidCallback defErr = () {};static VoidCallback defSuc = () {};static Future<bool> check(PermissionType type, {VoidCallback onSuc, VoidCallback onErr, String errMsg}) async {bool flag = false;Permission permission = convertType(type);PermissionStatus status = await permission.status;if (status.isGranted) {onSuc != null ? onSuc() : defSuc();flag = true;}else if (status.isUndetermined) {PermissionStatus p = await permission.request();if (p.isGranted) {onSuc != null ? onSuc() : defSuc();flag = true;}else {showErr(onErr: onErr, errMsg: errMsg);}}else if (status.isDenied || status.isPermanentlyDenied) {PermissionStatus p = await permission.request();if (p.isGranted) {onSuc != null ? onSuc() : defSuc();flag = true;}else {showErr(onErr: onErr, errMsg: errMsg);}}else {showErr(onErr: onErr, errMsg: errMsg);}return flag;}static void showErr({VoidCallback onErr, String errMsg}) {showToastCommon(errMsg ?? '請授予該權(quán)限,否則將影響一些功能的使用');onErr ?? defErr();}static Permission convertType(PermissionType type) {Permission p;switch (type) {case PermissionType.calendar:p = Permission.calendar;break;case PermissionType.camera:p = Permission.camera;break;case PermissionType.contacts:p = Permission.contacts;break;case PermissionType.location:p = Permission.location;break;case PermissionType.locationAlways:p = Permission.locationAlways;break;case PermissionType.locationWhenInUse:p = Permission.locationWhenInUse;break;case PermissionType.mediaLibrary:p = Permission.mediaLibrary;break;case PermissionType.microphone:p = Permission.microphone;break;case PermissionType.phone:p = Permission.phone;break;case PermissionType.photos:p = Permission.photos;break;case PermissionType.photosAddOnly:p = Permission.photosAddOnly;break;case PermissionType.reminders:p = Permission.reminders;break;case PermissionType.sensors:p = Permission.sensors;break;case PermissionType.sms:p = Permission.sms;break;case PermissionType.speech:p = Permission.speech;break;case PermissionType.storage:p = Permission.storage;break;case PermissionType.ignoreBatteryOptimizations:p = Permission.ignoreBatteryOptimizations;break;case PermissionType.notification:p = Permission.notification;break;case PermissionType.accessMediaLocation:p = Permission.accessMediaLocation;break;case PermissionType.activityRecognition:p = Permission.activityRecognition;break;default:p = Permission.unknown;}return p;} }enum PermissionType {calendar,camera,contacts,location,locationAlways,locationWhenInUse,mediaLibrary,microphone,phone,photos,photosAddOnly,reminders,sensors,sms,speech,storage,ignoreBatteryOptimizations,notification,accessMediaLocation,activityRecognition,unknown }工具類使用
申請運(yùn)行時(shí)相冊權(quán)限
bool allow = await PermissionHelper.check(PermissionType.storage,errMsg: '請授予相冊權(quán)限',onErr: () {debugPrint('錯誤回調(diào)');},onSuc: () {debugPrint('成功回調(diào)');} );申請相機(jī)的權(quán)限
bool allow = await PermissionHelper.check(PermissionType.camera,errMsg: '請授予相機(jī)權(quán)限',onErr: () {debugPrint('錯誤回調(diào)');},onSuc: () {debugPrint('成功回調(diào)');});總結(jié)
日常的程序設(shè)計(jì)要盡可能考慮到各種情況,用戶是(不講武德 )最好的測試,經(jīng)常不按常理出牌,應(yīng)該要預(yù)判到用戶的各種操作(騷操作 ),從而讓應(yīng)用變得更加健壯
最近筆者在公司使用Flutter技術(shù)獨(dú)自開發(fā)一款企業(yè)級的物聯(lián)網(wǎng)應(yīng)用,如果對筆者感興趣,歡迎關(guān)注筆者。讀者有好的建議,也歡迎在下面留言。碼字不易,請給👍
總結(jié)
以上是生活随笔為你收集整理的Flutter Android权限问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: midaspay能删除吗_midaspa
- 下一篇: 百度杀毒软件2013低调发布