Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
A
apk_update
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
openSourceLibrary
apk_update
Commits
deaba6f0
提交
deaba6f0
authored
6月 18, 2025
作者:
史晓晨
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:调试项目管理工具升级功能
上级
29676c8c
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
268 行增加
和
7 行删除
+268
-7
gradle-wrapper.properties
example/android/gradle/wrapper/gradle-wrapper.properties
+2
-1
main.dart
example/lib/main.dart
+20
-1
apk_update.dart
lib/apk_update.dart
+82
-0
utils.dart
lib/utils/utils.dart
+161
-2
update_dialog.dart
lib/widget/update_dialog.dart
+3
-3
没有找到文件。
example/android/gradle/wrapper/gradle-wrapper.properties
浏览文件 @
deaba6f0
...
...
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath
=
wrapper/dists
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-7.
5
-all.zip
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-7.
6.3
-all.zip
\ No newline at end of file
example/lib/main.dart
浏览文件 @
deaba6f0
...
...
@@ -42,7 +42,7 @@ class _MyAppState extends State<MyApp> {
'objectKey'
:
'msl.apk'
,
'bucketName'
:
'mslapp-download'
,
'endpoint'
:
'oss-cn-beijing.aliyuncs.com'
,
"baseUrl"
:
"https://gateway.testclx.cn"
"baseUrl"
:
"https://gateway.testclx.cn"
};
ApkUpdate
().
updateApp
(
url:
...
...
@@ -61,6 +61,25 @@ class _MyAppState extends State<MyApp> {
},
child:
const
Text
(
'升级应用(新)'
),
),
TextButton
(
onPressed:
()
{
var
map
=
{
'token'
:
"20502a804a784bc1a21681e26aa14cb8"
,
'objectKey'
:
'msl.apk'
,
'bucketName'
:
'mslapp-download'
,
'endpoint'
:
'oss-cn-beijing.aliyuncs.com'
,
"baseUrl"
:
"https://gateway.testclx.cn"
};
ApkUpdate
().
updateAppByPM
(
baseUrl:
"https://gateway.91msl.com"
,
productCode:
"msl-report-app"
,
versionNumber:
1
,
onceDay:
false
,
paramsOSS:
map
,
appleId:
"1585610919"
);
},
child:
const
Text
(
'升级应用(项目管理工具)'
),
),
],
),
),
...
...
lib/apk_update.dart
浏览文件 @
deaba6f0
import
'dart:io'
;
import
'package:apk_update/utils/dio_update_util.dart'
;
import
'package:apk_update/utils/toast_util.dart'
;
import
'package:apk_update/utils/utils.dart'
;
import
'package:flutter/material.dart'
;
import
'package:url_launcher/url_launcher.dart'
;
...
...
@@ -142,4 +145,83 @@ class ApkUpdate {
},
);
}
/// 对接项目管理工具升级功能
/// baseUrl:
void
updateAppByPM
({
required
String
baseUrl
,
required
String
productCode
,
required
int
versionNumber
,
required
String
appleId
,
bool
onceDay
=
false
,
Map
<
String
,
dynamic
>?
paramsOSS
,
})
{
var
params
=
{
"productCode"
:
productCode
,
"currentVersion"
:
versionNumber
,
"sideType"
:
Platform
.
isIOS
?
2
:
1
};
checkVersionPM
(
baseUrl:
baseUrl
,
params:
params
,
onceDay:
onceDay
,
isOssDownload:
paramsOSS
!=
null
?
1
:
0
,
jumpAppStore:
()
{
// 跳转AppStore
debugPrint
(
"===== jumpAppStore"
);
_jumpAppStore
(
appleId
);
},
installApk:
(
String
?
path
)
{
// 安装Apk
debugPrint
(
"===== installApk"
);
ApkUpdatePlatform
.
instance
.
installApk
(
path
);
},
downloadApk:
(
String
?
path
,
String
?
apkPath
)
async
{
DioUpdateUtil
.
getDio
()
.
get
(
"
${paramsOSS?['baseUrl']}$generateByExt
"
,
queryParameters:
{
"extension"
:
"apk"
,
"bucketName"
:
paramsOSS
?[
"bucketName"
]
},
options:
Options
(
headers:
{
"token"
:
paramsOSS
?[
'token'
],
"product-code"
:
params
[
"productCode"
]
}))
.
then
((
res
)
{
if
(
res
.
data
==
null
||
res
.
data
is
String
)
{
debugPrint
(
'获取OSS授权失败:
${res.data}
'
);
ToastUtil
.
showToast
(
"获取OSS授权失败,请稍后重新"
);
return
;
}
var
map
=
res
.
data
[
'data'
];
// 使用OSS下载
var
ak
=
map
?[
'onceAccessKeyId'
];
var
sk
=
map
?[
"onceAccessKeySecret"
];
var
token
=
map
?[
"onceSecurityToken"
];
var
objectKey
=
apkPath
??
""
;
// apkPath https://mslapp-download.oss-cn-beijing.aliyuncs.com/msl-chengyun.apk 截取后:msl-chengyun.apk
objectKey
=
objectKey
.
substring
(
objectKey
.
lastIndexOf
(
"/"
)
+
1
);
var
endpoint
=
paramsOSS
?[
"endpoint"
];
var
bucketName
=
paramsOSS
?[
"bucketName"
];
var
localPath
=
path
;
if
(
localPath
==
null
)
{
ToastUtil
.
showToast
(
"下载路径错误,请稍后重新"
);
return
;
}
ApkUpdatePlatform
.
instance
.
downloadApk
(
ak
,
sk
,
token
,
objectKey
,
endpoint
,
bucketName
,
localPath
);
}).
catchError
((
e
)
{
debugPrint
(
'获取OSS授权失败'
);
ToastUtil
.
showToast
(
"获取OSS授权失败,请稍后重新"
);
return
;
});
},
downloadApkError:
()
{
// 下载Apk错误
debugPrint
(
"===== downloadApkError"
);
ToastUtil
.
showToast
(
"应用更新失败,请稍后重新"
);
},
);
}
}
lib/utils/utils.dart
浏览文件 @
deaba6f0
...
...
@@ -13,6 +13,11 @@ import 'dio_update_util.dart';
// 获取版本号
const
String
getSystemVersionByNumber
=
"/user-service/system/version/getSystemVersionByNumber"
;
// 项目管理工具 版本检测接口
const
getLatestByProductCodePM
=
"/pm-process/external/web/onlineConfig/getLatestByProductCode"
;
// 项目管理工具 获取信息版本详情
const
getDetailPM
=
"/pm-process/external/web/onlineConfig/getDetail"
;
// 获取OSS 下载授权ak sk token
const
String
generateByExt
=
"/msl-document/common/oss/generateByExt"
;
const
currentDay
=
"current_day"
;
...
...
@@ -75,7 +80,7 @@ void checkVersion(
// 一天提示一次升级,是在应用首次设置,不需要提示最新版本toast
if
(!
onceDay
&&
result
==
null
)
{
// 当前已经是最新版本
ToastUtil
.
showToast
(
"
当前已经是最新版本
"
);
ToastUtil
.
showToast
(
"
已经是最新版本了!
"
);
return
;
}
if
(
result
==
null
)
{
...
...
@@ -87,7 +92,161 @@ void checkVersion(
UpdateDialog
(
title:
result
[
'versionName'
],
content:
result
[
'tipContent'
]
??
result
[
'versionContent'
],
isUpdateMore:
result
[
'versionForce'
]
==
1
,
versionForce:
result
[
'versionForce'
]
==
1
,
versionPath:
result
[
'versionPath'
],
jumpAppStore:
jumpAppStore
,
installApk:
installApk
,
isOssDownload:
isOssDownload
,
downloadApk:
downloadApk
,
downloadApkError:
downloadApkError
,
),
);
}
on
DioException
catch
(
e
)
{
_printLog
(
e
.
response
);
// 打印日志
ToastUtil
.
showToast
(
"服务器请求错误"
);
}
}
/// 检查版本(项目管理工具)
void
checkVersionPM
(
{
required
String
baseUrl
,
Map
<
String
,
dynamic
>?
params
,
bool
onceDay
=
false
,
Function
()?
jumpAppStore
,
// 跳转AppStore
Function
(
String
?
path
)?
installApk
,
// 安装Apk
Function
()?
downloadApkError
,
// 下载Apk错误
Function
(
String
?
path
,
String
?
apkPath
)?
downloadApk
,
// 使用OSS下载Apk
int
?
isOssDownload
//1 使用OSS下载
})
async
{
// 判断网络是否连接
var
resList
=
await
connectivity
.
checkConnectivity
();
if
(
resList
.
isNotEmpty
&&
resList
[
0
]
==
ConnectivityResult
.
none
)
{
ToastUtil
.
showToast
(
"网络异常,请检查网络"
);
return
;
}
try
{
final
Response
response
=
await
DioUpdateUtil
.
getDio
().
request
(
"
$baseUrl$getLatestByProductCodePM
"
,
options:
Options
(
method:
Method
.
get
.
value
,
headers:
{
"productGroupCode"
:
"common"
}),
queryParameters:
params
,
);
// 网络请求成功
_printLog
(
response
);
// 打印日志
var
responseData
=
response
.
data
;
if
(
responseData
.
runtimeType
==
String
)
{
// 兼容后端数据返回string
responseData
=
json
.
decode
(
responseData
);
}
if
(
responseData
?[
"code"
]
!=
0
)
{
ToastUtil
.
showToast
(
responseData
?[
"msg"
]);
return
;
}
var
result
=
responseData
?[
"data"
];
// 是否是最新版本提示
final
newVersion
=
int
.
tryParse
(
result
?[
'version'
]?.
toString
()
??
''
)
??
0
;
final
currentVersion
=
int
.
tryParse
(
params
?[
"currentVersion"
]?.
toString
()
??
''
)
??
0
;
if
(
newVersion
<=
currentVersion
)
{
if
(!
onceDay
)
{
ToastUtil
.
showToast
(
'已经是最新版本了!'
);
}
return
;
}
// 获取新版本详情
getVersionDetailPM
(
baseUrl:
baseUrl
,
id:
result
?[
'id'
],
onceDay:
onceDay
,
versionNumber:
params
?[
"currentVersion"
],
jumpAppStore:
jumpAppStore
,
installApk:
installApk
,
downloadApkError:
downloadApkError
,
downloadApk:
downloadApk
,
isOssDownload:
isOssDownload
,
);
}
on
DioException
catch
(
e
)
{
_printLog
(
e
.
response
);
// 打印日志
ToastUtil
.
showToast
(
"服务器请求错误"
);
}
}
/// 获取版本详情(项目管理工具)
void
getVersionDetailPM
(
{
required
String
baseUrl
,
required
int
?
id
,
required
bool
onceDay
,
required
int
?
versionNumber
,
Function
()?
jumpAppStore
,
// 跳转AppStore
Function
(
String
?
path
)?
installApk
,
// 安装Apk
Function
()?
downloadApkError
,
// 下载Apk错误
Function
(
String
?
path
,
String
?
apkPath
)?
downloadApk
,
// 使用OSS下载Apk
int
?
isOssDownload
,
//1 使用OSS下载
})
async
{
// 判断网络是否连接
var
resList
=
await
connectivity
.
checkConnectivity
();
if
(
resList
.
isNotEmpty
&&
resList
[
0
]
==
ConnectivityResult
.
none
)
{
ToastUtil
.
showToast
(
"网络异常,请检查网络"
);
return
;
}
try
{
final
Response
response
=
await
DioUpdateUtil
.
getDio
().
request
(
"
$baseUrl$getDetailPM
"
,
options:
Options
(
method:
Method
.
get
.
value
,
headers:
{
'productGroupCode'
:
'common'
,
}),
queryParameters:
{
'id'
:
id
},
);
// 网络请求成功
_printLog
(
response
);
// 打印日志
var
responseData
=
response
.
data
;
if
(
responseData
.
runtimeType
==
String
)
{
// 兼容后端数据返回string
responseData
=
json
.
decode
(
responseData
);
}
if
(
responseData
?[
"code"
]
!=
0
)
{
ToastUtil
.
showToast
(
responseData
?[
"msg"
]);
return
;
}
var
result
=
responseData
?[
"data"
];
//获取当前时间
String
spCurrent
=
SpUtil
.
getString
(
currentDay
)
??
""
;
String
current
=
DateUtil
.
formatDate
(
DateTime
.
now
(),
format:
dateFormat
);
// 是否是强升
final
versionForce
=
result
?[
'forceUpgradeStatus'
]
==
1
;
//一天提示一次升级 & 非强升 & 当天已提示 => 不再提示
if
(
onceDay
&&
!
versionForce
&&
spCurrent
==
current
)
{
// 不再提示
return
;
}
//缓存当前时间
SpUtil
.
putString
(
currentDay
,
current
);
// 一天提示一次升级,是在应用首次设置,不需要提示最新版本toast
if
(!
onceDay
&&
result
==
null
)
{
// 当前已经是最新版本
ToastUtil
.
showToast
(
"已经是最新版本了!"
);
return
;
}
// 是否是最新版本提示
final
newVersion
=
int
.
tryParse
(
result
?[
'version'
]?.
toString
()
??
''
)
??
0
;
final
currentVersion
=
int
.
tryParse
(
versionNumber
?.
toString
()
??
''
)
??
0
;
if
(
newVersion
<=
currentVersion
)
{
if
(!
onceDay
)
{
ToastUtil
.
showToast
(
'已经是最新版本了!'
);
}
return
;
}
// 升级弹框提示
Get
.
dialog
(
UpdateDialog
(
title:
result
[
'name'
],
content:
result
[
'popContent'
],
versionForce:
result
[
'forceUpgradeStatus'
]
==
1
,
versionPath:
result
[
'versionPath'
],
jumpAppStore:
jumpAppStore
,
installApk:
installApk
,
...
...
lib/widget/update_dialog.dart
浏览文件 @
deaba6f0
...
...
@@ -15,7 +15,7 @@ import '../apk_update_platform_interface.dart';
class
UpdateDialog
extends
StatefulWidget
{
final
String
?
title
;
// 升级版本
final
String
?
content
;
// 升级内容
final
bool
isUpdateMor
e
;
// 是否强升
final
bool
versionForc
e
;
// 是否强升
final
String
?
versionPath
;
// apk 路径
final
Function
()?
jumpAppStore
;
// 跳转AppStore
final
Function
(
String
?
path
)?
installApk
;
// 安装Apk
...
...
@@ -27,7 +27,7 @@ class UpdateDialog extends StatefulWidget {
Key
?
key
,
this
.
title
,
this
.
content
,
this
.
isUpdateMor
e
=
false
,
this
.
versionForc
e
=
false
,
this
.
versionPath
,
this
.
jumpAppStore
,
this
.
installApk
,
...
...
@@ -118,7 +118,7 @@ class _UpdateDialogState extends State<UpdateDialog> {
),
const
SizedBox
(
height:
5.0
),
Offstage
(
offstage:
widget
.
isUpdateMor
e
,
offstage:
widget
.
versionForc
e
,
child:
_btn
(
title:
'忽略此版本'
,
textColor:
const
Color
(
0xFF666666
),
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论