fix: permission dialog (#1799)

* don't request photo permission on A13+

saving to system album requires no additional permission

* fix permission dialog

* update

Signed-off-by: dom <githubaccount56556@proton.me>

---------

Co-authored-by: dom <githubaccount56556@proton.me>
This commit is contained in:
KoishiMoe
2026-01-09 11:07:39 +08:00
committed by GitHub
parent fffce10b31
commit dbc11c36df
6 changed files with 29 additions and 58 deletions

View File

@@ -117,10 +117,7 @@ void imageSaveDialog({
iconBtn(
tooltip: '保存封面图',
onPressed: () async {
bool saveStatus = await ImageUtils.downloadImg(
context,
[cover],
);
bool saveStatus = await ImageUtils.downloadImg([cover]);
if (saveStatus) {
SmartDialog.dismiss();
}

View File

@@ -437,10 +437,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
ListTile(
onTap: () {
Get.back();
ImageUtils.downloadImg(
this.context,
[item.url],
);
ImageUtils.downloadImg([item.url]);
},
dense: true,
title: const Text('保存图片', style: TextStyle(fontSize: 14)),
@@ -459,7 +456,6 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
onTap: () {
Get.back();
ImageUtils.downloadImg(
this.context,
widget.sources.map((item) => item.url).toList(),
);
},
@@ -471,7 +467,6 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
onTap: () {
Get.back();
ImageUtils.downloadLivePhoto(
context: this.context,
url: item.url,
liveUrl: item.liveUrl!,
width: item.width!,
@@ -503,7 +498,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
),
PopupMenuItem(
height: 42,
onTap: () => ImageUtils.downloadImg(context, [item.url]),
onTap: () => ImageUtils.downloadImg([item.url]),
child: const Text('保存图片', style: TextStyle(fontSize: 14)),
),
PopupMenuItem(
@@ -515,7 +510,6 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
PopupMenuItem(
height: 42,
onTap: () => ImageUtils.downloadLivePhoto(
context: context,
url: item.url,
liveUrl: item.liveUrl!,
width: item.width!,

View File

@@ -291,7 +291,7 @@ class _SavePanelState extends State<SavePanel> {
Future<void> _onSaveOrSharePic([bool isShare = false]) async {
if (!isShare && PlatformUtils.isMobile) {
if (mounted && !await ImageUtils.checkPermissionDependOnSdkInt(context)) {
if (mounted && !await ImageUtils.checkPermissionDependOnSdkInt()) {
return;
}
}

View File

@@ -1312,10 +1312,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
),
if (videoDetailController.cover.value.isNotEmpty)
PopupMenuItem(
onTap: () => ImageUtils.downloadImg(
context,
[videoDetailController.cover.value],
),
onTap: () =>
ImageUtils.downloadImg([videoDetailController.cover.value]),
child: const Text('保存封面'),
),
if (!videoDetailController.isFileSource && videoDetailController.isUgc)

View File

@@ -407,10 +407,9 @@ class HeaderControlState extends State<HeaderControl>
dense: true,
onTap: () {
Get.back();
ImageUtils.downloadImg(
context,
[widget.videoDetailCtr.cover.value],
);
ImageUtils.downloadImg([
widget.videoDetailCtr.cover.value,
]);
},
leading: const Icon(Icons.image_outlined, size: 20),
title: const Text('保存封面', style: titleStyle),

View File

@@ -50,22 +50,24 @@ abstract final class ImageUtils {
}
// 获取存储权限
static Future<bool> requestStoragePer(BuildContext context) async {
await Permission.storage.request();
PermissionStatus status = await Permission.storage.status;
static Future<bool> requestPer() async {
final status = Platform.isAndroid
? await Permission.storage.request()
: await Permission.photos.request();
if (status == PermissionStatus.denied ||
status == PermissionStatus.permanentlyDenied) {
if (!context.mounted) return false;
showDialog(
context: context,
SmartDialog.show(
builder: (context) {
return const AlertDialog(
title: Text('提示'),
content: Text('存储权限未授权'),
return AlertDialog(
title: const Text('提示'),
content: const Text('存储权限未授权'),
actions: [
TextButton(
onPressed: openAppSettings,
child: Text('去授权'),
onPressed: () {
SmartDialog.dismiss();
openAppSettings();
},
child: const Text('去授权'),
),
],
);
@@ -77,42 +79,25 @@ abstract final class ImageUtils {
}
}
// 获取相册权限
static Future<bool> requestPhotoPer() async {
await Permission.photos.request();
PermissionStatus status = await Permission.photos.status;
if (status == PermissionStatus.denied ||
status == PermissionStatus.permanentlyDenied) {
return false;
} else {
return true;
}
}
static Future<bool> checkPermissionDependOnSdkInt(
BuildContext context,
) async {
static Future<bool> checkPermissionDependOnSdkInt() async {
if (Platform.isAndroid) {
if (await Utils.sdkInt <= 32) {
if (!context.mounted) return false;
return requestStoragePer(context);
if (await Utils.sdkInt < 29) {
return requestPer();
} else {
return requestPhotoPer();
return true;
}
}
return requestStoragePer(context);
return requestPer();
}
static Future<bool> downloadLivePhoto({
required BuildContext context,
required String url,
required String liveUrl,
required int width,
required int height,
}) async {
try {
if (PlatformUtils.isMobile &&
!await checkPermissionDependOnSdkInt(context)) {
if (PlatformUtils.isMobile && !await checkPermissionDependOnSdkInt()) {
return false;
}
if (!silentDownImg) SmartDialog.showLoading(msg: '正在下载');
@@ -167,12 +152,10 @@ abstract final class ImageUtils {
}
static Future<bool> downloadImg(
BuildContext context,
List<String> imgList, [
CacheManager? manager,
]) async {
if (PlatformUtils.isMobile &&
!await checkPermissionDependOnSdkInt(context)) {
if (PlatformUtils.isMobile && !await checkPermissionDependOnSdkInt()) {
return false;
}
CancelToken? cancelToken;