338 lines
11 KiB
Dart
338 lines
11 KiB
Dart
// ignore_for_file: unused_import
|
|
|
|
import 'dart:io';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:tencent_im_base/tencent_im_base.dart';
|
|
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
|
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
|
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
|
|
|
class PermissionRequestInfo extends StatefulWidget {
|
|
final Function removeOverLay;
|
|
final int permissionType;
|
|
final String appName;
|
|
|
|
const PermissionRequestInfo(
|
|
{Key? key,
|
|
required this.removeOverLay,
|
|
required this.permissionType,
|
|
required this.appName})
|
|
: super(key: key);
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => _PermissionRequestInfo();
|
|
}
|
|
|
|
class _PermissionRequestInfo extends TIMUIKitState<PermissionRequestInfo>
|
|
with WidgetsBindingObserver {
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance?.addObserver(this);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
widget.removeOverLay();
|
|
super.dispose();
|
|
WidgetsBinding.instance?.removeObserver(this);
|
|
}
|
|
|
|
@override
|
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
|
super.didChangeAppLifecycleState(state);
|
|
if (state == AppLifecycleState.resumed) {
|
|
widget.removeOverLay();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
|
final theme = value.theme;
|
|
|
|
final permission = {
|
|
1: {
|
|
"name": TIM_t("相机"),
|
|
"icon": "images/chat_permission_icon_camera.png",
|
|
"text": TIM_t("为方便您将所拍摄的照片或视频发送给朋友,以及进行视频通话,请允许我们访问摄像头进行拍摄照片和视频。")
|
|
},
|
|
7: {
|
|
"name": TIM_t("麦克风"),
|
|
"icon": "images/chat_permission_icon_mic.png",
|
|
"text": TIM_t("为方便您发送语音消息、拍摄视频以及音视频通话,请允许我们使用麦克风进行录音。")
|
|
},
|
|
15: {
|
|
"name": TIM_t("存储"),
|
|
"icon": "images/chat_permission_icon_file.png",
|
|
"text": TIM_t("为方便您查看和选择相册里的图片视频发送给朋友,以及保存内容到设备,请允许我们访问您设备上的照片、媒体内容。")
|
|
},
|
|
}[widget.permissionType];
|
|
final option2 = permission?["name"] ?? "";
|
|
return Stack(
|
|
children: [
|
|
Positioned(
|
|
child: SafeArea(
|
|
child: Opacity(
|
|
opacity: 0.7,
|
|
child: Container(
|
|
color: theme.black,
|
|
padding: const EdgeInsets.symmetric(horizontal: 40),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
const SizedBox(
|
|
height: 50,
|
|
),
|
|
SizedBox(
|
|
height: 50,
|
|
width: 50,
|
|
child: Image.asset(
|
|
permission?["icon"] ?? "",
|
|
package: "tencent_cloud_chat_uikit",
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 10,
|
|
),
|
|
Text(
|
|
TIM_t(widget.appName) +
|
|
TIM_t_para(" 申请获取{{option2}}", " 申请获取$option2")(
|
|
option2: option2) +
|
|
TIM_t("权限"),
|
|
style: TextStyle(color: theme.white, fontSize: 18),
|
|
),
|
|
const SizedBox(
|
|
height: 20,
|
|
),
|
|
Text(
|
|
permission?["text"] ?? "",
|
|
style: TextStyle(color: theme.white, fontSize: 16),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
top: 0,
|
|
)
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class Permissions {
|
|
static List<String> _names(BuildContext context) {
|
|
return <String>[
|
|
TIM_t("日历"),
|
|
TIM_t("相机"),
|
|
TIM_t("联系人"),
|
|
TIM_t("位置"),
|
|
'locationAlways',
|
|
'locationWhenInUse',
|
|
'mediaLibrary',
|
|
TIM_t("麦克风"),
|
|
'phone',
|
|
TIM_t("照片"),
|
|
TIM_t("相册写入"),
|
|
'reminders',
|
|
'sensors',
|
|
'sms',
|
|
'speech',
|
|
TIM_t("文件"),
|
|
'ignoreBatteryOptimizations',
|
|
'notification',
|
|
'access_media_location',
|
|
'activity_recognition',
|
|
'unknown',
|
|
'bluetooth',
|
|
'manageExternalStorage',
|
|
'systemAlertWindow',
|
|
'requestInstallPackages',
|
|
'appTrackingTransparency',
|
|
'criticalAlerts',
|
|
'accessNotificationPolicy',
|
|
'bluetoothScan',
|
|
'bluetoothAdvertise',
|
|
'bluetoothConnect',
|
|
];
|
|
}
|
|
|
|
static String _permissionText(
|
|
BuildContext context, String appName, int value) {
|
|
final _prefix = TIM_t("需要授予");
|
|
final _postfixList = <String>[
|
|
TIM_t("日历"),
|
|
TIM_t(" 相机权限,以正常使用拍摄图片视频、视频通话等功能。"),
|
|
TIM_t("联系人"),
|
|
TIM_t("位置"),
|
|
'locationAlways',
|
|
'locationWhenInUse',
|
|
'mediaLibrary',
|
|
TIM_t(" 麦克风权限,以正常使用发送语音消息、拍摄视频、音视频通话等功能。"),
|
|
'phone',
|
|
TIM_t(" 访问照片权限,以正常使用发送图片、视频等功能。"),
|
|
TIM_t(" 访问相册写入权限,以正常使用存储图片、视频等功能。"),
|
|
'reminders',
|
|
'sensors',
|
|
'sms',
|
|
'speech',
|
|
TIM_t(" 文件读写权限,以正常使用在聊天功能中的图片查看、选择能力和发送文件的能力。"),
|
|
'ignoreBatteryOptimizations',
|
|
'notification',
|
|
'access_media_location',
|
|
'activity_recognition',
|
|
'unknown',
|
|
'bluetooth',
|
|
'manageExternalStorage',
|
|
'systemAlertWindow',
|
|
'requestInstallPackages',
|
|
'appTrackingTransparency',
|
|
'criticalAlerts',
|
|
'accessNotificationPolicy',
|
|
'bluetoothScan',
|
|
'bluetoothAdvertise',
|
|
'bluetoothConnect',
|
|
];
|
|
return _prefix + appName + _postfixList[value];
|
|
}
|
|
|
|
static Future<bool> checkPermission(
|
|
BuildContext context,
|
|
int value, [
|
|
TUITheme? theme,
|
|
bool isShowPermissionPage = true,
|
|
]) async {
|
|
final status = await Permission.byValue(value).status;
|
|
if (status.isGranted || status.isLimited) {
|
|
return true;
|
|
}
|
|
final bool? shouldRequestPermission = await showPermissionConfirmDialog(
|
|
context,
|
|
value,
|
|
theme,
|
|
isShowPermissionPage,
|
|
);
|
|
if (shouldRequestPermission != null && shouldRequestPermission) {
|
|
return await Permission.byValue(value).request().isGranted;
|
|
}
|
|
return shouldRequestPermission ?? false;
|
|
}
|
|
|
|
static Future<bool> checkPermissionSetBefore(int value) async {
|
|
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
|
SharedPreferences prefs = await _prefs;
|
|
final _hasPermissionSetBefore = prefs.getBool("permission$value");
|
|
return _hasPermissionSetBefore ?? false;
|
|
}
|
|
|
|
static Future<bool> setLocalPermission(int value) async {
|
|
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
|
SharedPreferences prefs = await _prefs;
|
|
return await prefs.setBool("permission$value", true);
|
|
}
|
|
|
|
static showPermissionRequestInfoDialog(BuildContext context, value) async {
|
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
|
String appName = packageInfo.appName;
|
|
OverlayEntry? _entry;
|
|
final entry = OverlayEntry(builder: (context) {
|
|
return PermissionRequestInfo(
|
|
appName: appName,
|
|
removeOverLay: () => _entry?.remove(),
|
|
permissionType: value,
|
|
);
|
|
});
|
|
_entry = entry;
|
|
Overlay.of(context)?.insert(entry);
|
|
}
|
|
|
|
static Future<bool?> showPermissionConfirmDialog(BuildContext context, value,
|
|
[TUITheme? theme, bool isShowPermissionPage = true]) async {
|
|
final platformUtils = PlatformUtils();
|
|
// 第一次直接走系统文案
|
|
if (!await checkPermissionSetBefore(value)) {
|
|
await setLocalPermission(value);
|
|
if (platformUtils.isAndroid && isShowPermissionPage) {
|
|
showPermissionRequestInfoDialog(context, value);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
|
String appName = packageInfo.appName;
|
|
final option2 = _names(context)[value];
|
|
final permissionText = _permissionText(context, appName, value);
|
|
void closeDialog() {
|
|
Navigator.of(context).pop(false);
|
|
}
|
|
|
|
void getPermission() async {
|
|
Navigator.of(context).pop(false);
|
|
openAppSettings();
|
|
}
|
|
|
|
return showDialog<bool>(
|
|
context: context,
|
|
builder: (context) {
|
|
return platformUtils.isIOS
|
|
? CupertinoAlertDialog(
|
|
title: Text("“$appName”" +
|
|
TIM_t_para(" 想访问您的{{option2}}", " 想访问您的$option2")(
|
|
option2: option2)),
|
|
content: Text(permissionText),
|
|
actions: <Widget>[
|
|
CupertinoDialogAction(
|
|
child: Text(TIM_t("以后再说")),
|
|
onPressed: closeDialog, // 关闭对话框
|
|
),
|
|
CupertinoDialogAction(
|
|
child: Text(TIM_t("去开启")),
|
|
onPressed: getPermission,
|
|
),
|
|
],
|
|
)
|
|
: AlertDialog(
|
|
content: Text(permissionText),
|
|
actions: <Widget>[
|
|
const Divider(),
|
|
SizedBox(
|
|
height: 48,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
Expanded(
|
|
child: TextButton(
|
|
child: Text(TIM_t("以后再说"),
|
|
style: TextStyle(
|
|
color: theme?.black ?? Colors.black,
|
|
)),
|
|
onPressed: closeDialog, // 关闭对话框
|
|
),
|
|
),
|
|
const VerticalDivider(),
|
|
Expanded(
|
|
child: TextButton(
|
|
child: Text(TIM_t("去开启"),
|
|
style: TextStyle(
|
|
color: theme?.black ?? Colors.black,
|
|
)),
|
|
onPressed: getPermission,
|
|
),
|
|
)
|
|
],
|
|
),
|
|
)
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|