Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
ethan
/
appframe
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit a6505868
authored
2025-12-02 13:52:42 +0800
by
tanghuan
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
权限设置引导,以及一些优化
1 parent
67ce5110
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
137 additions
and
11 deletions
lib/bloc/web_cubit.dart
lib/data/repositories/message/storage_handler.dart
lib/ui/pages/web_page.dart
lib/bloc/web_cubit.dart
View file @
a650586
...
...
@@ -2,6 +2,7 @@ import 'dart:async';
import
'dart:convert'
;
import
'dart:io'
;
import
'package:app_settings/app_settings.dart'
;
import
'package:appframe/config/constant.dart'
;
import
'package:appframe/config/locator.dart'
;
import
'package:appframe/config/routes.dart'
;
...
...
@@ -12,12 +13,14 @@ import 'package:appframe/services/local_server_service.dart';
import
'package:appframe/services/player_service.dart'
;
import
'package:appframe/services/recorder_service.dart'
;
import
'package:appframe/utils/zip_util.dart'
;
import
'package:device_info_plus/device_info_plus.dart'
;
import
'package:dio/dio.dart'
;
import
'package:equatable/equatable.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:fluwx/fluwx.dart'
;
import
'package:path_provider/path_provider.dart'
;
import
'package:permission_handler/permission_handler.dart'
;
import
'package:shared_preferences/shared_preferences.dart'
;
import
'package:uuid/uuid.dart'
;
import
'package:webview_flutter/webview_flutter.dart'
;
...
...
@@ -59,7 +62,9 @@ class WebState extends Equatable {
final
bool
chooseVideoCmdFlag
;
final
String
chooseVideoCmdMessage
;
const
WebState
({
final
String
h5Version
;
WebState
({
this
.
selectedIndex
=
0
,
this
.
loaded
=
false
,
this
.
isUpgrading
=
false
,
...
...
@@ -82,7 +87,8 @@ class WebState extends Equatable {
this
.
chooseImageCmdMessage
=
''
,
this
.
chooseVideoCmdFlag
=
false
,
this
.
chooseVideoCmdMessage
=
''
,
});
String
?
h5Version
,
})
:
this
.
h5Version
=
h5Version
??
getIt
.
get
<
SharedPreferences
>().
getString
(
"h5_version"
)
??
Constant
.
h5Version
;
WebState
copyWith
({
int
?
selectedIndex
,
...
...
@@ -108,6 +114,7 @@ class WebState extends Equatable {
String
?
chooseImageCmdMessage
,
bool
?
chooseVideoCmdFlag
,
String
?
chooseVideoCmdMessage
,
String
?
h5Version
,
})
{
return
WebState
(
selectedIndex:
selectedIndex
??
this
.
selectedIndex
,
...
...
@@ -132,6 +139,7 @@ class WebState extends Equatable {
chooseImageCmdMessage:
chooseImageCmdMessage
??
this
.
chooseImageCmdMessage
,
chooseVideoCmdFlag:
chooseVideoCmdFlag
??
this
.
chooseVideoCmdFlag
,
chooseVideoCmdMessage:
chooseVideoCmdMessage
??
this
.
chooseVideoCmdMessage
,
h5Version:
h5Version
??
this
.
h5Version
,
);
}
...
...
@@ -159,6 +167,7 @@ class WebState extends Equatable {
chooseImageCmdMessage
,
chooseVideoCmdFlag
,
chooseVideoCmdMessage
,
h5Version
,
];
}
...
...
@@ -475,9 +484,9 @@ class WebCubit extends Cubit<WebState> {
Future
<
void
>
clearStorage
()
async
{
// 1 清理非 h5_version 的缓存
var
sharedPreferences
=
getIt
.
get
<
SharedPreferences
>();
sharedPreferences
.
getKeys
().
forEach
((
key
)
{
sharedPreferences
.
getKeys
().
forEach
((
key
)
async
{
if
(!
key
.
startsWith
(
'h5_version'
))
{
sharedPreferences
.
remove
(
key
);
await
sharedPreferences
.
remove
(
key
);
}
});
...
...
@@ -619,16 +628,29 @@ class WebCubit extends Cubit<WebState> {
}
void
_chooseImageFromAlbum
(
BuildContext
context
,
int
count
,
String
unique
,
String
cmd
)
async
{
final
List
<
AssetEntity
>?
result
=
await
AssetPicker
.
pickAssets
(
final
List
<
AssetEntity
>?
result
;
try
{
result
=
await
AssetPicker
.
pickAssets
(
context
,
pickerConfig:
AssetPickerConfig
(
maxAssets:
count
,
requestType:
RequestType
.
image
,
gridThumbnailSize:
const
ThumbnailSize
.
square
(
8
0
),
gridThumbnailSize:
const
ThumbnailSize
.
square
(
12
0
),
previewThumbnailSize:
const
ThumbnailSize
.
square
(
150
),
dragToSelect:
false
,
),
);
}
catch
(
e
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'no auth'
};
_sendResponse
(
resp
);
// 权限异常之后,检查是否已被永久拒绝,此时需要对用户进行引导
if
(
await
_checkGalleryPermanentlyDenied
())
{
_permissionLead
(
context
,
'相册权限'
);
}
return
;
}
if
(
result
==
null
||
result
.
isEmpty
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'cancel'
};
...
...
@@ -653,7 +675,19 @@ class WebCubit extends Cubit<WebState> {
}
void
_chooseImageFromCamera
(
BuildContext
context
,
String
unique
,
String
cmd
)
async
{
AssetEntity
?
asset
=
await
CameraPicker
.
pickFromCamera
(
context
,
pickerConfig:
const
CameraPickerConfig
());
AssetEntity
?
asset
;
try
{
asset
=
await
CameraPicker
.
pickFromCamera
(
context
,
pickerConfig:
const
CameraPickerConfig
());
}
catch
(
e
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'no auth'
};
_sendResponse
(
resp
);
if
(
await
_checkCameraPermanentlyDenied
())
{
_permissionLead
(
context
,
'相机权限'
);
}
return
;
}
if
(
asset
==
null
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'cancel'
};
...
...
@@ -693,6 +727,64 @@ class WebCubit extends Cubit<WebState> {
};
}
///
/// 引导打开权限设置
///
Future
<
void
>
_permissionLead
(
BuildContext
context
,
String
permission
)
async
{
showDialog
(
context:
context
,
builder:
(
BuildContext
context
)
{
return
AlertDialog
(
title:
Text
(
'权限设置'
),
content:
Text
(
'
$permission
已被拒绝,请到设置中手动开启权限'
),
actions:
<
Widget
>[
TextButton
(
child:
Text
(
'取消'
),
onPressed:
()
{
Navigator
.
of
(
context
).
pop
();
},
),
TextButton
(
child:
Text
(
'去设置'
),
onPressed:
()
{
Navigator
.
of
(
context
).
pop
();
AppSettings
.
openAppSettings
(
asAnotherTask:
true
);
// 引导用户到应用设置页面
},
),
],
);
},
);
}
///
/// 检测相册权限是否被永久拒绝
///
Future
<
bool
>
_checkGalleryPermanentlyDenied
()
async
{
PermissionStatus
status
;
if
(
Platform
.
isAndroid
)
{
final
androidInfo
=
await
DeviceInfoPlugin
().
androidInfo
;
if
(
androidInfo
.
version
.
sdkInt
<=
32
)
{
status
=
await
Permission
.
storage
.
status
;
}
else
{
status
=
await
Permission
.
photos
.
status
;
}
}
else
if
(
Platform
.
isIOS
)
{
status
=
await
Permission
.
photos
.
status
;
}
else
{
return
false
;
}
return
PermissionStatus
.
permanentlyDenied
==
status
;
}
///
/// 检测摄像头权限是否被永久拒绝
///
Future
<
bool
>
_checkCameraPermanentlyDenied
()
async
{
PermissionStatus
status
=
await
Permission
.
camera
.
status
;
return
PermissionStatus
.
permanentlyDenied
==
status
;
}
void
setChooseVideoCmdFlag
(
bool
chooseVideoCmdFlag
,
String
chooseVideoCmdMessage
)
{
emit
(
state
.
copyWith
(
chooseVideoCmdFlag:
chooseVideoCmdFlag
,
chooseVideoCmdMessage:
chooseVideoCmdMessage
));
}
...
...
@@ -739,7 +831,10 @@ class WebCubit extends Cubit<WebState> {
}
void
_chooseVideoFromAlbum
(
BuildContext
context
,
int
count
,
String
unique
,
String
cmd
)
async
{
final
List
<
AssetEntity
>?
result
=
await
AssetPicker
.
pickAssets
(
List
<
AssetEntity
>?
result
;
try
{
result
=
await
AssetPicker
.
pickAssets
(
context
,
pickerConfig:
AssetPickerConfig
(
maxAssets:
count
,
...
...
@@ -747,6 +842,17 @@ class WebCubit extends Cubit<WebState> {
dragToSelect:
false
,
),
);
}
catch
(
e
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'no auth'
};
_sendResponse
(
resp
);
// 权限异常之后,检查是否已被永久拒绝,此时需要对用户进行引导
if
(
await
_checkGalleryPermanentlyDenied
())
{
_permissionLead
(
context
,
'相册权限'
);
}
return
;
}
if
(
result
==
null
||
result
.
isEmpty
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'cancel'
};
...
...
@@ -771,7 +877,9 @@ class WebCubit extends Cubit<WebState> {
}
void
_chooseVideoFromCamera
(
BuildContext
context
,
int
maxDuration
,
String
unique
,
String
cmd
)
async
{
AssetEntity
?
asset
=
await
CameraPicker
.
pickFromCamera
(
AssetEntity
?
asset
;
try
{
asset
=
await
CameraPicker
.
pickFromCamera
(
context
,
pickerConfig:
CameraPickerConfig
(
enableRecording:
true
,
...
...
@@ -780,6 +888,16 @@ class WebCubit extends Cubit<WebState> {
maximumRecordingDuration:
Duration
(
seconds:
maxDuration
),
),
);
}
catch
(
e
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'no auth'
};
_sendResponse
(
resp
);
if
(
await
_checkCameraPermanentlyDenied
())
{
_permissionLead
(
context
,
'相机权限'
);
}
return
;
}
if
(
asset
==
null
)
{
var
resp
=
{
'unique'
:
unique
,
'cmd'
:
cmd
,
'data'
:
null
,
'errMsg'
:
'cancel'
};
...
...
lib/data/repositories/message/storage_handler.dart
View file @
a650586
...
...
@@ -57,6 +57,13 @@ class RemoveStorageHandler extends MessageHandler {
class
ClearStorageHandler
extends
MessageHandler
{
@override
Future
<
dynamic
>
handleMessage
(
dynamic
params
)
async
{
return
await
getIt
.
get
<
SharedPreferences
>().
clear
();
var
sharedPreferences
=
getIt
.
get
<
SharedPreferences
>();
sharedPreferences
.
getKeys
().
forEach
((
key
)
async
{
if
(!
key
.
startsWith
(
'h5_version'
))
{
await
sharedPreferences
.
remove
(
key
);
}
});
return
true
;
}
}
lib/ui/pages/web_page.dart
View file @
a650586
...
...
@@ -151,12 +151,13 @@ class WebPage extends StatelessWidget {
child:
Column
(
children:
[
Text
(
'Version
${Constant.appVersion}
'
,
'Version
${Constant.appVersion}
-
${state.h5Version}
'
,
style:
TextStyle
(
color:
Colors
.
grey
,
fontSize:
12
,
),
),
SizedBox
(
height:
8
),
Text
(
'Copyright © 中山班小二科技有限公司'
,
),
...
...
Write
Preview
Styling with
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment