Compare commits

..

10 Commits

Author SHA1 Message Date
ZhanGSKen
bf17688ebf 发布测试 2025-04-27 08:09:42 +08:00
ZhanGSKen
c2ed7d648b 编译测试 2025-04-27 08:07:06 +08:00
ZhanGSKen
458fa40c40 更换为maven库引用方式的类库依赖。 2025-04-27 08:05:00 +08:00
ZhanGSKen
6190d728db 类库模块移除安卓版本依赖 2025-04-27 02:01:43 +08:00
ZhanGSKen
94375f34e2 编译模块方式调整 2025-04-27 01:08:33 +08:00
ZhanGSKen
a0e5a687d3 调整类库组织类型为子项目模块引用,忽略采用Maven库依赖的方法。 2025-04-27 01:01:12 +08:00
ZhanGSKen
ecccc68b8e 编译测试 2025-04-27 00:44:27 +08:00
ZhanGSKen
7565eb6cf0 <libapputils>Library Release 15.2.2 2025-04-03 11:09:47 +08:00
ZhanGSKen
eee62024cf <apputils>APK 15.2.2 release Publish. 2025-04-03 11:09:25 +08:00
ZhanGSKen
bf6870696d 清理应用介绍模块资源,模块已移动至AES。 2025-04-03 11:08:21 +08:00
190 changed files with 2256 additions and 3844 deletions

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "libjc/jcc/libs"]
path = libjc/jcc/libs
url = https://gitea.winboll.cc/Studio/APP_libjc_jcc_libs.git

View File

@@ -1,4 +1,4 @@
## WinBoLL 主机编译事项提醒 ## WinBoll 主机编译事项提醒
## 类库类型源码发布 ## 类库类型源码发布
# 类库发布使用以下面命令 # 类库发布使用以下面命令

View File

@@ -37,7 +37,7 @@ fi
# 使用grep找到包含"publishVersion="的那一行然后用awk提取其后的值 # 使用grep找到包含"publishVersion="的那一行然后用awk提取其后的值
PUBLISH_VERSION=$(grep -o "publishVersion=.*" $1/build.properties | awk -F '=' '{print $2}') PUBLISH_VERSION=$(grep -o "publishVersion=.*" $1/build.properties | awk -F '=' '{print $2}')
echo "< $1/build.properties publishVersion : ${PUBLISH_VERSION} >" echo "< $1/build.properties publishVersion : ${PUBLISH_VERSION} >"
## 设新的 WinBoLL 标签 ## 设新的 WinBoll 标签
# 脚本调试时使用 # 脚本调试时使用
#tag="v7.6.4-test1" #tag="v7.6.4-test1"
# 正式设置标签时使用 # 正式设置标签时使用

View File

@@ -38,24 +38,24 @@ function askAddWorkflowsTag {
fi fi
} }
function addWinBoLLTag { function addWinBollTag {
# 就读取脚本 .winboll/winboll_app_build.gradle 生成的 publishVersion。 # 就读取脚本 .winboll/winboll_app_build.gradle 生成的 publishVersion。
# 如果文件中有 publishVersion 这一项, # 如果文件中有 publishVersion 这一项,
# 使用grep找到包含"publishVersion="的那一行然后用awk提取其后的值 # 使用grep找到包含"publishVersion="的那一行然后用awk提取其后的值
PUBLISH_VERSION=$(grep -o "publishVersion=.*" $1/build.properties | awk -F '=' '{print $2}') PUBLISH_VERSION=$(grep -o "publishVersion=.*" $1/build.properties | awk -F '=' '{print $2}')
echo "< $1/build.properties publishVersion : ${PUBLISH_VERSION} >" echo "< $1/build.properties publishVersion : ${PUBLISH_VERSION} >"
## 设新的 WinBoLL 标签 ## 设新的 WinBoll 标签
# 脚本调试时使用 # 脚本调试时使用
#tag="projectname-v7.6.4-test1" #tag="projectname-v7.6.4-test1"
# 正式设置标签时使用 # 正式设置标签时使用
tag=$1"-v"${PUBLISH_VERSION} tag=$1"-v"${PUBLISH_VERSION}
echo "< WinBoLL Tag To: $tag >"; echo "< WinBoll Tag To: $tag >";
# 检查是否已经添加了 WinBoLL Tag # 检查是否已经添加了 WinBoll Tag
if [ "$(git tag -l ${tag})" == "${tag}" ]; then if [ "$(git tag -l ${tag})" == "${tag}" ]; then
echo -e "< WinBoLL Tag ${tag} exist! >" echo -e "< WinBoll Tag ${tag} exist! >"
return 1 # WinBoLL标签重复 return 1 # WinBoll标签重复
fi fi
# 添加WinBoLL标签 # 添加WinBoll标签
git tag -a ${tag} -F $1/app_update_description.txt git tag -a ${tag} -F $1/app_update_description.txt
return 0 return 0
} }
@@ -119,22 +119,22 @@ if [[ $? -eq 0 ]]; then
echo $result echo $result
# 发布应用 # 发布应用
echo "Publishing WinBoLL APK ..." echo "Publishing WinBoll APK ..."
# 脚本调试时使用 # 脚本调试时使用
#bash gradlew :$1:assembleBetaDebug #bash gradlew :$1:assembleBetaDebug
# 正式发布 # 正式发布
bash gradlew :$1:assembleStageRelease bash gradlew :$1:assembleStageRelease
echo "Publishing WinBoLL APK OK." echo "Publishing WinBoll APK OK."
# 添加 WinBoLL 标签 # 添加 WinBoll 标签
result=$(addWinBoLLTag $1) result=$(addWinBollTag $1)
echo $result echo $result
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo $result echo $result
# WinBoLL 标签添加成功 # WinBoll 标签添加成功
else else
echo -e "${0}: addWinBoLLTag $1\n${result}\nAdd WinBoLL tag cancel." echo -e "${0}: addWinBollTag $1\n${result}\nAdd WinBoll tag cancel."
exit 1 # addWinBoLLTag 异常 exit 1 # addWinBollTag 异常
fi fi
# 添加 GitHub 工作流标签 # 添加 GitHub 工作流标签

View File

@@ -38,24 +38,24 @@ function askAddWorkflowsTag {
fi fi
} }
function addWinBoLLTag { function addWinBollTag {
# 就读取脚本 .winboll/winboll_app_build.gradle 生成的 publishVersion。 # 就读取脚本 .winboll/winboll_app_build.gradle 生成的 publishVersion。
# 如果文件中有 publishVersion 这一项, # 如果文件中有 publishVersion 这一项,
# 使用grep找到包含"publishVersion="的那一行然后用awk提取其后的值 # 使用grep找到包含"publishVersion="的那一行然后用awk提取其后的值
PUBLISH_VERSION=$(grep -o "publishVersion=.*" $1/build.properties | awk -F '=' '{print $2}') PUBLISH_VERSION=$(grep -o "publishVersion=.*" $1/build.properties | awk -F '=' '{print $2}')
echo "< $1/build.properties publishVersion : ${PUBLISH_VERSION} >" echo "< $1/build.properties publishVersion : ${PUBLISH_VERSION} >"
## 设新的 WinBoLL 标签 ## 设新的 WinBoll 标签
# 脚本调试时使用 # 脚本调试时使用
#tag="v7.6.4-test1" #tag="v7.6.4-test1"
# 正式调试版设置标签时使用 # 正式调试版设置标签时使用
tag=$1"-v"${PUBLISH_VERSION}"-debug" tag=$1"-v"${PUBLISH_VERSION}"-debug"
echo "< WinBoLL Tag To: $tag >"; echo "< WinBoll Tag To: $tag >";
# 检查是否已经添加了 WinBoLL Tag # 检查是否已经添加了 WinBoll Tag
if [ "$(git tag -l ${tag})" == "${tag}" ]; then if [ "$(git tag -l ${tag})" == "${tag}" ]; then
echo -e "< WinBoLL Tag ${tag} exist! >" echo -e "< WinBoll Tag ${tag} exist! >"
return 1 # WinBoLL标签重复 return 1 # WinBoll标签重复
fi fi
# 添加WinBoLL标签 # 添加WinBoll标签
git tag -a ${tag} -F $1/app_update_description.txt git tag -a ${tag} -F $1/app_update_description.txt
return 0 return 0
} }
@@ -119,22 +119,22 @@ if [[ $? -eq 0 ]]; then
echo $result echo $result
# 发布应用 # 发布应用
echo "Publishing WinBoLL Debug APK ..." echo "Publishing WinBoll Debug APK ..."
# 脚本调试时使用 # 脚本调试时使用
#bash gradlew :$1:assembleBetaDebug #bash gradlew :$1:assembleBetaDebug
# 正式发布调试版 # 正式发布调试版
bash gradlew :$1:assembleStageDebug bash gradlew :$1:assembleStageDebug
echo "Publishing WinBoLL Debug APK OK." echo "Publishing WinBoll Debug APK OK."
# 添加 WinBoLL 标签 # 添加 WinBoll 标签
result=$(addWinBoLLTag $1) result=$(addWinBollTag $1)
echo $result echo $result
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo $result echo $result
# WinBoLL 标签添加成功 # WinBoll 标签添加成功
else else
echo -e "${0}: addWinBoLLTag $1\n${result}\nAdd WinBoLL tag cancel." echo -e "${0}: addWinBollTag $1\n${result}\nAdd WinBoll tag cancel."
exit 1 # addWinBoLLTag 异常 exit 1 # addWinBollTag 异常
fi fi
# 添加 GitHub 工作流标签 # 添加 GitHub 工作流标签

View File

@@ -8,7 +8,7 @@ if [ -z "$1" ]; then
fi fi
## 正式发布使用 ## 正式发布使用
git pull && bash gradlew :$1:publishReleasePublicationToWinBoLLReleaseRepository && bash .winboll/bashCommitLibReleaseBuildFlagInfo.sh $1 git pull && bash gradlew :$1:publishReleasePublicationToWinBollReleaseRepository && bash .winboll/bashCommitLibReleaseBuildFlagInfo.sh $1
## 调试使用 ## 调试使用
#bash gradlew :$1:publishSnapshotWinBoLLPublicationToWinBoLLSnapshotRepository && bash .winboll/bashCommitLibReleaseBuildFlagInfo.sh $1 #bash gradlew :$1:publishSnapshotWinBollPublicationToWinBollSnapshotRepository && bash .winboll/bashCommitLibReleaseBuildFlagInfo.sh $1

View File

@@ -1,4 +1,4 @@
// WinBoLL 应用签名配置 // WinBoll 应用签名配置
// //
android { android {
@@ -31,18 +31,18 @@ android {
} }
} }
flavorDimensions "WinBoLLApp" flavorDimensions "WinBollApp"
productFlavors { productFlavors {
beta { beta {
// 检查编译标志位配置 // 检查编译标志位配置
assert (winbollBuildProps['buildCount'] != null) assert (winbollBuildProps['buildCount'] != null)
dimension "WinBoLLApp" dimension "WinBollApp"
applicationIdSuffix ".beta" applicationIdSuffix ".beta"
LocalDateTime localDateTimeNow = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); LocalDateTime localDateTimeNow = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
versionNameSuffix "-beta" + winbollBuildProps['buildCount'] + "_" + localDateTimeNow.format('mmss') versionNameSuffix "-beta" + winbollBuildProps['buildCount'] + "_" + localDateTimeNow.format('mmss')
} }
stage { stage {
dimension "WinBoLLApp" dimension "WinBollApp"
} }
} }
@@ -61,7 +61,7 @@ android {
} }
// //
// WinBoLL 应用包输出配置 // WinBoll 应用包输出配置
// 1. 配置 Stage Release 版应用包输出 // 1. 配置 Stage Release 版应用包输出
// 2. 配置 Beta Debug 版应用包输出 // 2. 配置 Beta Debug 版应用包输出
// //
@@ -74,13 +74,13 @@ android {
//def outputFileName="${rootProject.name}_${versionName}.apk" //def outputFileName="${rootProject.name}_${versionName}.apk"
def outputFileName=project.rootDir.name + "_${versionName}.apk" def outputFileName=project.rootDir.name + "_${versionName}.apk"
// 创建 WinBoLL Studio 发布接口文件夹 // 创建 WinBoll Studio 发布接口文件夹
File fWinBoLLStudioDir = file("/sdcard/WinBoLLStudio/APKs"); File fWinBoLLStudioDir = file("/sdcard/WinBoLLStudio/APKs");
if(!fWinBoLLStudioDir.exists()) { if(!fWinBoLLStudioDir.exists()) {
//fWinBoLLStudioDir.mkdirs(); //fWinBoLLStudioDir.mkdirs();
// 如果没有发布接口文件就不用进行APK发布和源码管理操作 // 如果没有发布接口文件就不用进行APK发布和源码管理操作
// 当前编译环境不是 WinBoLL 主机, 以下将忽略APK发布和源码管理操作。 // 当前编译环境不是 WinBoll 主机, 以下将忽略APK发布和源码管理操作。
println 'The current compilation environment is not in WinBoLL host, and the following APK publishing and source management operations will be ignore.' println 'The current compilation environment is not in WinBoll host, and the following APK publishing and source management operations will be ignore.'
} else { } else {
/// WINBOLL 主机的 APK 发布和源码管理操作 /// /// WINBOLL 主机的 APK 发布和源码管理操作 ///
variant.getAssembleProvider().get().doFirst { variant.getAssembleProvider().get().doFirst {
@@ -91,7 +91,7 @@ android {
// //
variant.getAssembleProvider().get().doLast { variant.getAssembleProvider().get().doLast {
variant.outputs.forEach{ file-> variant.outputs.forEach{ file->
// 如果正在调试,就拷贝到 WinBoLL 备份管理文件夹 // 如果正在调试,就拷贝到 WinBoll 备份管理文件夹
// //
if(variant.flavorName == "beta"&&variant.buildType.name == "debug"){ if(variant.flavorName == "beta"&&variant.buildType.name == "debug"){
//File outBuildBckDir = new File(fWinBoLLStudioDir, "/${rootProject.name}/${variant.buildType.name}") //File outBuildBckDir = new File(fWinBoLLStudioDir, "/${rootProject.name}/${variant.buildType.name}")
@@ -137,7 +137,7 @@ android {
} }
} }
// 如果正在发布,就拷贝到 WinBoLL 标签管理文件夹 // 如果正在发布,就拷贝到 WinBoll 标签管理文件夹
// //
if((variant.flavorName == "stage"&&variant.buildType.name == "debug") if((variant.flavorName == "stage"&&variant.buildType.name == "debug")
|| (variant.flavorName == "stage"&&variant.buildType.name == "release")){ || (variant.flavorName == "stage"&&variant.buildType.name == "release")){

View File

@@ -1,4 +1,4 @@
// 本机和 WinBoLL Maven 仓库传输配置。 // 本机和 WinBoll Maven 仓库传输配置。
// //
def getDefaultVersion(){ def getDefaultVersion(){
@@ -9,7 +9,7 @@ def getDefaultVersion(){
} }
def siteUrl = 'https://winboll.cc/?page=studio/details.php&app=${rootProject.name}' // 项目主页 def siteUrl = 'https://winboll.cc/?page=studio/details.php&app=${rootProject.name}' // 项目主页
def gitUrl = 'https://gitea.winboll.cc/WinBoLL/${rootProject.name}' // 项目的git地址 def gitUrl = 'https://gitea.winboll.cc/WinBoll/${rootProject.name}' // 项目的git地址
def DefaultGroupId = 'cc.winboll.studio' // 类库所有者groupId def DefaultGroupId = 'cc.winboll.studio' // 类库所有者groupId
def DefaultVersion = getDefaultVersion() // 版本号 def DefaultVersion = getDefaultVersion() // 版本号
def DeveloperId='zhangsken' // 开发者账号 def DeveloperId='zhangsken' // 开发者账号
@@ -27,10 +27,10 @@ afterEvaluate {
properties.load(file("${RootProjectDir}/${winbollFilePath}").newDataInputStream()) properties.load(file("${RootProjectDir}/${winbollFilePath}").newDataInputStream())
def NexusUserName = properties.getProperty("Nexus.name") def NexusUserName = properties.getProperty("Nexus.name")
def NexusPassword = properties.getProperty("Nexus.password") def NexusPassword = properties.getProperty("Nexus.password")
// WinBoLL Release 仓库 // WinBoll Release 仓库
maven{ maven{
//仓库的名字和地址 //仓库的名字和地址
name = "WinBoLLRelease" name = "WinBollRelease"
url="https://nexus.winboll.cc/repository/maven-releases/" url="https://nexus.winboll.cc/repository/maven-releases/"
// 仓库用户名密码 // 仓库用户名密码
credentials { credentials {
@@ -38,10 +38,10 @@ afterEvaluate {
password = NexusPassword password = NexusPassword
} }
} }
// WinBoLL Snapshot 仓库 // WinBoll Snapshot 仓库
maven{ maven{
//仓库的名字和地址 //仓库的名字和地址
name = "WinBoLLSnapshot" name = "WinBollSnapshot"
url="https://nexus.winboll.cc/repository/maven-snapshots/" url="https://nexus.winboll.cc/repository/maven-snapshots/"
// 仓库用户名密码 // 仓库用户名密码
credentials { credentials {
@@ -101,9 +101,9 @@ afterEvaluate {
} }
} }
// WinBoLL Maven Release 仓库传输任务 // WinBoll Maven Release 仓库传输任务
// //
releaseWinBoLL(MavenPublication) { releaseWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个 // 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free //from components.free
@@ -154,9 +154,9 @@ afterEvaluate {
} // 创建名为 release 的任务结束 } // 创建名为 release 的任务结束
// WinBoLL Maven Snapshot 仓库传输任务 // WinBoll Maven Snapshot 仓库传输任务
// //
snapshotWinBoLL(MavenPublication) { snapshotWinBoll(MavenPublication) {
// 需要使用的变体假设有free和pay两个变体可以选择一个 // 需要使用的变体假设有free和pay两个变体可以选择一个
//from components.free //from components.free

120
README.md
View File

@@ -1,23 +1,23 @@
# ☁ ☁ ☁ WinBoLL APP ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ # ☁ ☁ ☁ WinBoll APP ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁
# ☁ ☁ WinBoLL Studio Android 应用开源项目。☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ # ☁ ☁ 这是 WinBoll 系列 APP 汇总项目。☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁
# ☁ ☁ ☁ WinBoLL 网站地址 https://www.winboll.cc/ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ # ☁ ☁ ☁ WinBoll 网站地址 https://www.winboll.cc/studio/app/ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁
## WinBoLL 提问 ## WinBoll 提问
同样是 /sdcard 目录,在开发 Android 应用时, 同样是 /sdcard 目录,在开发 Android 应用时,
能否实现手机编译与电脑编译的源码同步。 能否实现手机编译与电脑编译的源码同步。
☁因而 WinBoLL 项目组诞生了。 ☁因而 WinBoll 项目组诞生了。
## WinBoLL 项目组研发计划 ## WinBoll 项目组研发计划
致力于把 WinBoLL-APP 应用在手机端 Android 项目开发。 致力于把 WinBoll-APP 应用在手机端 Android 项目开发。
也在探索 https://gitea.winboll.cc/<WinBoLL 项目组>/APP.git 应用于 WinBoLL-APP APK 分发。 也在探索 https://gitea.winboll.cc/<WinBoll 项目组>/APP.git 应用于 WinBoll-APP APK 分发。
更想进阶 https://github.com/<WinBoLL 项目组>/APP.git 应用于 WinBoLL-APP Beta APK 分发。 更想进阶 https://github.com/<WinBoll 项目组>/APP.git 应用于 WinBoll-APP Beta APK 分发。
## WinBoLL-APP 汗下... ## WinBoll-APP 汗下...
#### ☁应用何置如此呢。且观用户云云。 #### ☁应用何置如此呢。且观用户云云。
#### ☁ 正当下 ☁ ### #### ☁ 正当下 ☁ ###
#### ☁ 且容傻家叙说 ☁ WinBoLL-APP 应用场景 #### ☁ 且容傻家叙说 ☁ WinBoll-APP 应用场景
### ☁ WinBoLL 设备资源概述 ### ☁ WinBoll 设备资源概述
#### ☁ 1. Raid Disk. #### ☁ 1. Raid Disk.
概述:这是一个矩阵存储类设备。 概述:这是一个矩阵存储类设备。
优点:该设备具有数据容错存储功能, 优点:该设备具有数据容错存储功能,
@@ -40,58 +40,58 @@
设备位于操作系统内部文件系统。 设备位于操作系统内部文件系统。
数据持久性与操作系统挂钩。 数据持久性与操作系统挂钩。
#### ☁ 4. WinBoLL 用户资源概述。 #### ☁ 4. WinBoll 用户资源概述。
1> /home/<用户名> 位于 WinBoLL 操作系统目录下。 1> /home/<用户名> 位于 WinBoll 操作系统目录下。
2> /rdisk/<用户名> 挂载用户 Raid Disk. 2> /rdisk/<用户名> 挂载用户 Raid Disk.
3> /data/<用户名> 挂载用户 Data Disk. 3> /data/<用户名> 挂载用户 Data Disk.
4> /sdcard/<用户名> 挂载用户 SSD Disk. 4> /sdcard/<用户名> 挂载用户 SSD Disk.
#### ☁ 5. WinBoLL-APP 用户资源概述。 #### ☁ 5. WinBoll-APP 用户资源概述。
1> /sdcard 挂载用户手机 SD 存储/storage/emulated/0 1> /sdcard 挂载用户手机 SD 存储/storage/emulated/0
### ☁ 稍稍歇 ☁ ### ### ☁ 稍稍歇 ☁ ###
### ☁ 急急停 ☁ WinBoLL 应用前置条件 ### ☁ 急急停 ☁ WinBoll 应用前置条件
☁ WinBoLL 主机建立 1Panel MySQL 应用。 ☁ WinBoll 主机建立 1Panel MySQL 应用。
☁ WinBoLL 主机建立 1Panel Gitea 应用。 ☁ WinBoll 主机建立 1Panel Gitea 应用。
☁ WinBoLL 主机设置 WinBoLL 应用为非登录状态。 ☁ WinBoll 主机设置 WinBoll 应用为非登录状态。
☁ WinBoLL 主机建立 WinBoLL 账户与 WinBoLL 用户组。 ☁ WinBoll 主机建立 WinBoll 账户与 WinBoll 用户组。
☁ WinBoLL 账户 User ID 为: J。 ☁ WinBoll 账户 User ID 为: J。
☁ WinBoLL 用户组 Group ID 为: Studio。 ☁ WinBoll 用户组 Group ID 为: Studio。
☁ WinBoLL 主机 WinBoLL 1Panel Gitea 建立 WinBoLL 工作组。 ☁ WinBoll 主机 WinBoll 1Panel Gitea 建立 WinBoll 工作组。
☁ WinBoLL 主机 WinBoLL 1Panel Gitea 用户项目 APK 编译输出目录为 /sdcard/WinBoLLStudio/<用户名>/APKs/ ☁ WinBoll 主机 WinBoll 1Panel Gitea 用户项目 APK 编译输出目录为 /sdcard/WinBollStudio/<用户名>/APKs/
☁ WinBoLL 项目配置文件示例为 "<WinBoLL 项目根目录>/.winboll/winboll.properties-demo"(WinBoLL 项目已设置) ☁ WinBoll 项目配置文件示例为 "<WinBoll 项目根目录>/.winboll/winboll.properties-demo"(WinBoll 项目已设置)
☁ WinBoLL 项目配置文件为 "<WinBoLL 项目根目录>/.winboll/winboll.properties" ☁ WinBoll 项目配置文件为 "<WinBoll 项目根目录>/.winboll/winboll.properties"
☁ WinBoLL 项目配置文件设定为源码提交时忽略。(WinBoLL 项目已设置) ☁ WinBoll 项目配置文件设定为源码提交时忽略。(WinBoll 项目已设置)
☁ Gradle 项目配置文件示例为 "<WinBoLL 项目根目录>/.winboll/local.properties-demo"(WinBoLL 项目已设置) ☁ Gradle 项目配置文件示例为 "<WinBoll 项目根目录>/.winboll/local.properties-demo"(WinBoll 项目已设置)
☁ Gradle 项目配置文件为 "<WinBoLL 项目根目录>/local.properties"(WinBoLL 项目已设置) ☁ Gradle 项目配置文件为 "<WinBoll 项目根目录>/local.properties"(WinBoll 项目已设置)
☁ Gradle 项目配置文件设定为源码提交时忽略。(WinBoLL 项目已设置) ☁ Gradle 项目配置文件设定为源码提交时忽略。(WinBoll 项目已设置)
### ☁ 登高处 ☁ WinBoLL 应用需求规划 ### ☁ 登高处 ☁ WinBoll 应用需求规划
☁ WinBoLL 主机建立 WinBoLL 客户端用户数据库为 MySQL winbollclient 数据库。 ☁ WinBoll 主机建立 WinBoll 客户端用户数据库为 MySQL winbollclient 数据库。
☁ WinBoLL 主机设置 WinBoLL 客户端用户信息存储在 winbollclient 数据库中。 ☁ WinBoll 主机设置 WinBoll 客户端用户信息存储在 winbollclient 数据库中。
☁ MySQL winbollclient 数据库中 ☁ MySQL winbollclient 数据库中
WinBoLL 客户端用户信息设定为: WinBoll 客户端用户信息设定为:
<用户名, 验证密码, 验证邮箱, 验证手机, 唯一存储令牌Token, 备用验证邮箱>。 <用户名, 验证密码, 验证邮箱, 验证手机, 唯一存储令牌Token, 备用验证邮箱>。
☁ WinBoLL 项目源码仓库托管在 WinBoLL 1Panel Gitea 目录 /opt/1panel/apps/gitea/gitea/data/git/repositories/studio/app.git中。 ☁ WinBoll 项目源码仓库托管在 WinBoll 1Panel Gitea 目录 /opt/1panel/apps/gitea/gitea/data/git/repositories/studio/app.git中。
☁ WinBoLL 主机提供 WinBoLL 1Panel Gitea 应用的 WinBoLL 项目源码仓库存取功能。Gitea 应用已提供) ☁ WinBoll 主机提供 WinBoll 1Panel Gitea 应用的 WinBoll 项目源码仓库存取功能。Gitea 应用已提供)
☁ WinBoLL 主机提供 WinBoLL Gitea 项目仓库存档功能。Gitea 应用已提供) ☁ WinBoll 主机提供 WinBoll Gitea 项目仓库存档功能。Gitea 应用已提供)
☁ 提供 WinBoLL 客户端用户登录功能。Gitea 应用已提供) ☁ 提供 WinBoll 客户端用户登录功能。Gitea 应用已提供)
### ☁ 看远方 ☁ ### ### ☁ 看远方 ☁ ###
### ☁ 心忧虑 ☁ WinBoLL-APP 应用前置需求 ### ☁ 心忧虑 ☁ WinBoll-APP 应用前置需求
☁ WinBoLL-APP WinBoLL 项目根目录设定为手机的 /sdcard/WinBoLLStudio/Sources 目录。(需要用户手动建立文件夹) ☁ WinBoll-APP WinBoll 项目根目录设定为手机的 /sdcard/WinBollStudio/Sources 目录。(需要用户手动建立文件夹)
☁ WinBoLL-APP 具有手机 /sdcard/WinBoLL 目录的存储权限。(需要手机操作系统授权) ☁ WinBoll-APP 具有手机 /sdcard/WinBoll 目录的存储权限。(需要手机操作系统授权)
☁ WinBoLL-APP WinBoLL 项目仓库源码存储路径为 /sdcard/WinBoLLStudio/Sources/APP.git需要用户手动建立文件夹 ☁ WinBoll-APP WinBoll 项目仓库源码存储路径为 /sdcard/WinBollStudio/Sources/APP.git需要用户手动建立文件夹
☁ WinBoLL-APP 项目 APK 编译输出目录为 /sdcard/WinBoLLStudio/APKs/ ☁ WinBoll-APP 项目 APK 编译输出目录为 /sdcard/WinBollStudio/APKs/
☁ WinBoLL-APP 应用签名验证可定制化。WinBoLL 项目已提供) ☁ WinBoll-APP 应用签名验证可定制化。WinBoll 项目已提供)
☁ WinBoLL-APP 与系列衍生 APP 应用共享 cc.winboll.studio 命名空间资源。WinBoLL 项目已提供) ☁ WinBoll-APP 与系列衍生 APP 应用共享 cc.winboll.studio 命名空间资源。WinBoll 项目已提供)
☁ WinBoLL-APP 用户客户端信息存储在命名空间为 WinBoLL APP MySQLLite 应用的 winbollappclient 数据库中。 ☁ WinBoll-APP 用户客户端信息存储在命名空间为 WinBoll APP MySQLLite 应用的 winbollappclient 数据库中。
☁ WinBoLL-APP MySQLLite 应用的 winbollappclient 数据库中, ☁ WinBoll-APP MySQLLite 应用的 winbollappclient 数据库中,
WinBoLL 用户客户端信息设定为: WinBoll 用户客户端信息设定为:
<用户名, 唯一存储令牌Token>。 <用户名, 唯一存储令牌Token>。
### ☁ 云游四方 ☁ ### ### ☁ 云游四方 ☁ ###
### ☁ 呔! ☁ WinBoLL-APP 应用需求规划 ### ☁ 呔! ☁ WinBoll-APP 应用需求规划
☁ 如要使用 WinBoLL Android 项目的 Gradle 编译功能,则需要设置以下两个文件夹。 ☁ 如要使用 WinBoLL Android 项目的 Gradle 编译功能,则需要设置以下两个文件夹。
☁ 1. 则需要建立数据存储目录 /sdcard/WinBoLLStudio/APKs。 ☁ 1. 则需要建立数据存储目录 /sdcard/WinBoLLStudio/APKs。
WinBoLL 项目源码编译出来的安装包会拷贝一份到 /sdcard/WinBoLLStudio/APKs 目录下。 WinBoLL 项目源码编译出来的安装包会拷贝一份到 /sdcard/WinBoLLStudio/APKs 目录下。
@@ -99,20 +99,20 @@
WinBoLL 项目源码编译出来的安装包会拷贝一份并命名 "app.apk" 的安装文件为到 /sdcard/AppProjects 目录下。 WinBoLL 项目源码编译出来的安装包会拷贝一份并命名 "app.apk" 的安装文件为到 /sdcard/AppProjects 目录下。
### ☁ 吁! ☁ WinBoLL-APP 共享计划前景 ### ☁ 吁! ☁ WinBoll-APP 共享计划前景
☁ WinBoLL-APP 将会实现 https://winboll.cc/api 访问功能。 ☁ WinBoll-APP 将会实现 https://winboll.cc/api 访问功能。
☁ WinBoLL-APP 将会实现手机端 Android 应用的开发与管理功能。 ☁ WinBoll-APP 将会实现手机端 Android 应用的开发与管理功能。
## ☁ WinBoLL ☁ WinBoLL 主机忧虑 ## ☁ WinBoll ☁ WinBoll 主机忧虑
☁ WinBoLL 将会提供 gitea.winboll.cc 域名用户注册登录功能。 ☁ WinBoll 将会提供 gitea.winboll.cc 域名用户注册登录功能。
☁ WinBoLL 将会提供 WinBoLL-APP 及其衍生应用的 Gitea 仓库管理服务。 ☁ WinBoll 将会提供 WinBoll-APP 及其衍生应用的 Gitea 仓库管理服务。
☁ WinBoLL 将会提供 winboll.cc 域名 WinBoLL 项目组注册登录功能。 ☁ WinBoll 将会提供 winboll.cc 域名 WinBoll 项目组注册登录功能。
# 本项目要实际运用需要注意以下几个步骤: # 本项目要实际运用需要注意以下几个步骤:
# 在项目根目录下: # 在项目根目录下:
## 1. 项目模块编译环境设置(必须)settings.gradle-demo 要复制为 settings.gradle并取消相应项目模块的注释。 ## 1. 项目模块编译环境设置(必须)settings.gradle-demo 要复制为 settings.gradle并取消相应项目模块的注释。
## 2. 项目 Android SDK 编译环境设置(可选)local.properties-demo 要复制为 local.properties并按需要设置 Android SDK 目录。 ## 2. 项目 Android SDK 编译环境设置(可选)local.properties-demo 要复制为 local.properties并按需要设置 Android SDK 目录。
## 3. 类库型模块编译环境设置(可选)winboll.properties-demo 要复制为 winboll.properties并按需要设置 WinBoLL Maven 库登录用户信息。 ## 3. 类库型模块编译环境设置(可选)winboll.properties-demo 要复制为 winboll.properties并按需要设置 WinBoll Maven 库登录用户信息。
# ☆类库型项目编译方法 # ☆类库型项目编译方法
@@ -121,12 +121,12 @@
设置属性 libraryProject=<类库项目模块文件夹名称> 设置属性 libraryProject=<类库项目模块文件夹名称>
### 再编译测试项目 ### 再编译测试项目
$ bash .winboll/bashPublishAPKAddTag.sh <应用项目模块文件夹名称> $ bash .winboll/bashPublishAPKAddTag.sh <应用项目模块文件夹名称>
#### 测试项目编译后,编译器会复制一份 APK 到以下路径:"/sdcard/WinBoLLStudio/APKs/<项目根目录名称>/tag/" 文件夹。 #### 测试项目编译后,编译器会复制一份 APK 到以下路径:"/sdcard/WinBollStudio/APKs/<项目根目录名称>/tag/" 文件夹。
### 最后编译类库项目 ### 最后编译类库项目
$ bash .winboll/bashPublishLIBAddTag.sh <类库项目模块文件夹名称> $ bash .winboll/bashPublishLIBAddTag.sh <类库项目模块文件夹名称>
#### 类库模块编译命令执行后,编译器会发布到 WinBoLL Nexus Maven 库Maven 库地址可以参阅根项目目录配置 build.gradle 文件。 #### 类库模块编译命令执行后,编译器会发布到 WinBoll Nexus Maven 库Maven 库地址可以参阅根项目目录配置 build.gradle 文件。
# ☆应用型项目编译方法 # ☆应用型项目编译方法
## 直接调用以下命令编译应用型项目 ## 直接调用以下命令编译应用型项目
$ bash .winboll/bashPublishAPKAddTag.sh <应用项目模块文件夹名称> $ bash .winboll/bashPublishAPKAddTag.sh <应用项目模块文件夹名称>
#### 应用模块编译命令执行后,编译器会复制一份 APK 到以下路径:"/sdcard/WinBoLLStudio/APKs/<项目根目录名称>/tag/" 文件夹。 #### 应用模块编译命令执行后,编译器会复制一份 APK 到以下路径:"/sdcard/WinBollStudio/APKs/<项目根目录名称>/tag/" 文件夹。

View File

@@ -24,12 +24,12 @@ android {
defaultConfig { defaultConfig {
applicationId "cc.winboll.studio.aes" applicationId "cc.winboll.studio.aes"
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 29
versionCode 1 versionCode 1
// versionName 更新后需要手动设置 // versionName 更新后需要手动设置
// 项目模块目录的 build.gradle 文件的 stageCount=0 // 项目模块目录的 build.gradle 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.6" versionName "15.2"
if(true) { if(true) {
versionName = genVersionName("${versionName}") versionName = genVersionName("${versionName}")
} }

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Mon May 12 18:10:35 HKT 2025 #Thu Apr 03 11:14:05 HKT 2025
stageCount=4 stageCount=7
libraryProject=libaes libraryProject=libaes
baseVersion=15.6 baseVersion=15.2
publishVersion=15.6.3 publishVersion=15.2.6
buildCount=0 buildCount=0
baseBetaVersion=15.6.4 baseBetaVersion=15.2.7

View File

@@ -15,9 +15,9 @@ import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libaes.winboll.APPInfo; import cc.winboll.studio.libaes.winboll.APPInfo;
import cc.winboll.studio.libaes.winboll.AboutView; import cc.winboll.studio.libaes.winboll.AboutView;
import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
public class AboutActivity extends AppCompatActivity implements IWinBoLLActivity { public class AboutActivity extends WinBollActivity implements IWinBollActivity {
public static final String TAG = "AboutActivity"; public static final String TAG = "AboutActivity";
@@ -64,13 +64,13 @@ public class AboutActivity extends AppCompatActivity implements IWinBoLLActivity
); );
layout.addView(aboutView, params); layout.addView(aboutView, params);
GlobalApplication.getWinBoLLActivityManager().add(this); GlobalApplication.getWinBollActivityManager().add(this);
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
GlobalApplication.getWinBoLLActivityManager().registeRemove(this); GlobalApplication.getWinBollActivityManager().registeRemove(this);
} }
public AboutView CreateAboutView() { public AboutView CreateAboutView() {

View File

@@ -8,7 +8,6 @@ package cc.winboll.studio.aes;
import android.view.Gravity; import android.view.Gravity;
import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.libappbase.GlobalApplication;
import com.hjq.toast.ToastUtils; import com.hjq.toast.ToastUtils;
import com.hjq.toast.style.WhiteToastStyle;
public class App extends GlobalApplication { public class App extends GlobalApplication {
@@ -22,8 +21,8 @@ public class App extends GlobalApplication {
// 初始化 Toast 框架 // 初始化 Toast 框架
ToastUtils.init(this); ToastUtils.init(this);
// 设置 Toast 布局样式 // 设置 Toast 布局样式
//ToastUtils.setView(R.layout.view_toast); ToastUtils.setView(R.layout.view_toast);
ToastUtils.setStyle(new WhiteToastStyle()); //ToastUtils.setStyle(new WhiteToastStyle());
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200); ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
} }

View File

@@ -25,12 +25,12 @@ import cc.winboll.studio.libaes.unittests.TestAToolbarActivity;
import cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity; import cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity;
import cc.winboll.studio.libaes.unittests.TestViewPageFragment; import cc.winboll.studio.libaes.unittests.TestViewPageFragment;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import com.a4455jkjh.colorpicker.ColorPickerDialog; import com.a4455jkjh.colorpicker.ColorPickerDialog;
import com.hjq.toast.ToastUtils; import com.hjq.toast.ToastUtils;
import java.util.ArrayList; import java.util.ArrayList;
public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActivity { public class MainActivity extends DrawerFragmentActivity implements IWinBollActivity {
public static final String TAG = "MainActivity"; public static final String TAG = "MainActivity";
@@ -123,7 +123,7 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
int nItemId = item.getItemId(); int nItemId = item.getItemId();
// if (item.getItemId() == R.id.item_log) { // if (item.getItemId() == R.id.item_log) {
// WinBoLLActivityManager.getInstance(this).startWinBoLLActivity(getApplicationContext(), LogActivity.class); // WinBollActivityManager.getInstance(this).startWinBollActivity(getApplicationContext(), LogActivity.class);
// } else // } else
if (nItemId == R.id.item_atoast) { if (nItemId == R.id.item_atoast) {
Toast.makeText(getApplication(), "item_testatoast", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplication(), "item_testatoast", Toast.LENGTH_SHORT).show();

View File

@@ -0,0 +1,60 @@
package cc.winboll.studio.aes;
import android.app.Activity;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import cc.winboll.studio.libaes.beans.AESThemeBean;
import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import android.view.MenuItem;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/30 00:34:02
* @Describe WinBoll 活动窗口通用基类
*/
public class WinBollActivity extends AppCompatActivity implements IWinBollActivity {
public static final String TAG = "WinBollActivity";
protected volatile AESThemeBean.ThemeType mThemeType;
@Override
public Activity getActivity() {
return this;
}
@Override
public String getTag() {
return TAG;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
mThemeType = getThemeType();
setThemeStyle();
super.onCreate(savedInstanceState);
}
AESThemeBean.ThemeType getThemeType() {
/*SharedPreferences sharedPreferences = getSharedPreferences(
SHAREDPREFERENCES_NAME, MODE_PRIVATE);
return AESThemeBean.ThemeType.values()[((sharedPreferences.getInt(DRAWER_THEME_TYPE, AESThemeBean.ThemeType.DEFAULT.ordinal())))];
*/
return AESThemeBean.getThemeStyleType(AESThemeUtil.getThemeTypeID(getApplicationContext()));
}
void setThemeStyle() {
//setTheme(AESThemeBean.getThemeStyle(getThemeType()));
setTheme(AESThemeUtil.getThemeTypeID(getApplicationContext()));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -25,12 +25,12 @@ android {
defaultConfig { defaultConfig {
applicationId "cc.winboll.studio.appbase" applicationId "cc.winboll.studio.appbase"
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 29
versionCode 1 versionCode 1
// versionName 更新后需要手动设置 // versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0 // .winboll/winbollBuildProps.properties 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.7" versionName "15.2"
if(true) { if(true) {
versionName = genVersionName("${versionName}") versionName = genVersionName("${versionName}")
} }

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sat May 03 10:32:21 GMT 2025 #Sun Apr 27 00:07:35 GMT 2025
stageCount=7 stageCount=7
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.7 baseVersion=15.2
publishVersion=15.7.6 publishVersion=15.2.6
buildCount=4 buildCount=0
baseBetaVersion=15.7.7 baseBetaVersion=15.2.7

View File

@@ -5,7 +5,7 @@
<application <application
android:name=".App" android:name=".App"
android:icon="@drawable/ic_miapp" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/MyAPPBaseTheme" android:theme="@style/MyAPPBaseTheme"
android:resizeableActivity="true" android:resizeableActivity="true"

View File

@@ -4,11 +4,11 @@ import android.app.Activity;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.Toolbar;
import cc.winboll.studio.appbase.R; import cc.winboll.studio.appbase.R;
import cc.winboll.studio.appbase.activities.NewActivity; import cc.winboll.studio.appbase.activities.NewActivity;
import cc.winboll.studio.appbase.services.MainService; import cc.winboll.studio.appbase.services.MainService;
@@ -21,9 +21,9 @@ import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.SOS; import cc.winboll.studio.libappbase.sos.SOS;
import cc.winboll.studio.libappbase.utils.ToastUtils; import cc.winboll.studio.libappbase.utils.ToastUtils;
import cc.winboll.studio.libappbase.widgets.StatusWidget; import cc.winboll.studio.libappbase.widgets.StatusWidget;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
public class MainActivity extends WinBoLLActivityBase implements IWinBoLLActivity { public class MainActivity extends WinBoLLActivity implements IWinBollActivity {
public static final String TAG = "MainActivity"; public static final String TAG = "MainActivity";
@@ -47,7 +47,7 @@ public class MainActivity extends WinBoLLActivityBase implements IWinBoLLActivit
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
mToolbar = findViewById(R.id.toolbar); mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar); setSupportActionBar(mToolbar);
CheckBox cbIsDebugMode = findViewById(R.id.activitymainCheckBox1); CheckBox cbIsDebugMode = findViewById(R.id.activitymainCheckBox1);
cbIsDebugMode.setChecked(GlobalApplication.isDebuging()); cbIsDebugMode.setChecked(GlobalApplication.isDebuging());
@@ -176,7 +176,7 @@ public class MainActivity extends WinBoLLActivityBase implements IWinBoLLActivit
} }
public void onTestOpenNewActivity(View view) { public void onTestOpenNewActivity(View view) {
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, NewActivity.class); GlobalApplication.getWinBollActivityManager().startWinBollActivity(this, NewActivity.class);
} }

View File

@@ -0,0 +1,86 @@
package cc.winboll.studio.appbase;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/28 15:34:16
* @Describe 应用活动窗口基类
*/
import android.app.Activity;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.widget.Toast;
import cc.winboll.studio.appbase.App;
import cc.winboll.studio.appbase.R;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog;
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import cc.winboll.studio.libappbase.winboll.WinBollActivityManager;
public class WinBoLLActivity extends AppCompatActivity implements IWinBollActivity {
public static final String TAG = "WinBollActivityBase";
@Override
public Activity getActivity() {
return this;
}
@Override
public String getTag() {
return TAG;
}
WinBollActivityManager getWinBollActivityManager() {
return WinBollActivityManager.getInstance(GlobalApplication.getInstance());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWinBollActivityManager().add(this);
}
@Override
public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_log) {
GlobalApplication.getWinBollActivityManager().startLogActivity(this);
return true;
} else if (item.getItemId() == cc.winboll.studio.libappbase.R.id.item_about) {
Toast.makeText(getApplication(), "item_about", Toast.LENGTH_SHORT).show();
return true;
} else if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_minimal) {
//moveTaskToBack(true);
exit();
}
// 在switch语句中处理每个ID并在处理完后返回true未处理的情况返回false。
return super.onOptionsItemSelected(item);
}
void exit() {
YesNoAlertDialog.show(this, "Exit " + getString(R.string.app_name), "Close all activity and exit?", new YesNoAlertDialog.OnDialogResultListener(){
@Override
public void onYes() {
App.getWinBollActivityManager().finishAll();
}
@Override
public void onNo() {
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
getWinBollActivityManager().registeRemove(this);
}
}

View File

@@ -7,16 +7,16 @@ package cc.winboll.studio.appbase.activities;
*/ */
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.Toolbar;
import cc.winboll.studio.appbase.R; import cc.winboll.studio.appbase.R;
import cc.winboll.studio.appbase.WinBoLLActivityBase; import cc.winboll.studio.appbase.WinBoLLActivity;
import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
public class New2Activity extends WinBoLLActivityBase implements IWinBoLLActivity { public class New2Activity extends WinBoLLActivity implements IWinBollActivity {
public static final String TAG = "New2Activity"; public static final String TAG = "New2Activity";
@@ -41,7 +41,7 @@ public class New2Activity extends WinBoLLActivityBase implements IWinBoLLActivit
// mLogView = findViewById(R.id.logview); // mLogView = findViewById(R.id.logview);
// mLogView.start(); // mLogView.start();
mToolbar = findViewById(R.id.toolbar); mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar); setSupportActionBar(mToolbar);
} }
@@ -52,15 +52,15 @@ public class New2Activity extends WinBoLLActivityBase implements IWinBoLLActivit
} }
public void onCloseThisActivity(View view) { public void onCloseThisActivity(View view) {
GlobalApplication.getWinBoLLActivityManager().finish(this); GlobalApplication.getWinBollActivityManager().finish(this);
} }
public void onCloseAllActivity(View view) { public void onCloseAllActivity(View view) {
GlobalApplication.getWinBoLLActivityManager().finishAll(); GlobalApplication.getWinBollActivityManager().finishAll();
} }
public void onNewActivity(View view) { public void onNewActivity(View view) {
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, NewActivity.class); GlobalApplication.getWinBollActivityManager().startWinBollActivity(this, NewActivity.class);
} }
@@ -74,7 +74,7 @@ public class New2Activity extends WinBoLLActivityBase implements IWinBoLLActivit
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_log) { if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_log) {
GlobalApplication.getWinBoLLActivityManager().startLogActivity(this); GlobalApplication.getWinBollActivityManager().startLogActivity(this);
return true; return true;
} }
// 在switch语句中处理每个ID并在处理完后返回true未处理的情况返回false。 // 在switch语句中处理每个ID并在处理完后返回true未处理的情况返回false。

View File

@@ -6,16 +6,16 @@ package cc.winboll.studio.appbase.activities;
*/ */
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.Toolbar;
import cc.winboll.studio.appbase.R; import cc.winboll.studio.appbase.R;
import cc.winboll.studio.appbase.WinBoLLActivityBase; import cc.winboll.studio.appbase.WinBoLLActivity;
import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
public class NewActivity extends WinBoLLActivityBase implements IWinBoLLActivity { public class NewActivity extends WinBoLLActivity implements IWinBollActivity {
public static final String TAG = "NewActivity"; public static final String TAG = "NewActivity";
@@ -39,7 +39,7 @@ public class NewActivity extends WinBoLLActivityBase implements IWinBoLLActivity
// mLogView = findViewById(R.id.logview); // mLogView = findViewById(R.id.logview);
// mLogView.start(); // mLogView.start();
mToolbar = findViewById(R.id.toolbar); mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar); setSupportActionBar(mToolbar);
} }
@@ -50,15 +50,15 @@ public class NewActivity extends WinBoLLActivityBase implements IWinBoLLActivity
} }
public void onCloseThisActivity(View view) { public void onCloseThisActivity(View view) {
GlobalApplication.getWinBoLLActivityManager().finish(this); GlobalApplication.getWinBollActivityManager().finish(this);
} }
public void onCloseAllActivity(View view) { public void onCloseAllActivity(View view) {
GlobalApplication.getWinBoLLActivityManager().finishAll(); GlobalApplication.getWinBollActivityManager().finishAll();
} }
public void onNew2Activity(View view) { public void onNew2Activity(View view) {
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, New2Activity.class); GlobalApplication.getWinBollActivityManager().startWinBollActivity(this, New2Activity.class);
} }
@@ -72,7 +72,7 @@ public class NewActivity extends WinBoLLActivityBase implements IWinBoLLActivity
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_log) { if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_log) {
GlobalApplication.getWinBoLLActivityManager().startLogActivity(this); GlobalApplication.getWinBollActivityManager().startLogActivity(this);
return true; return true;
} }
// 在switch语句中处理每个ID并在处理完后返回true未处理的情况返回false。 // 在switch语句中处理每个ID并在处理完后返回true未处理的情况返回false。

View File

@@ -1,49 +1,54 @@
package cc.winboll.studio.autoinstaller.models; package cc.winboll.studio.appbase.models;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/17 10:05:09
* @Describe APPSOSReportBean
*/
import android.util.JsonReader; import android.util.JsonReader;
import android.util.JsonWriter; import android.util.JsonWriter;
import cc.winboll.studio.libappbase.BaseBean; import cc.winboll.studio.libappbase.BaseBean;
import java.io.IOException; import java.io.IOException;
/** public class WinBollNewsBean extends BaseBean {
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/04/15 09:27:39 public static final String TAG = "WinBollNewsBean";
* @Describe MainServiceBean
*/ protected String message;
public class MainServiceBean extends BaseBean {
public WinBollNewsBean() {
public static final String TAG = "MainServiceBean"; this.message = "";
boolean isEnable;
public MainServiceBean() {
this.isEnable = false;
} }
public void setIsEnable(boolean isEnable) { public WinBollNewsBean(String message) {
this.isEnable = isEnable; this.message = message;
} }
public boolean isEnable() { public void setMessage(String message) {
return isEnable; this.message = message;
}
public String getMessage() {
return message;
} }
@Override @Override
public String getName() { public String getName() {
return MainServiceBean.class.getName(); return WinBollNewsBean.class.getName();
} }
@Override @Override
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
super.writeThisToJsonWriter(jsonWriter); super.writeThisToJsonWriter(jsonWriter);
jsonWriter.name("isEnable").value(isEnable()); jsonWriter.name("message").value(getMessage());
} }
@Override @Override
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException { public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else { if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
if (name.equals("isEnable")) { if (name.equals("message")) {
setIsEnable(jsonReader.nextBoolean()); setMessage(jsonReader.nextString());
} else { } else {
return false; return false;
} }

View File

@@ -10,7 +10,7 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import cc.winboll.studio.appbase.models.WinBoLLNewsBean; import cc.winboll.studio.appbase.models.WinBollNewsBean;
import cc.winboll.studio.appbase.services.MainService; import cc.winboll.studio.appbase.services.MainService;
import cc.winboll.studio.appbase.widgets.APPNewsWidget; import cc.winboll.studio.appbase.widgets.APPNewsWidget;
import cc.winboll.studio.libappbase.AppUtils; import cc.winboll.studio.libappbase.AppUtils;
@@ -18,7 +18,7 @@ import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.APPModel; import cc.winboll.studio.libappbase.sos.APPModel;
import cc.winboll.studio.libappbase.sos.SOS; import cc.winboll.studio.libappbase.sos.SOS;
import cc.winboll.studio.libappbase.sos.SOSObject; import cc.winboll.studio.libappbase.sos.SOSObject;
import cc.winboll.studio.libappbase.sos.WinBoLL; import cc.winboll.studio.libappbase.sos.WinBoll;
import cc.winboll.studio.libappbase.utils.ToastUtils; import cc.winboll.studio.libappbase.utils.ToastUtils;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@@ -42,11 +42,11 @@ public class MainReceiver extends BroadcastReceiver {
String szAction = intent.getAction(); String szAction = intent.getAction();
if (szAction.equals(ACTION_BOOT_COMPLETED)) { if (szAction.equals(ACTION_BOOT_COMPLETED)) {
ToastUtils.show("ACTION_BOOT_COMPLETED"); ToastUtils.show("ACTION_BOOT_COMPLETED");
} else if (szAction.equals(WinBoLL.ACTION_BIND)) { } else if (szAction.equals(WinBoll.ACTION_BIND)) {
LogUtils.d(TAG, "ACTION_BIND"); LogUtils.d(TAG, "ACTION_BIND");
LogUtils.d(TAG, String.format("context.getPackageName() %s", context.getPackageName())); LogUtils.d(TAG, String.format("context.getPackageName() %s", context.getPackageName()));
LogUtils.d(TAG, String.format("intent.getAction() %s", intent.getAction())); LogUtils.d(TAG, String.format("intent.getAction() %s", intent.getAction()));
String szAPPModel = intent.getStringExtra(WinBoLL.EXTRA_APPMODEL); String szAPPModel = intent.getStringExtra(WinBoll.EXTRA_APPMODEL);
LogUtils.d(TAG, String.format("szAPPModel %s", szAPPModel)); LogUtils.d(TAG, String.format("szAPPModel %s", szAPPModel));
if (szAPPModel != null && !szAPPModel.equals("")) { if (szAPPModel != null && !szAPPModel.equals("")) {
try { try {
@@ -80,7 +80,7 @@ public class MainReceiver extends BroadcastReceiver {
String appName = AppUtils.getAppNameByPackageName(context, szObjectPackageName); String appName = AppUtils.getAppNameByPackageName(context, szObjectPackageName);
LogUtils.d(TAG, String.format("appName %s", appName)); LogUtils.d(TAG, String.format("appName %s", appName));
WinBoLLNewsBean appWinBoLLNewsBean = new WinBoLLNewsBean(appName); WinBollNewsBean appWinBollNewsBean = new WinBollNewsBean(appName);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentTime = sdf.format(new Date()); String currentTime = sdf.format(new Date());
StringBuilder sbLine = new StringBuilder(); StringBuilder sbLine = new StringBuilder();
@@ -88,9 +88,9 @@ public class MainReceiver extends BroadcastReceiver {
sbLine.append(currentTime); sbLine.append(currentTime);
sbLine.append("] Power to "); sbLine.append("] Power to ");
sbLine.append(appName); sbLine.append(appName);
appWinBoLLNewsBean.setMessage(sbLine.toString()); appWinBollNewsBean.setMessage(sbLine.toString());
APPNewsWidget.addWinBoLLNewsBean(context, appWinBoLLNewsBean); APPNewsWidget.addWinBollNewsBean(context, appWinBollNewsBean);
Intent intentWidget = new Intent(context, APPNewsWidget.class); Intent intentWidget = new Intent(context, APPNewsWidget.class);
intentWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT); intentWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT);
@@ -110,7 +110,7 @@ public class MainReceiver extends BroadcastReceiver {
IntentFilter filter=new IntentFilter(); IntentFilter filter=new IntentFilter();
filter.addAction(ACTION_BOOT_COMPLETED); filter.addAction(ACTION_BOOT_COMPLETED);
filter.addAction(SOS.ACTION_SOS); filter.addAction(SOS.ACTION_SOS);
filter.addAction(WinBoLL.ACTION_BIND); filter.addAction(WinBoll.ACTION_BIND);
//filter.addAction(Intent.ACTION_BATTERY_CHANGED); //filter.addAction(Intent.ACTION_BATTERY_CHANGED);
service.registerReceiver(this, filter); service.registerReceiver(this, filter);
} }

View File

@@ -12,7 +12,7 @@ import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import cc.winboll.studio.appbase.models.TestDemoBindServiceBean; import cc.winboll.studio.appbase.models.TestDemoBindServiceBean;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.WinBoLL; import cc.winboll.studio.libappbase.sos.WinBoll;
import cc.winboll.studio.appbase.App; import cc.winboll.studio.appbase.App;
import cc.winboll.studio.libappbase.sos.SOS; import cc.winboll.studio.libappbase.sos.SOS;
@@ -156,9 +156,9 @@ public class TestDemoBindService extends Service {
super.run(); super.run();
LogUtils.d(TAG, "run() start"); LogUtils.d(TAG, "run() start");
if (App.isDebuging()) { if (App.isDebuging()) {
WinBoLL.bindToAPPBaseBeta(mContext, TestDemoBindService.class.getName()); WinBoll.bindToAPPBaseBeta(mContext, TestDemoBindService.class.getName());
} else { } else {
WinBoLL.bindToAPPBase(mContext, TestDemoBindService.class.getName()); WinBoll.bindToAPPBase(mContext, TestDemoBindService.class.getName());
} }
while (!isExit()) { while (!isExit()) {

View File

@@ -12,7 +12,7 @@ import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import cc.winboll.studio.appbase.models.TestDemoServiceBean; import cc.winboll.studio.appbase.models.TestDemoServiceBean;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.WinBoLL; import cc.winboll.studio.libappbase.sos.WinBoll;
public class TestDemoService extends Service { public class TestDemoService extends Service {

View File

@@ -12,12 +12,12 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import cc.winboll.studio.appbase.R; import cc.winboll.studio.appbase.R;
import cc.winboll.studio.appbase.models.WinBoLLNewsBean; import cc.winboll.studio.appbase.models.WinBollNewsBean;
import cc.winboll.studio.appbase.receivers.APPNewsWidgetClickListener; import cc.winboll.studio.appbase.receivers.APPNewsWidgetClickListener;
import cc.winboll.studio.libappbase.AppUtils; import cc.winboll.studio.libappbase.AppUtils;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.APPModel; import cc.winboll.studio.libappbase.sos.APPModel;
import cc.winboll.studio.libappbase.sos.WinBoLL; import cc.winboll.studio.libappbase.sos.WinBoll;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
@@ -31,14 +31,14 @@ public class APPNewsWidget extends AppWidgetProvider {
public static final String ACTION_RELOAD_REPORT = APPNewsWidget.class.getName() + ".ACTION_RELOAD_REPORT"; public static final String ACTION_RELOAD_REPORT = APPNewsWidget.class.getName() + ".ACTION_RELOAD_REPORT";
volatile static ArrayList<WinBoLLNewsBean> _WinBoLLNewsBeanList; volatile static ArrayList<WinBollNewsBean> _WinBollNewsBeanList;
final static int _MAX_PAGES = 10; final static int _MAX_PAGES = 10;
final static int _OnePageLinesCount = 5; final static int _OnePageLinesCount = 5;
volatile static int _CurrentPageIndex = 0; volatile static int _CurrentPageIndex = 0;
@Override @Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
initWinBoLLNewsBeanList(context); initWinBollNewsBeanList(context);
for (int appWidgetId : appWidgetIds) { for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId); updateAppWidget(context, appWidgetManager, appWidgetId);
} }
@@ -47,7 +47,7 @@ public class APPNewsWidget extends AppWidgetProvider {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent); super.onReceive(context, intent);
initWinBoLLNewsBeanList(context); initWinBollNewsBeanList(context);
if (intent.getAction().equals(ACTION_RELOAD_REPORT)) { if (intent.getAction().equals(ACTION_RELOAD_REPORT)) {
LogUtils.d(TAG, "ACTION_RELOAD_REPORT"); LogUtils.d(TAG, "ACTION_RELOAD_REPORT");
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
@@ -57,7 +57,7 @@ public class APPNewsWidget extends AppWidgetProvider {
} }
}else if (intent.getAction().equals(ACTION_WAKEUP_SERVICE)) { }else if (intent.getAction().equals(ACTION_WAKEUP_SERVICE)) {
LogUtils.d(TAG, "ACTION_WAKEUP_SERVICE"); LogUtils.d(TAG, "ACTION_WAKEUP_SERVICE");
String szAPPModel = intent.getStringExtra(WinBoLL.EXTRA_APPMODEL); String szAPPModel = intent.getStringExtra(WinBoll.EXTRA_APPMODEL);
LogUtils.d(TAG, String.format("szAPPModel %s", szAPPModel)); LogUtils.d(TAG, String.format("szAPPModel %s", szAPPModel));
if (szAPPModel != null && !szAPPModel.equals("")) { if (szAPPModel != null && !szAPPModel.equals("")) {
try { try {
@@ -71,7 +71,7 @@ public class APPNewsWidget extends AppWidgetProvider {
String appName = AppUtils.getAppNameByPackageName(context, szAppPackageName); String appName = AppUtils.getAppNameByPackageName(context, szAppPackageName);
LogUtils.d(TAG, String.format("appName %s", appName)); LogUtils.d(TAG, String.format("appName %s", appName));
WinBoLLNewsBean winBollNewsBean = new WinBoLLNewsBean(appName); WinBollNewsBean winBollNewsBean = new WinBollNewsBean(appName);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentTime = sdf.format(new Date()); String currentTime = sdf.format(new Date());
StringBuilder sbLine = new StringBuilder(); StringBuilder sbLine = new StringBuilder();
@@ -81,7 +81,7 @@ public class APPNewsWidget extends AppWidgetProvider {
sbLine.append(appName); sbLine.append(appName);
winBollNewsBean.setMessage(sbLine.toString()); winBollNewsBean.setMessage(sbLine.toString());
addWinBoLLNewsBean(context, winBollNewsBean); addWinBollNewsBean(context, winBollNewsBean);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPNewsWidget.class)); int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPNewsWidget.class));
@@ -99,24 +99,24 @@ public class APPNewsWidget extends AppWidgetProvider {
// //
// 加入新报告信息 // 加入新报告信息
// //
public synchronized static void addWinBoLLNewsBean(Context context, WinBoLLNewsBean bean) { public synchronized static void addWinBollNewsBean(Context context, WinBollNewsBean bean) {
initWinBoLLNewsBeanList(context); initWinBollNewsBeanList(context);
_WinBoLLNewsBeanList.add(0, bean); _WinBollNewsBeanList.add(0, bean);
// 控制记录总数 // 控制记录总数
while (_WinBoLLNewsBeanList.size() > _MAX_PAGES * _OnePageLinesCount) { while (_WinBollNewsBeanList.size() > _MAX_PAGES * _OnePageLinesCount) {
_WinBoLLNewsBeanList.remove(_WinBoLLNewsBeanList.size() - 1); _WinBollNewsBeanList.remove(_WinBollNewsBeanList.size() - 1);
} }
WinBoLLNewsBean.saveBeanList(context, _WinBoLLNewsBeanList, WinBoLLNewsBean.class); WinBollNewsBean.saveBeanList(context, _WinBollNewsBeanList, WinBollNewsBean.class);
} }
synchronized static void initWinBoLLNewsBeanList(Context context) { synchronized static void initWinBollNewsBeanList(Context context) {
if (_WinBoLLNewsBeanList == null) { if (_WinBollNewsBeanList == null) {
_WinBoLLNewsBeanList = new ArrayList<WinBoLLNewsBean>(); _WinBollNewsBeanList = new ArrayList<WinBollNewsBean>();
WinBoLLNewsBean.loadBeanList(context, _WinBoLLNewsBeanList, WinBoLLNewsBean.class); WinBollNewsBean.loadBeanList(context, _WinBollNewsBeanList, WinBollNewsBean.class);
} }
if (_WinBoLLNewsBeanList == null) { if (_WinBollNewsBeanList == null) {
_WinBoLLNewsBeanList = new ArrayList<WinBoLLNewsBean>(); _WinBollNewsBeanList = new ArrayList<WinBollNewsBean>();
WinBoLLNewsBean.saveBeanList(context, _WinBoLLNewsBeanList, WinBoLLNewsBean.class); WinBollNewsBean.saveBeanList(context, _WinBollNewsBeanList, WinBollNewsBean.class);
} }
} }
@@ -141,11 +141,11 @@ public class APPNewsWidget extends AppWidgetProvider {
public static String getMessage() { public static String getMessage() {
ArrayList<String> msgTemp = new ArrayList<String>(); ArrayList<String> msgTemp = new ArrayList<String>();
if (_WinBoLLNewsBeanList != null) { if (_WinBollNewsBeanList != null) {
int start = _OnePageLinesCount * _CurrentPageIndex; int start = _OnePageLinesCount * _CurrentPageIndex;
start = _WinBoLLNewsBeanList.size() > start ? start : _WinBoLLNewsBeanList.size() - 1; start = _WinBollNewsBeanList.size() > start ? start : _WinBollNewsBeanList.size() - 1;
for (int i = start, j = 0; i < _WinBoLLNewsBeanList.size() && j < _OnePageLinesCount && start > -1; i++, j++) { for (int i = start, j = 0; i < _WinBollNewsBeanList.size() && j < _OnePageLinesCount && start > -1; i++, j++) {
msgTemp.add(_WinBoLLNewsBeanList.get(i).getMessage()); msgTemp.add(_WinBollNewsBeanList.get(i).getMessage());
} }
String message = String.join("\n", msgTemp); String message = String.join("\n", msgTemp);
return message; return message;
@@ -154,7 +154,7 @@ public class APPNewsWidget extends AppWidgetProvider {
} }
public static void prePage(Context context) { public static void prePage(Context context) {
if (_WinBoLLNewsBeanList != null) { if (_WinBollNewsBeanList != null) {
if (_CurrentPageIndex > 0) { if (_CurrentPageIndex > 0) {
_CurrentPageIndex = _CurrentPageIndex - 1; _CurrentPageIndex = _CurrentPageIndex - 1;
} }
@@ -165,8 +165,8 @@ public class APPNewsWidget extends AppWidgetProvider {
} }
public static void nextPage(Context context) { public static void nextPage(Context context) {
if (_WinBoLLNewsBeanList != null) { if (_WinBollNewsBeanList != null) {
if ((_CurrentPageIndex + 1) * _OnePageLinesCount < _WinBoLLNewsBeanList.size()) { if ((_CurrentPageIndex + 1) * _OnePageLinesCount < _WinBollNewsBeanList.size()) {
_CurrentPageIndex = _CurrentPageIndex + 1; _CurrentPageIndex = _CurrentPageIndex + 1;
} }
Intent intentWidget = new Intent(context, APPNewsWidget.class); Intent intentWidget = new Intent(context, APPNewsWidget.class);
@@ -176,11 +176,11 @@ public class APPNewsWidget extends AppWidgetProvider {
} }
String getPageInfo() { String getPageInfo() {
if (_WinBoLLNewsBeanList == null) { if (_WinBollNewsBeanList == null) {
return "0/0"; return "0/0";
} }
int leftCount = _WinBoLLNewsBeanList.size() % _OnePageLinesCount; int leftCount = _WinBollNewsBeanList.size() % _OnePageLinesCount;
int currentPageCount = _WinBoLLNewsBeanList.size() / _OnePageLinesCount + (leftCount == 0 ?0: 1); int currentPageCount = _WinBollNewsBeanList.size() / _OnePageLinesCount + (leftCount == 0 ?0: 1);
return String.format("%d/%d", _CurrentPageIndex + 1, currentPageCount); return String.format("%d/%d", _CurrentPageIndex + 1, currentPageCount);
} }
} }

View File

@@ -5,7 +5,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.widget.Toolbar <android.support.v7.widget.Toolbar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/toolbar"/> android:id="@+id/toolbar"/>
@@ -32,7 +32,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello, WinBoLL!"/> android:text="Hello, WinBoll!"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -6,7 +6,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.widget.Toolbar <android.support.v7.widget.Toolbar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/toolbar"/> android:id="@+id/toolbar"/>

View File

@@ -6,7 +6,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.widget.Toolbar <android.support.v7.widget.Toolbar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/toolbar"/> android:id="@+id/toolbar"/>

View File

@@ -18,7 +18,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/tv_title" android:id="@+id/tv_title"
android:layout_weight="1.0" android:layout_weight="1.0"
android:text="WinBoLLNews" android:text="WinBollNews"
android:textStyle="bold" android:textStyle="bold"
android:textSize="16sp"/> android:textSize="16sp"/>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">AppBase</string> <string name="app_name">AppBase</string>
<string name="tileservice_name">WinBoLL</string> <string name="tileservice_name">WinBoll</string>
</resources> </resources>

View File

@@ -24,12 +24,12 @@ android {
defaultConfig { defaultConfig {
applicationId "cc.winboll.studio.apputils" applicationId "cc.winboll.studio.apputils"
minSdkVersion 26 minSdkVersion 26
targetSdkVersion 30 targetSdkVersion 29
versionCode 1 versionCode 1
// versionName 更新后需要手动设置 // versionName 更新后需要手动设置
// 项目模块目录的 build.gradle 文件的 stageCount=0 // 项目模块目录的 build.gradle 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.3" versionName "15.2"
if(true) { if(true) {
versionName = genVersionName("${versionName}") versionName = genVersionName("${versionName}")
} }

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Tue Apr 29 15:04:17 HKT 2025 #Sat Apr 26 16:55:12 GMT 2025
stageCount=5 stageCount=2
libraryProject=libapputils libraryProject=libapputils
baseVersion=15.3 baseVersion=15.2
publishVersion=15.3.4 publishVersion=15.2.1
buildCount=0 buildCount=1
baseBetaVersion=15.3.5 baseBetaVersion=15.2.2

View File

@@ -15,12 +15,12 @@ import android.view.MenuItem;
import android.widget.Toolbar; import android.widget.Toolbar;
import cc.winboll.studio.apputils.R; import cc.winboll.studio.apputils.R;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import cc.winboll.studio.libapputils.views.SimpleWebView; import cc.winboll.studio.libapputils.views.SimpleWebView;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
public class AssetsHtmlActivity extends WinBoLLActivityBase implements IWinBoLLActivity { public class AssetsHtmlActivity extends WinBollActivityBase implements IWinBollActivity {
@Override @Override
public Activity getActivity() { public Activity getActivity() {
@@ -57,7 +57,7 @@ public class AssetsHtmlActivity extends WinBoLLActivityBase implements IWinBoLLA
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
// if (item.getItemId() == android.R.id.home) { // if (item.getItemId() == android.R.id.home) {
// WinBoLLActivityManager.getInstance(this).finish(this); // WinBollActivityManager.getInstance(this).finish(this);
// } // }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }

View File

@@ -60,9 +60,9 @@ final public class MainActivity extends Activity {
//if (prosessIntents(getIntent())) return; //if (prosessIntents(getIntent())) return;
// 以下正常创建主窗口 // 以下正常创建主窗口
// // 设置 WinBoLL 应用 UI 类型 // // 设置 WinBoll 应用 UI 类型
// WinBoLLApplication.setWinBoLLUI_TYPE(WinBoLLApplication.WinBoLLUI_TYPE.Aplication); // WinBollApplication.setWinBollUI_TYPE(WinBollApplication.WinBollUI_TYPE.Aplication);
// //ToastUtils.show("WinBoLLUI_TYPE " + WinBoLLApplication.getWinBoLLUI_TYPE()); // //ToastUtils.show("WinBollUI_TYPE " + WinBollApplication.getWinBollUI_TYPE());
// LogUtils.d(TAG, "BuildConfig.DEBUG : " + Boolean.toString(BuildConfig.DEBUG)); // LogUtils.d(TAG, "BuildConfig.DEBUG : " + Boolean.toString(BuildConfig.DEBUG));
} }
@@ -77,7 +77,7 @@ final public class MainActivity extends Activity {
if (intent.getAction() != null) { if (intent.getAction() != null) {
// if (intent.getAction().equals(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW)) { // if (intent.getAction().equals(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW)) {
// App.setIsDebug(true); // App.setIsDebug(true);
// //ToastUtils.show!("WinBoLLApplication.setIsDebug(true) by action : " + intent.getAction()); // //ToastUtils.show!("WinBollApplication.setIsDebug(true) by action : " + intent.getAction());
// //
// } // }
} }
@@ -130,12 +130,12 @@ final public class MainActivity extends Activity {
protected void onPostCreate(Bundle savedInstanceState) { protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState); super.onPostCreate(savedInstanceState);
// 缓存当前 activity // 缓存当前 activity
//WinBoLLActivityManager.getInstance(this).add(this); //WinBollActivityManager.getInstance(this).add(this);
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
//WinBoLLActivityManager.getInstance(this).registeRemove(this); //WinBollActivityManager.getInstance(this).registeRemove(this);
super.onDestroy(); super.onDestroy();
} }
@@ -150,8 +150,8 @@ final public class MainActivity extends Activity {
// intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); // intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
// startActivity(intent); // startActivity(intent);
//WinBoLLActivityManager.getInstance().printAvtivityListInfo(); //WinBollActivityManager.getInstance().printAvtivityListInfo();
//WinBoLLActivityManager.getInstance(this).startWinBoLLActivity(this, LogActivity.class); //WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
} }
// //
@@ -165,7 +165,7 @@ final public class MainActivity extends Activity {
// if (intent.getAction().equals(StringToQrCodeView.ACTION_UNITTEST_QRCODE)) { // if (intent.getAction().equals(StringToQrCodeView.ACTION_UNITTEST_QRCODE)) {
// try { // try {
// WinBoLLActivity clazzActivity = UnitTestActivity.class.newInstance(); // WinBollActivity clazzActivity = UnitTestActivity.class.newInstance();
// String tag = clazzActivity.getTag(); // String tag = clazzActivity.getTag();
// LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag); // LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag);
// Intent subIntent = new Intent(this, UnitTestActivity.class); // Intent subIntent = new Intent(this, UnitTestActivity.class);
@@ -183,8 +183,8 @@ final public class MainActivity extends Activity {
// } // }
// //
// Files.copy(Paths.get(szSrcPath), Paths.get(file.getPath())); // Files.copy(Paths.get(szSrcPath), Paths.get(file.getPath()));
// //startWinBoLLActivity(subIntent, tag); // //startWinBollActivity(subIntent, tag);
// WinBoLLActivityManager.getInstance(this).startWinBoLLActivity(this, subIntent, UnitTestActivity.class); // WinBollActivityManager.getInstance(this).startWinBollActivity(this, subIntent, UnitTestActivity.class);
// } catch (IllegalAccessException | InstantiationException | IOException e) { // } catch (IllegalAccessException | InstantiationException | IOException e) {
// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); // LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
// // 函数处理异常返回失败 // // 函数处理异常返回失败
@@ -201,8 +201,8 @@ final public class MainActivity extends Activity {
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
//ToastUtils.show("onCreateOptionsMenu"); //ToastUtils.show("onCreateOptionsMenu");
getMenuInflater().inflate(R.menu.toolbar_main, menu); getMenuInflater().inflate(R.menu.toolbar_main, menu);
// if (isAddWinBoLLToolBar()) { // if (isAddWinBollToolBar()) {
// //ToastUtils.show("mIWinBoLL.isAddWinBoLLToolBar()"); // //ToastUtils.show("mIWinBoll.isAddWinBollToolBar()");
// getMenuInflater().inflate(R.menu.toolbar_winboll_shared_main, menu); // getMenuInflater().inflate(R.menu.toolbar_winboll_shared_main, menu);
// } // }
if (App.isDebuging()) { if (App.isDebuging()) {
@@ -220,7 +220,7 @@ final public class MainActivity extends Activity {
} else if (item.getItemId() == R.id.item_teststringtoqrcodeview) { } else if (item.getItemId() == R.id.item_teststringtoqrcodeview) {
Intent intent = new Intent(this, TestStringToQRCodeViewActivity.class); Intent intent = new Intent(this, TestStringToQRCodeViewActivity.class);
startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY); startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY);
//WinBoLLActivityManager.getInstance(this).startWinBoLLActivity(this, TestStringToQrCodeViewActivity.class); //WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestStringToQrCodeViewActivity.class);
} else if (item.getItemId() == R.id.item_testqrcodedecodeactivity) { } else if (item.getItemId() == R.id.item_testqrcodedecodeactivity) {
Intent intent = new Intent(this, QRCodeDecodeActivity.class); Intent intent = new Intent(this, QRCodeDecodeActivity.class);
startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY); startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY);
@@ -230,13 +230,13 @@ final public class MainActivity extends Activity {
} }
return true; return true;
} else if (item.getItemId() == R.id.item_log) { } else if (item.getItemId() == R.id.item_log) {
//WinBoLLActivityManager.getInstance(this).startWinBoLLActivity(this, LogActivity.class); //WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
return true; return true;
} else if (item.getItemId() == R.id.item_exitdebug) { } else if (item.getItemId() == R.id.item_exitdebug) {
//AboutView.setApp2NormalMode(this); //AboutView.setApp2NormalMode(this);
return true; return true;
} else if (item.getItemId() == android.R.id.home) { } else if (item.getItemId() == android.R.id.home) {
//WinBoLLActivityManager.getInstance(this).finish(this); //WinBollActivityManager.getInstance(this).finish(this);
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@@ -247,7 +247,7 @@ final public class MainActivity extends Activity {
// //
// @Override // @Override
// public void onYes() { // public void onYes() {
// //WinBoLLActivityManager.getInstance(getApplicationContext()).finishAll(); // //WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
// } // }
// //
// @Override // @Override
@@ -260,10 +260,10 @@ final public class MainActivity extends Activity {
@Override @Override
public void onBackPressed() { public void onBackPressed() {
// if (WinBoLLActivityManager.getInstance(getApplicationContext()).isFirstIWinBoLLActivity(this)) { // if (WinBollActivityManager.getInstance(getApplicationContext()).isFirstIWinBollActivity(this)) {
// exit(); // exit();
// } else { // } else {
// WinBoLLActivityManager.getInstance(this).finish(this); // WinBollActivityManager.getInstance(this).finish(this);
// super.onBackPressed(); // super.onBackPressed();
// } // }
} }
@@ -275,7 +275,7 @@ final public class MainActivity extends Activity {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent); startActivity(intent);
//WinBoLLActivityManager.getInstance(this).startWinBoLLActivity(this, intent, AssetsHtmlActivity.class); //WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AssetsHtmlActivity.class);
} }
@Override @Override

View File

@@ -0,0 +1,36 @@
package cc.winboll.studio.apputils;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2025/01/17 19:50:46
*/
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toolbar;
import cc.winboll.studio.apputils.R;
import cc.winboll.studio.libapputils.views.StringToQrCodeView;
public class TestStringToQRCodeViewActivity extends Activity {
public static final String TAG = "TestStringToQrCodeViewActivity";
StringToQrCodeView mStringToQrCodeView;
//
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teststringtoqrcodeview);
// 初始化工具栏
Toolbar mToolbar = findViewById(R.id.toolbar);
mToolbar.setSubtitle(TAG);
setActionBar(mToolbar);
mStringToQrCodeView = findViewById(R.id.activityteststringtoqrcodeviewStringToQrCodeView1);
}
}

View File

@@ -0,0 +1,52 @@
package cc.winboll.studio.apputils;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/28 17:11:37
* @Describe 应用活动窗口基类
*/
import android.app.Activity;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import cc.winboll.studio.libappbase.winboll.WinBollActivityManager;
public class WinBollActivityBase extends AppCompatActivity implements IWinBollActivity {
public static final String TAG = "WinBollActivityBase";
@Override
public Activity getActivity() {
return this;
}
@Override
public String getTag() {
return TAG;
}
WinBollActivityManager getWinBollActivityManager() {
return WinBollActivityManager.getInstance(GlobalApplication.getInstance());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWinBollActivityManager().add(this);
}
@Override
public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
}
@Override
protected void onDestroy() {
super.onDestroy();
getWinBollActivityManager().registeRemove(this);
}
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- WinBoLL 默认方案 --> <!-- WinBoll 默认方案 -->
<color name="colorPrimary">#FF196ABC</color> <color name="colorPrimary">#FF196ABC</color>
<color name="colorPrimaryDark">#FF002B57</color> <color name="colorPrimaryDark">#FF002B57</color>
<color name="colorAccent">#FF80BFFF</color> <color name="colorAccent">#FF80BFFF</color>

View File

@@ -19,7 +19,7 @@ def genVersionName(def versionName){
android { android {
compileSdkVersion 32 compileSdkVersion 32
buildToolsVersion "32.0.0" buildToolsVersion "33.0.3"
defaultConfig { defaultConfig {
applicationId "cc.winboll.studio.autoinstaller" applicationId "cc.winboll.studio.autoinstaller"
@@ -29,7 +29,7 @@ android {
// versionName 更新后需要手动设置 // versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0 // .winboll/winbollBuildProps.properties 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.2" versionName "5.0"
if(true) { if(true) {
versionName = genVersionName("${versionName}") versionName = genVersionName("${versionName}")
} }
@@ -41,33 +41,30 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
} }
dependencies { dependencies {
api fileTree(dir: 'libs', include: ['*.jar']) api 'cc.winboll.studio:winboll-shared:1.1.0'
api 'cc.winboll.studio:libaes:15.6.0'
api 'cc.winboll.studio:libapputils:15.3.4'
api 'cc.winboll.studio:libappbase:15.7.6'
// SSH
api 'com.jcraft:jsch:0.1.55'
// Html 解析
api 'org.jsoup:jsoup:1.13.1'
// 二维码类库
api 'com.google.zxing:core:3.4.1'
api 'com.journeyapps:zxing-android-embedded:3.6.0'
// 应用介绍页类库
api 'io.github.medyo:android-about-page:2.0.0' api 'io.github.medyo:android-about-page:2.0.0'
// 吐司类库
api 'com.github.getActivity:ToastUtils:10.5' api 'com.github.getActivity:ToastUtils:10.5'
// 网络连接类库 api 'com.jcraft:jsch:0.1.55'
api 'org.jsoup:jsoup:1.13.1'
api 'com.squareup.okhttp3:okhttp:4.4.1' api 'com.squareup.okhttp3:okhttp:4.4.1'
// AndroidX 类库
api 'androidx.appcompat:appcompat:1.1.0'
api 'com.google.android.material:material:1.4.0'
//api 'androidx.viewpager:viewpager:1.0.0'
//api 'androidx.vectordrawable:vectordrawable:1.1.0'
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
//api 'androidx.fragment:fragment:1.1.0'
api 'androidx.appcompat:appcompat:1.0.0'
api 'androidx.fragment:fragment:1.0.0'
api 'com.google.android.material:material:1.0.0'
api 'androidx.vectordrawable:vectordrawable-animated:1.0.0'
api 'androidx.lifecycle:lifecycle-livedata:1.0.0'
//api 'cc.winboll.studio:libaes:6.3.2'
//api 'cc.winboll.studio:libapputils:8.3.8'
api fileTree(dir: 'libs', include: ['*.jar'])
} }

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sun May 04 05:32:00 GMT 2025 #Thu Jan 02 02:39:56 HKT 2025
stageCount=1 stageCount=4
libraryProject= libraryProject=
baseVersion=15.2 baseVersion=5.0
publishVersion=15.2.0 publishVersion=5.0.3
buildCount=74 buildCount=0
baseBetaVersion=15.2.1 baseBetaVersion=5.0.4

View File

@@ -23,8 +23,6 @@
<!-- MANAGE_EXTERNAL_STORAGE --> <!-- MANAGE_EXTERNAL_STORAGE -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application <application
android:name=".App" android:name=".App"
@@ -35,7 +33,7 @@
android:persistent="true" android:persistent="true"
android:supportsRtl="true" android:supportsRtl="true"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:theme="@style/MyAppTheme"> android:theme="@style/Theme.Application">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
@@ -56,21 +54,6 @@
<service android:name=".services.AssistantService"/> <service android:name=".services.AssistantService"/>
<service
android:name=".AppBaseTileService"
android:exported="true"
android:label="@string/tileservice_name"
android:icon="@drawable/ic_launcher"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE"/>
</intent-filter>
</service>
<receiver <receiver
android:name=".receivers.MainReceiver" android:name=".receivers.MainReceiver"
android:enabled="true" android:enabled="true"

View File

@@ -6,23 +6,22 @@ package cc.winboll.studio.autoinstaller;
* @Describe 全局应用类 * @Describe 全局应用类
*/ */
import android.view.Gravity; import android.view.Gravity;
import cc.winboll.studio.libappbase.GlobalApplication;
import com.hjq.toast.ToastUtils; import com.hjq.toast.ToastUtils;
import com.hjq.toast.style.WhiteToastStyle; import cc.winboll.studio.shared.app.WinBollApplication;
public class App extends GlobalApplication { public class App extends WinBollApplication {
public static final String TAG = "App"; public static final String TAG = "App";
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
setIsDebug(BuildConfig.DEBUG);
// 初始化 Toast 框架 // 初始化 Toast 框架
ToastUtils.init(this); ToastUtils.init(this);
// 设置 Toast 布局样式 // 设置 Toast 布局样式
//ToastUtils.setView(R.layout.view_toast); ToastUtils.setView(R.layout.toast_custom_view);
ToastUtils.setStyle(new WhiteToastStyle()); //ToastUtils.setStyle(new WhiteToastStyle());
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200); ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
} }
} }

View File

@@ -1,12 +0,0 @@
package cc.winboll.studio.autoinstaller;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/04/15 09:24:46
* @Describe 磁贴工具服务类
*/
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import cc.winboll.studio.autoinstaller.models.AppConfigs;

View File

@@ -1,7 +1,7 @@
package cc.winboll.studio.autoinstaller; package cc.winboll.studio.autoinstaller;
import android.os.FileObserver; import android.os.FileObserver;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.shared.log.LogUtils;
public class FileListener extends FileObserver { public class FileListener extends FileObserver {
public final static String TAG = "FileListener"; public final static String TAG = "FileListener";

View File

@@ -6,24 +6,21 @@ import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.SimpleAdapter; import android.widget.SimpleAdapter;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextClock; import android.widget.TextClock;
import android.widget.Toast;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.shared.log.LogView;
import cc.winboll.studio.autoinstaller.MainActivity; import cc.winboll.studio.autoinstaller.MainActivity;
import cc.winboll.studio.autoinstaller.models.APKModel; import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.models.AppConfigs;
import cc.winboll.studio.autoinstaller.services.MainService; import cc.winboll.studio.autoinstaller.services.MainService;
import cc.winboll.studio.autoinstaller.utils.NotificationUtil; import cc.winboll.studio.autoinstaller.utils.NotificationUtil;
import cc.winboll.studio.autoinstaller.utils.PackageUtil;
import cc.winboll.studio.autoinstaller.views.ListViewForScrollView; import cc.winboll.studio.autoinstaller.views.ListViewForScrollView;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.LogView;
import com.hjq.toast.ToastUtils; import com.hjq.toast.ToastUtils;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@@ -33,13 +30,8 @@ import java.util.Map;
public class MainActivity extends Activity { public class MainActivity extends Activity {
public static final String TAG = "MainActivity"; public static final String TAG = "MainActivity";
public static final int MSG_UPDATE_STATUS = 0;
private static final int INSTALL_PERMISSION_CODE = 1; private static final int INSTALL_PERMISSION_CODE = 1;
static MainActivity _MainActivity;
ArrayList<APKModel> _APKModelList = new ArrayList<APKModel>();
LogView mLogView; LogView mLogView;
TextClock mTextClock; TextClock mTextClock;
EditText mEditText; EditText mEditText;
@@ -68,11 +60,9 @@ public class MainActivity extends Activity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
_MainActivity = this;
initView(); initView();
String action = getIntent().getAction(); if (getIntent().getAction().equals(ACTION_NEW_INSTALLTASK)) {
if ((action != null) && action.equals(ACTION_NEW_INSTALLTASK)) {
mszInstalledPackageName = getIntent().getStringExtra(EXTRA_INSTALLED_PACKAGENAME); mszInstalledPackageName = getIntent().getStringExtra(EXTRA_INSTALLED_PACKAGENAME);
mszInstalledAPKFilePath = getIntent().getStringExtra(EXTRA_INSTALLED_APKFILEPATH); mszInstalledAPKFilePath = getIntent().getStringExtra(EXTRA_INSTALLED_APKFILEPATH);
installAPK(); installAPK();
@@ -86,7 +76,11 @@ public class MainActivity extends Activity {
mLogView = findViewById(R.id.logview); mLogView = findViewById(R.id.logview);
mLogView.start(); mLogView.start();
AppConfigs appConfigs = AppConfigs.getInstance(this).loadAppConfigs(this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(this);
if (appConfigs == null) {
appConfigs = new AppConfigs();
AppConfigs.saveAppConfigs(this, appConfigs);
}
if (appConfigs.getSetupMode() == AppConfigs.SetupMode.WATCHOUTPUTINSTALLER) { if (appConfigs.getSetupMode() == AppConfigs.SetupMode.WATCHOUTPUTINSTALLER) {
((RadioButton)findViewById(R.id.activitymainRadioButton1)).setChecked(true); ((RadioButton)findViewById(R.id.activitymainRadioButton1)).setChecked(true);
@@ -137,44 +131,23 @@ public class MainActivity extends Activity {
} }
String getLastApkPackageName() {
APKModel.loadBeanList(this, _APKModelList, APKModel.class);
if (_APKModelList.size() > 0) {
return _APKModelList.get(_APKModelList.size() - 1).getApkPackageName();
}
return "";
}
public void onOpenAPP(View view) { public void onOpenAPP(View view) {
String szInstalledPackageName = getLastApkPackageName(); if (mszInstalledPackageName.trim().equals("")) {
LogUtils.d(TAG, "szInstalledPackageName : " + szInstalledPackageName);
if (szInstalledPackageName.trim().equals("")) {
ToastUtils.show("Installed APP package name is null."); ToastUtils.show("Installed APP package name is null.");
return; return;
} }
PackageUtil.openAPP(this, szInstalledPackageName); Intent intent = getPackageManager().getLaunchIntentForPackage(mszInstalledPackageName);
if (intent != null) {
startActivity(intent);
} else {
// 若没能获取到启动意图,可进行相应提示等操作,比如跳转到应用商店让用户下载该应用(示例)
Intent marketIntent = new Intent(Intent.ACTION_VIEW);
marketIntent.setData(Uri.parse("market://details?id=" + mszInstalledPackageName));
startActivity(marketIntent);
}
} }
// public void onOpenAPP(View view) {
// String szInstalledPackageName = getLastApkPackageName();
// if (szInstalledPackageName.trim().equals("")) {
// ToastUtils.show("Installed APP package name is null.");
// return;
// }
//
// Intent intent = getPackageManager().getLaunchIntentForPackage(mszInstalledPackageName);
// if (intent != null) {
// //ToastUtils.show("startActivity");
// startActivity(intent);
// } else {
// // 若没能获取到启动意图,可进行相应提示等操作,比如跳转到应用商店让用户下载该应用(示例)
// Intent marketIntent = new Intent(Intent.ACTION_VIEW);
// marketIntent.setData(Uri.parse("market://details?id=" + mszInstalledPackageName));
// startActivity(marketIntent);
// }
// }
public void onInstallAPK(View view) { public void onInstallAPK(View view) {
installAPK(); installAPK();
} }
@@ -212,22 +185,17 @@ public class MainActivity extends Activity {
} }
public void onLockPath(View view) { public void onLockPath(View view) {
AppConfigs appConfigs = AppConfigs.loadAppConfigs(this);
Switch sw = (Switch)view; Switch sw = (Switch)view;
setMainServiceStatus(sw.isChecked()); if (sw.isChecked()) {
}
public void setMainServiceStatus(boolean isEnable) {
AppConfigs appConfigs = AppConfigs.getInstance(this).loadAppConfigs(this);
Switch sw = (Switch)findViewById(R.id.activitymainSwitch1);
if (isEnable) {
String szFilePath = mEditText.getText().toString(); String szFilePath = mEditText.getText().toString();
// 设置空路径时退出 // 设置空路径时退出
// //
if (szFilePath.trim().equals("")) { if (szFilePath.trim().equals("")) {
sw.setChecked(false); sw.setChecked(false);
ToastUtils.show("监控路径为空。"); Toast.makeText(getApplication(), "监控路径为空。", Toast.LENGTH_SHORT).show();
return; return;
} }
@@ -268,7 +236,7 @@ public class MainActivity extends Activity {
stopWatchingFile(); stopWatchingFile();
} }
AppConfigs.getInstance(this).saveAppConfigs(this, appConfigs); AppConfigs.saveAppConfigs(this, appConfigs);
} }
void stopWatchingFile() { void stopWatchingFile() {
@@ -283,6 +251,8 @@ public class MainActivity extends Activity {
Intent intentService = new Intent(MainActivity.this, MainService.class); Intent intentService = new Intent(MainActivity.this, MainService.class);
//intentService.putExtra(MainService.EXTRA_APKFILEPATH, szAPKFilePath); //intentService.putExtra(MainService.EXTRA_APKFILEPATH, szAPKFilePath);
startService(intentService); startService(intentService);
} }
/* /*
@@ -328,7 +298,7 @@ public class MainActivity extends Activity {
}*/ }*/
public void onChangeSetupMode(View view) { public void onChangeSetupMode(View view) {
AppConfigs appConfigs = AppConfigs.getInstance(this).loadAppConfigs(this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(this);
if (view.getId() == R.id.activitymainRadioButton1) { if (view.getId() == R.id.activitymainRadioButton1) {
appConfigs.setSetupMode(AppConfigs.SetupMode.WATCHOUTPUTINSTALLER); appConfigs.setSetupMode(AppConfigs.SetupMode.WATCHOUTPUTINSTALLER);
@@ -337,42 +307,6 @@ public class MainActivity extends Activity {
appConfigs.setSetupMode(AppConfigs.SetupMode.NEWAPKINFONEWAPKINFO); appConfigs.setSetupMode(AppConfigs.SetupMode.NEWAPKINFONEWAPKINFO);
((RadioButton)findViewById(R.id.activitymainRadioButton1)).setChecked(false); ((RadioButton)findViewById(R.id.activitymainRadioButton1)).setChecked(false);
} }
AppConfigs.getInstance(this).saveAppConfigs(this, appConfigs); AppConfigs.saveAppConfigs(this, appConfigs);
}
// 定义Handler
static Handler _Handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == MSG_UPDATE_STATUS) {
if (_MainActivity != null) {
boolean isEnableMainService = (boolean)msg.obj;
// 处理消息,这里更新 MainService 的状态
_MainActivity.setMainServiceStatus(isEnableMainService);
}
}
}
};
static void updateMainServiceStatus(boolean isEnable) {
if (_Handler != null) {
Message msg = new Message();
msg.obj = isEnable;
msg.what = MSG_UPDATE_STATUS;
_Handler.sendMessage(msg);
}
}
public static void stopMainService() {
if (_MainActivity != null && _Handler != null) {
updateMainServiceStatus(false);
}
}
public static void startMainService() {
if (_MainActivity != null && _Handler != null) {
updateMainServiceStatus(true);
}
} }
} }

View File

@@ -1,4 +1,4 @@
package cc.winboll.studio.autoinstaller.models; package cc.winboll.studio.autoinstaller.beans;
/** /**
* @Author ZhanGSKen@QQ.COM * @Author ZhanGSKen@QQ.COM
@@ -8,14 +8,13 @@ package cc.winboll.studio.autoinstaller.models;
import android.content.Context; import android.content.Context;
import android.util.JsonReader; import android.util.JsonReader;
import android.util.JsonWriter; import android.util.JsonWriter;
import cc.winboll.studio.autoinstaller.models.AppConfigs; import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.utils.FileUtil; import cc.winboll.studio.autoinstaller.utils.FileUtil;
import cc.winboll.studio.libappbase.LogUtils;
import com.hjq.toast.ToastUtils;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import cc.winboll.studio.shared.log.LogUtils;
public class AppConfigs implements Serializable { public class AppConfigs implements Serializable {
@@ -27,21 +26,6 @@ public class AppConfigs implements Serializable {
NEWAPKINFONEWAPKINFO // 调用[应用信息查看器]打开应用包 NEWAPKINFONEWAPKINFO // 调用[应用信息查看器]打开应用包
}; };
static volatile AppConfigs _AppConfigs;
Context mContext;
AppConfigs(Context context) {
mContext = context.getApplicationContext();
}
public static synchronized AppConfigs getInstance(Context context) {
if (_AppConfigs == null) {
_AppConfigs = new AppConfigs(context);
_AppConfigs.loadAppConfigs(_AppConfigs.mContext);
}
return _AppConfigs;
}
// 监控文件路径 // 监控文件路径
private String watchingFilePath = ""; private String watchingFilePath = "";
@@ -101,8 +85,8 @@ public class AppConfigs implements Serializable {
return ""; return "";
} }
public AppConfigs parseAppConfigs(String szAppConfigs) { public static AppConfigs parseAppConfigs(String szAppConfigs) {
AppConfigs appConfigs = new AppConfigs(mContext); AppConfigs appConfigs = new AppConfigs();
// 创建 JsonWriter 对象 // 创建 JsonWriter 对象
StringReader stringReader = new StringReader(szAppConfigs); StringReader stringReader = new StringReader(szAppConfigs);
JsonReader jsonReader = new JsonReader jsonReader = new
@@ -137,35 +121,20 @@ public class AppConfigs implements Serializable {
static String getDataPath(Context context) { static String getDataPath(Context context) {
return context.getExternalFilesDir(TAG) + "/" + TAG + ".json"; return context.getExternalFilesDir(TAG) + "/" + TAG + ".json";
} }
public AppConfigs loadAppConfigs() { public static AppConfigs loadAppConfigs(Context context) {
AppConfigs appConfigs = null; AppConfigs appConfigs = null;
try { try {
String szJson = FileUtil.readFile(getDataPath(mContext)); String szJson = FileUtil.readFile(getDataPath(context));
appConfigs = AppConfigs.getInstance(mContext).parseAppConfigs(szJson); appConfigs = AppConfigs.parseAppConfigs(szJson);
} catch (IOException e) { } catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace()); LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} }
return appConfigs; return appConfigs;
} }
public AppConfigs loadAppConfigs(Context context) { public static void saveAppConfigs(Context context, AppConfigs appConfigs) {
AppConfigs appConfigs = null;
try { try {
String szJson = FileUtil.readFile(getDataPath(context.getApplicationContext()));
appConfigs = AppConfigs.getInstance(mContext).parseAppConfigs(szJson);
if(appConfigs != null) {
_AppConfigs = appConfigs;
}
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return _AppConfigs;
}
public void saveAppConfigs(Context context, AppConfigs appConfigs) {
try {
ToastUtils.show(String.format("AppConfigs set enable service to %s", appConfigs.isEnableService()));
//LogUtils.d(TAG, "appConfigs is : " + appConfigs.toString()); //LogUtils.d(TAG, "appConfigs is : " + appConfigs.toString());
String szJson = appConfigs.toString(); String szJson = appConfigs.toString();
FileUtil.writeFile(getDataPath(context), szJson); FileUtil.writeFile(getDataPath(context), szJson);
@@ -173,8 +142,4 @@ public class AppConfigs implements Serializable {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace()); LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} }
} }
public void saveAppConfigs() {
saveAppConfigs(mContext, this);
}
} }

View File

@@ -1,75 +0,0 @@
package cc.winboll.studio.autoinstaller.models;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/04/02 20:50:29
* @Describe 监控的 APK 安装文件对应的应用信息数据模型
*/
import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.libappbase.BaseBean;
import java.io.IOException;
public class APKModel extends BaseBean {
public static final String TAG = "APPModel";
// 每次更新的 APK 文件对应的应用包名称
String apkPackageName;
public APKModel() {
this.apkPackageName = "";
}
public APKModel(String apkPackageName) {
this.apkPackageName = apkPackageName;
}
public void setApkPackageName(String apkPackageName) {
this.apkPackageName = apkPackageName;
}
public String getApkPackageName() {
return apkPackageName;
}
@Override
public String getName() {
return APKModel.class.getName();
}
@Override
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
super.writeThisToJsonWriter(jsonWriter);
jsonWriter.name("appPackageName").value(getApkPackageName());
}
@Override
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
if (name.equals("appPackageName")) {
setApkPackageName(jsonReader.nextString());
} else {
return false;
}
}
return true;
}
@Override
public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
if (!initObjectsFromJsonReader(jsonReader, name)) {
jsonReader.skipValue();
}
}
// 结束 JSON 对象
jsonReader.endObject();
return this;
}
}

View File

@@ -4,9 +4,9 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import cc.winboll.studio.autoinstaller.models.AppConfigs; import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.services.MainService; import cc.winboll.studio.autoinstaller.services.MainService;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.shared.log.LogUtils;
/** /**
* @Author ZhanGSKen@QQ.COM * @Author ZhanGSKen@QQ.COM
@@ -23,7 +23,7 @@ public class MainReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String szAction = intent.getAction(); String szAction = intent.getAction();
if (szAction.equals(ACTION_BOOT_COMPLETED)) { if (szAction.equals(ACTION_BOOT_COMPLETED)) {
AppConfigs appConfigs = AppConfigs.getInstance(context).loadAppConfigs(context); AppConfigs appConfigs = AppConfigs.loadAppConfigs(context);
if (appConfigs.isEnableService()) { if (appConfigs.isEnableService()) {
Intent intentService = new Intent(context, MainService.class); Intent intentService = new Intent(context, MainService.class);
//intentService.putExtra(MainService.EXTRA_APKFILEPATH, appConfigs.getWatchingFilePath()); //intentService.putExtra(MainService.EXTRA_APKFILEPATH, appConfigs.getWatchingFilePath());

View File

@@ -6,7 +6,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.IBinder; import android.os.IBinder;
import cc.winboll.studio.autoinstaller.models.AppConfigs; import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.utils.ServiceUtil; import cc.winboll.studio.autoinstaller.utils.ServiceUtil;
/** /**
@@ -46,7 +46,7 @@ public class AssistantService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
//LogUtils.d(TAG, "call onStartCommand(...)"); //LogUtils.d(TAG, "call onStartCommand(...)");
run(); run();
AppConfigs appConfigs = AppConfigs.getInstance(AssistantService.this).loadAppConfigs(AssistantService.this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(AssistantService.this);
return appConfigs.isEnableService() ? Service.START_STICKY: super.onStartCommand(intent, flags, startId); return appConfigs.isEnableService() ? Service.START_STICKY: super.onStartCommand(intent, flags, startId);
} }
@@ -68,7 +68,7 @@ public class AssistantService extends Service {
// //
void run() { void run() {
//LogUtils.d(TAG, "call run()"); //LogUtils.d(TAG, "call run()");
AppConfigs appConfigs = AppConfigs.getInstance(AssistantService.this).loadAppConfigs(AssistantService.this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(AssistantService.this);
if (appConfigs.isEnableService()) { if (appConfigs.isEnableService()) {
if (mIsThreadAlive == false) { if (mIsThreadAlive == false) {
// 设置运行状态 // 设置运行状态
@@ -101,7 +101,7 @@ public class AssistantService extends Service {
@Override @Override
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
//LogUtils.d(TAG, "call onServiceDisconnected(...)"); //LogUtils.d(TAG, "call onServiceDisconnected(...)");
AppConfigs appConfigs = AppConfigs.getInstance(AssistantService.this).loadAppConfigs(AssistantService.this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(AssistantService.this);
if (appConfigs.isEnableService()) { if (appConfigs.isEnableService()) {
wakeupAndBindMain(); wakeupAndBindMain();
} }

View File

@@ -10,32 +10,25 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import android.widget.Toast; import android.widget.Toast;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.autoinstaller.FileListener; import cc.winboll.studio.autoinstaller.FileListener;
import cc.winboll.studio.autoinstaller.MainActivity; import cc.winboll.studio.autoinstaller.MainActivity;
import cc.winboll.studio.autoinstaller.R; import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.models.APKModel;
import cc.winboll.studio.autoinstaller.models.AppConfigs;
import cc.winboll.studio.autoinstaller.services.AssistantService; import cc.winboll.studio.autoinstaller.services.AssistantService;
import cc.winboll.studio.autoinstaller.services.MainService; import cc.winboll.studio.autoinstaller.services.MainService;
import cc.winboll.studio.autoinstaller.utils.NotificationUtil; import cc.winboll.studio.autoinstaller.utils.NotificationUtil;
import cc.winboll.studio.autoinstaller.utils.PackageUtil; import cc.winboll.studio.autoinstaller.utils.PackageUtil;
import cc.winboll.studio.autoinstaller.utils.ServiceUtil; import cc.winboll.studio.autoinstaller.utils.ServiceUtil;
import cc.winboll.studio.libappbase.LogUtils; import com.hjq.toast.ToastUtils;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList;
public class MainService extends Service { public class MainService extends Service {
public static String TAG = "MainService"; public static String TAG = "MainService";
Context mContext;
ArrayList<APKModel> _APKModelList = new ArrayList<APKModel>();
private static boolean _mIsServiceAlive; private static boolean _mIsServiceAlive;
//String mszAPKFilePath; //String mszAPKFilePath;
//String mszAPKFileName; //String mszAPKFileName;
@@ -54,7 +47,6 @@ public class MainService extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
mContext = this;
LogUtils.d(TAG, "onCreate()"); LogUtils.d(TAG, "onCreate()");
_mIsServiceAlive = false; _mIsServiceAlive = false;
mHandler = new MyHandler(MainService.this); mHandler = new MyHandler(MainService.this);
@@ -63,14 +55,11 @@ public class MainService extends Service {
} }
run(); run();
// 初始化磁贴工具服务
MainTileService mainTileService = new MainTileService(this);
} }
private void run() { private void run() {
AppConfigs appConfigs = AppConfigs.getInstance(MainService.this).loadAppConfigs(MainService.this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(MainService.this);
if (appConfigs.isEnableService()) { if (appConfigs.isEnableService()) {
if (_mIsServiceAlive == false) { if (_mIsServiceAlive == false) {
// 设置运行状态 // 设置运行状态
@@ -85,8 +74,7 @@ public class MainService extends Service {
startWatchingFile(appConfigs.getWatchingFilePath()); startWatchingFile(appConfigs.getWatchingFilePath());
//LogUtils.d(TAG, "running..."); LogUtils.d(TAG, "running...");
//ToastUtils.show("running...");
} else { } else {
LogUtils.d(TAG, "_mIsServiceAlive is " + Boolean.toString(_mIsServiceAlive)); LogUtils.d(TAG, "_mIsServiceAlive is " + Boolean.toString(_mIsServiceAlive));
@@ -106,7 +94,6 @@ public class MainService extends Service {
} }
_mIsServiceAlive = false; _mIsServiceAlive = false;
LogUtils.d(TAG, "onDestroy()"); LogUtils.d(TAG, "onDestroy()");
mContext = null;
} }
@Override @Override
@@ -114,7 +101,7 @@ public class MainService extends Service {
LogUtils.d(TAG, "onStartCommand"); LogUtils.d(TAG, "onStartCommand");
run(); run();
AppConfigs appConfigs = AppConfigs.getInstance(MainService.this).loadAppConfigs(MainService.this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(MainService.this);
return appConfigs.isEnableService() ? Service.START_STICKY: super.onStartCommand(intent, flags, startId); return appConfigs.isEnableService() ? Service.START_STICKY: super.onStartCommand(intent, flags, startId);
} }
@@ -131,7 +118,7 @@ public class MainService extends Service {
@Override @Override
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
//LogUtils.d(TAG, "call onServiceConnected(...)"); //LogUtils.d(TAG, "call onServiceConnected(...)");
AppConfigs appConfigs = AppConfigs.getInstance(MainService.this).loadAppConfigs(MainService.this); AppConfigs appConfigs = AppConfigs.loadAppConfigs(MainService.this);
if (appConfigs.isEnableService()) { if (appConfigs.isEnableService()) {
// 唤醒守护进程 // 唤醒守护进程
wakeupAndBindAssistant(); wakeupAndBindAssistant();
@@ -173,7 +160,7 @@ public class MainService extends Service {
}); });
mFileListener.startWatching(); mFileListener.startWatching();
//ToastUtils.show("Start watching."); ToastUtils.show("Start watching.");
} else { } else {
// 父级文件夹不存在,就提示用户 // 父级文件夹不存在,就提示用户
Toast.makeText(getApplication(), fParentDir.toString() + " no exist.", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplication(), fParentDir.toString() + " no exist.", Toast.LENGTH_SHORT).show();
@@ -189,9 +176,6 @@ public class MainService extends Service {
// 调用[应用信息查看器]打开应用包 // 调用[应用信息查看器]打开应用包
// //
private void installAPK(String szAPKFilePath) { private void installAPK(String szAPKFilePath) {
String szAPKPackageName = PackageUtil.getPackageNameFromApk(this, szAPKFilePath);
saveAPKInfo(szAPKPackageName);
long nTimeNow = System.currentTimeMillis(); long nTimeNow = System.currentTimeMillis();
/*SimpleDateFormat dateFormat = new SimpleDateFormat( /*SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()); "yyyy-MM-dd HH:mm:ss", Locale.getDefault());
@@ -226,24 +210,15 @@ public class MainService extends Service {
// //
void installAPK2(String szAPKFilePath) { void installAPK2(String szAPKFilePath) {
LogUtils.d(TAG, "installAPK2()"); LogUtils.d(TAG, "installAPK2()");
String szAPKPackageName = PackageUtil.getPackageNameFromApk(this, szAPKFilePath);
saveAPKInfo(szAPKPackageName);
Intent intent = new Intent(this, MainActivity.class); Intent intent = new Intent(this, MainActivity.class);
intent.setAction(MainActivity.ACTION_NEW_INSTALLTASK); intent.setAction(MainActivity.ACTION_NEW_INSTALLTASK);
intent.putExtra(MainActivity.EXTRA_INSTALLED_PACKAGENAME, szAPKPackageName); intent.putExtra(MainActivity.EXTRA_INSTALLED_PACKAGENAME, PackageUtil.getPackageNameFromApk(this, szAPKFilePath));
intent.putExtra(MainActivity.EXTRA_INSTALLED_APKFILEPATH, szAPKFilePath); intent.putExtra(MainActivity.EXTRA_INSTALLED_APKFILEPATH, szAPKFilePath);
// Intent.ACTION_VIEW); // Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent); this.startActivity(intent);
} }
void saveAPKInfo(String szApkPackageName) {
APKModel.loadBeanList(this, _APKModelList, APKModel.class);
_APKModelList.add(new APKModel(szApkPackageName));
APKModel.saveBeanList(this, _APKModelList, APKModel.class);
}
// //
// //
static class MyHandler extends Handler { static class MyHandler extends Handler {
@@ -256,7 +231,7 @@ public class MainService extends Service {
switch (message.what) { switch (message.what) {
case MSG_INSTALL_APK: case MSG_INSTALL_APK:
{ {
AppConfigs appConfigs = AppConfigs.getInstance(theActivity).loadAppConfigs(theActivity); AppConfigs appConfigs = AppConfigs.loadAppConfigs(theActivity);
if (appConfigs.getSetupMode() == AppConfigs.SetupMode.WATCHOUTPUTINSTALLER) { if (appConfigs.getSetupMode() == AppConfigs.SetupMode.WATCHOUTPUTINSTALLER) {
theActivity.installAPK2((String)message.obj); theActivity.installAPK2((String)message.obj);
} else if (appConfigs.getSetupMode() == AppConfigs.SetupMode.NEWAPKINFONEWAPKINFO) { } else if (appConfigs.getSetupMode() == AppConfigs.SetupMode.NEWAPKINFONEWAPKINFO) {
@@ -270,21 +245,4 @@ public class MainService extends Service {
super.handleMessage(message); super.handleMessage(message);
} }
} }
static class MainTileService extends TileService {
Context mContext;
MainTileService(Context context) {
mContext = context;
}
@Override
public void onStartListening() {
super.onStartListening();
Tile tile = getQsTile();
tile.setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.ic_android));
// 更新磁贴状态
tile.setState((mContext == null || mContext.getApplicationContext() == null )?Tile.STATE_INACTIVE: Tile.STATE_ACTIVE);
tile.updateTile();
}
}
} }

View File

@@ -55,9 +55,8 @@ public class NotificationUtil {
Notification mForegroundNotification = new Notification.Builder(service, szServiceChannelID) Notification mForegroundNotification = new Notification.Builder(service, szServiceChannelID)
.setAutoCancel(true) .setAutoCancel(true)
//.setContentTitle(service.getString(R.string.app_name)) .setContentTitle(service.getString(R.string.app_name))
.setContentTitle(service.TAG + " is started.") .setContentText(service.TAG + " is started.")
//.setContentText(service.TAG + " is started.")
.setWhen(System.currentTimeMillis()) .setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher) .setSmallIcon(R.drawable.ic_launcher)
//设置红色 //设置红色

View File

@@ -6,11 +6,9 @@ package cc.winboll.studio.autoinstaller.utils;
* @Describe 一个获取安卓APK安装文件的应用包名的函数 * @Describe 一个获取安卓APK安装文件的应用包名的函数
*/ */
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.libappbase.LogUtils;
public class PackageUtil { public class PackageUtil {
@@ -29,20 +27,4 @@ public class PackageUtil {
} }
return ""; return "";
} }
public static void openAPP(Context context, String packageName) {
// 这里假设要打开微信微信的包名是com.tencent.mm
//String packageName = "com.tencent.mm";
LogUtils.d(TAG, "packageName : " + packageName);
PackageManager packageManager = context.getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
if (intent != null) {
ResolveInfo resolveInfo = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfo != null) {
LogUtils.d(TAG, "startActivity...");
context.startActivity(intent);
}
}
}
} }

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FF000000"
android:pathData="M16.61,15.15C16.15,15.15 15.77,14.78 15.77,14.32S16.15,13.5 16.61,13.5H16.61C17.07,13.5 17.45,13.86 17.45,14.32C17.45,14.78 17.07,15.15 16.61,15.15M7.41,15.15C6.95,15.15 6.57,14.78 6.57,14.32C6.57,13.86 6.95,13.5 7.41,13.5H7.41C7.87,13.5 8.24,13.86 8.24,14.32C8.24,14.78 7.87,15.15 7.41,15.15M16.91,10.14L18.58,7.26C18.67,7.09 18.61,6.88 18.45,6.79C18.28,6.69 18.07,6.75 18,6.92L16.29,9.83C14.95,9.22 13.5,8.9 12,8.91C10.47,8.91 9,9.24 7.73,9.82L6.04,6.91C5.95,6.74 5.74,6.68 5.57,6.78C5.4,6.87 5.35,7.08 5.44,7.25L7.1,10.13C4.25,11.69 2.29,14.58 2,18H22C21.72,14.59 19.77,11.7 16.91,10.14H16.91Z"/>
</vector>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#ff000000"
android:pathData="M6.5,20Q4.22,20 2.61,18.43 1,16.85 1,14.58 1,12.63 2.17,11.1 3.35,9.57 5.25,9.15 5.88,6.85 7.75,5.43 9.63,4 12,4 14.93,4 16.96,6.04 19,8.07 19,11 20.73,11.2 21.86,12.5 23,13.78 23,15.5 23,17.38 21.69,18.69 20.38,20 18.5,20Z"/>
</vector>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#ff000000"
android:pathData="M6.5,20Q4.22,20 2.61,18.43 1,16.85 1,14.58 1,12.63 2.17,11.1 3.35,9.57 5.25,9.15 5.88,6.85 7.75,5.43 9.63,4 12,4 14.93,4 16.96,6.04 19,8.07 19,11 20.73,11.2 21.86,12.5 23,13.78 23,15.5 23,17.38 21.69,18.69 20.38,20 18.5,20M6.5,18H18.5Q19.55,18 20.27,17.27 21,16.55 21,15.5 21,14.45 20.27,13.73 19.55,13 18.5,13H17V11Q17,8.93 15.54,7.46 14.08,6 12,6 9.93,6 8.46,7.46 7,8.93 7,11H6.5Q5.05,11 4.03,12.03 3,13.05 3,14.5 3,15.95 4.03,17 5.05,18 6.5,18M12,12Z"/>
</vector>

View File

@@ -132,7 +132,7 @@
</LinearLayout> </LinearLayout>
<cc.winboll.studio.libappbase.LogView <cc.winboll.studio.shared.log.LogView
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="200dp" android:layout_height="200dp"

View File

@@ -1,4 +1,3 @@
<resources> <resources>
<string name="app_name">AutoInstaller</string> <string name="app_name">AutoInstaller</string>
<string name="tileservice_name">AutoInstaller</string>
</resources> </resources>

View File

@@ -1,13 +0,0 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="MyAppTheme" parent="APPBaseTheme">
<item name="attrColorPrimary">@color/colorPrimary</item>
<item name="themeGlobalCrashActivity">@style/MyGlobalCrashActivityTheme</item>
</style>
<style name="MyGlobalCrashActivityTheme" parent="GlobalCrashActivityTheme">
<item name="colorTittle">#FFFFFFFF</item>
<item name="colorTittleBackgound">#FF00A4B3</item>
<item name="colorText">#FFFFFFFF</item>
<item name="colorTextBackgound">#FF000000</item>
</style>
</resources>

View File

@@ -0,0 +1,14 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Application" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="android:colorPrimary">@color/purple_500</item>
<!-- Secondary brand color. -->
<item name="android:colorSecondary">@color/teal_200</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">@color/purple_700</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -1,15 +1,12 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
repositories { repositories {
mavenLocal { // 本地 Maven 仓库(默认路径为 ~/.m2/repository
// 设置本地Maven仓库路径 //mavenLocal()
url 'file:///sdcard/.m2/repository/' // 或自定义本地仓库路径
} //maven { url "file:///sdcard/.m2/repository" }
// Nexus Maven 库地址 // 或自定义本地仓库路径
// "WinBoLL Release" //maven { url "file:///sdcard/ZhanGSKen/AIDE/MavenReps/repository" }
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoLL Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
maven { url 'https://maven.aliyun.com/repository/public/' } maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' } maven { url 'https://maven.aliyun.com/repository/google/' }
@@ -19,13 +16,13 @@ buildscript {
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
mavenCentral() mavenCentral()
google() google()
//println "mavenLocal : ==========="
//println mavenLocal().url
//println "mavenLocal : ==========="
//mavenLocal() //mavenLocal()
// WinBoLL.CC 紧急备用 Maven // Nexus Maven 库地址
maven { url 'https://spare-maven.winboll.cc/repository/' } // "WinBoll Release"
maven { url "https://192.168.123.26:8801/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://192.168.123.26:8801/repository/maven-snapshots/" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.2.1' // 对应 compileSdkVersion 32 classpath 'com.android.tools.build:gradle:7.2.1' // 对应 compileSdkVersion 32
@@ -36,16 +33,12 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
mavenLocal { // 本地 Maven 仓库(默认路径为 ~/.m2/repository
// 设置本地Maven仓库路径 //mavenLocal()
url 'file:///sdcard/.m2/repository/' // 或自定义本地仓库路径
} //maven { url "file:///sdcard/.m2/repository" }
// 或自定义本地仓库路径
// Nexus Maven 库地址 //maven { url "file:///sdcard/ZhanGSKen/AIDE/MavenReps/repository" }
// "WinBoLL Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoLL Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
maven { url 'https://maven.aliyun.com/repository/public/' } maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' } maven { url 'https://maven.aliyun.com/repository/google/' }
@@ -55,13 +48,13 @@ allprojects {
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
mavenCentral() mavenCentral()
google() google()
//println "mavenLocal : ===========" mavenLocal()
//println mavenLocal().url
//println "mavenLocal : ==========="
//mavenLocal()
// WinBoLL.CC 紧急备用 Maven // Nexus Maven 库地址
maven { url 'https://spare-maven.winboll.cc/repository/' } // "WinBoll Release"
maven { url "https://192.168.123.26:8801/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://192.168.123.26:8801/repository/maven-snapshots/" }
} }
ext { ext {
// 定义全局变量,常用于版本管理 // 定义全局变量,常用于版本管理
@@ -72,6 +65,7 @@ allprojects {
bashCommitAppPublishBuildFlagInfoFilePath = ".winboll/bashCommitAppPublishBuildFlagInfo.sh" bashCommitAppPublishBuildFlagInfoFilePath = ".winboll/bashCommitAppPublishBuildFlagInfo.sh"
winbollFilePath = "winboll.properties" winbollFilePath = "winboll.properties"
//keyPropsFilePath = "winboll-x/current.keystore"
keyPropsFilePath = "current.keystore" keyPropsFilePath = "current.keystore"
// 定义 lint 输出文件 // 定义 lint 输出文件
lintXmlReportFilePath = "build/reports/lint-results.xml" lintXmlReportFilePath = "build/reports/lint-results.xml"

View File

@@ -9,7 +9,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 29
} }
buildTypes { buildTypes {
release { release {
@@ -21,9 +21,6 @@ android {
dependencies { dependencies {
api fileTree(dir: 'libs', include: ['*.jar']) api fileTree(dir: 'libs', include: ['*.jar'])
//api 'cc.winboll.studio:libaes:15.6.0'
api 'cc.winboll.studio:libapputils:15.3.4'
api 'cc.winboll.studio:libappbase:15.7.6'
// 吐司类库 // 吐司类库
api 'com.github.getActivity:ToastUtils:10.5' api 'com.github.getActivity:ToastUtils:10.5'
@@ -48,9 +45,12 @@ dependencies {
api 'com.squareup.okhttp3:okhttp:4.4.1' api 'com.squareup.okhttp3:okhttp:4.4.1'
// AndroidX 类库 // AndroidX 类库
api 'androidx.appcompat:appcompat:1.1.0' api 'androidx.appcompat:appcompat:1.1.0'
//api 'com.google.android.material:material:1.4.0' api 'com.google.android.material:material:1.4.0'
//api 'androidx.viewpager:viewpager:1.0.0' //api 'androidx.viewpager:viewpager:1.0.0'
//api 'androidx.vectordrawable:vectordrawable:1.1.0' //api 'androidx.vectordrawable:vectordrawable:1.1.0'
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0' //api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
//api 'androidx.fragment:fragment:1.1.0' //api 'androidx.fragment:fragment:1.1.0'
api 'cc.winboll.studio:libapputils:15.2.2'
api 'cc.winboll.studio:libappbase:15.2.2'
} }

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Mon May 12 18:10:35 HKT 2025 #Thu Apr 03 11:13:53 HKT 2025
stageCount=4 stageCount=7
libraryProject=libaes libraryProject=libaes
baseVersion=15.6 baseVersion=15.2
publishVersion=15.6.3 publishVersion=15.2.6
buildCount=0 buildCount=0
baseBetaVersion=15.6.4 baseBetaVersion=15.2.7

View File

@@ -5,34 +5,27 @@
<application> <application>
<activity <activity android:name="cc.winboll.studio.libaes.unittests.SecondaryLibraryActivity"
android:name="cc.winboll.studio.libaes.unittests.SecondaryLibraryActivity"
android:exported="true"/> android:exported="true"/>
<activity <activity android:name="cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity"
android:name="cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity"
android:exported="true"/> android:exported="true"/>
<activity <activity android:name="cc.winboll.studio.libaes.unittests.TestAToolbarActivity"
android:name="cc.winboll.studio.libaes.unittests.TestAToolbarActivity"
android:exported="true"/> android:exported="true"/>
<activity <activity android:name="cc.winboll.studio.libaes.unittests.TestASupportToolbarActivity"
android:name="cc.winboll.studio.libaes.unittests.TestASupportToolbarActivity"
android:exported="true"/> android:exported="true"/>
<service <service android:name="cc.winboll.studio.libaes.winboll.WinBollClientService"
android:name="cc.winboll.studio.libaes.winboll.WinBoLLClientService"
android:exported="true"/> android:exported="true"/>
<service <service android:name="cc.winboll.studio.libaes.winboll.AssistantService"
android:name="cc.winboll.studio.libaes.winboll.AssistantService"
android:exported="true"/> android:exported="true"/>
<service <service android:name="cc.winboll.studio.libaes.winboll.WinBollMail"
android:name="cc.winboll.studio.libaes.winboll.WinBoLLMail"
android:exported="true"/> android:exported="true"/>
</application> </application>
</manifest> </manifest>

View File

@@ -29,11 +29,11 @@ import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libaes.views.ADrawerMenuListView; import cc.winboll.studio.libaes.views.ADrawerMenuListView;
import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import com.baoyz.widget.PullRefreshLayout; import com.baoyz.widget.PullRefreshLayout;
import java.util.ArrayList; import java.util.ArrayList;
public abstract class DrawerFragmentActivity extends AppCompatActivity implements IWinBoLLActivity,AdapterView.OnItemClickListener { public abstract class DrawerFragmentActivity extends AppCompatActivity implements IWinBollActivity,AdapterView.OnItemClickListener {
public static final String TAG = "DrawerFragmentActivity"; public static final String TAG = "DrawerFragmentActivity";
@@ -177,7 +177,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
getString(i); getString(i);
} }
} else if (R.id.item_log == item.getItemId()) { } else if (R.id.item_log == item.getItemId()) {
GlobalApplication.getWinBoLLActivityManager().startLogActivity(this); GlobalApplication.getWinBollActivityManager().startLogActivity(this);
} else if (R.id.item_about == item.getItemId()) { } else if (R.id.item_about == item.getItemId()) {
LogUtils.d(TAG, "onAbout"); LogUtils.d(TAG, "onAbout");
} else if (android.R.id.home == item.getItemId()) { } else if (android.R.id.home == item.getItemId()) {

View File

@@ -7,14 +7,14 @@ import android.view.MenuItem;
import android.widget.Toast; import android.widget.Toast;
import cc.winboll.studio.libaes.R; import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity; import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
/** /**
* @Author ZhanGSKen@QQ.COM * @Author ZhanGSKen@QQ.COM
* @Date 2024/06/15 00:58:10 * @Date 2024/06/15 00:58:10
* @Describe 第二级窗口 * @Describe 第二级窗口
*/ */
public class SecondaryLibraryActivity extends DrawerFragmentActivity implements IWinBoLLActivity { public class SecondaryLibraryActivity extends DrawerFragmentActivity implements IWinBollActivity {
public static final String TAG = "SecondaryLibraryActivity"; public static final String TAG = "SecondaryLibraryActivity";

View File

@@ -11,9 +11,9 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libaes.R; import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.utils.AESThemeUtil; import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
public class TestASupportToolbarActivity extends AppCompatActivity implements IWinBoLLActivity { public class TestASupportToolbarActivity extends AppCompatActivity implements IWinBollActivity {
public static final String TAG = "TestASupportToolbarActivity"; public static final String TAG = "TestASupportToolbarActivity";

View File

@@ -10,9 +10,9 @@ import android.os.Bundle;
import android.widget.Toolbar; import android.widget.Toolbar;
import cc.winboll.studio.libaes.R; import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.utils.AESThemeUtil; import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
public class TestAToolbarActivity extends Activity implements IWinBoLLActivity { public class TestAToolbarActivity extends Activity implements IWinBollActivity {
public static final String TAG = "TestAToolbarActivity"; public static final String TAG = "TestAToolbarActivity";

View File

@@ -11,15 +11,16 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import cc.winboll.studio.libaes.R; import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity; import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
import cc.winboll.studio.libaes.beans.DrawerMenuBean; import cc.winboll.studio.libaes.beans.DrawerMenuBean;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import java.util.ArrayList; import java.util.ArrayList;
public class TestDrawerFragmentActivity extends DrawerFragmentActivity implements IWinBoLLActivity { public class TestDrawerFragmentActivity extends DrawerFragmentActivity implements IWinBollActivity {
@Override @Override
public Activity getActivity() { public Activity getActivity() {

View File

@@ -41,7 +41,7 @@ public class AESThemeUtil {
activity.setTheme(getThemeTypeID(activity)); activity.setTheme(getThemeTypeID(activity));
} }
/*public static <T extends WinBoLLActivity> void applyWinBoLLTheme(T activity) { /*public static <T extends WinBollActivity> void applyWinBollTheme(T activity) {
activity.setTheme(getThemeTypeID(activity.getApplicationContext())); activity.setTheme(getThemeTypeID(activity.getApplicationContext()));
}*/ }*/
@@ -53,7 +53,7 @@ public class AESThemeUtil {
activity.setTheme(AESThemeBean.getThemeStyleID(themeType)); activity.setTheme(AESThemeBean.getThemeStyleID(themeType));
} }
/*public static <T extends WinBoLLActivity> void applyWinBoLLTheme(Activity activity, AESThemeBean.ThemeType themeType) { /*public static <T extends WinBollActivity> void applyWinBollTheme(Activity activity, AESThemeBean.ThemeType themeType) {
activity.setTheme(AESThemeBean.getThemeStyleID(themeType)); activity.setTheme(AESThemeBean.getThemeStyleID(themeType));
}*/ }*/
@@ -65,7 +65,7 @@ public class AESThemeUtil {
activity.getMenuInflater().inflate(R.menu.toolbar_apptheme, menu); activity.getMenuInflater().inflate(R.menu.toolbar_apptheme, menu);
} }
/*public static <T extends WinBoLLActivity> void inflateWinBoLLMenu(T activity, Menu menu) { /*public static <T extends WinBollActivity> void inflateWinBollMenu(T activity, Menu menu) {
activity.getMenuInflater().inflate(R.menu.toolbar_apptheme, menu); activity.getMenuInflater().inflate(R.menu.toolbar_apptheme, menu);
}*/ }*/
@@ -131,7 +131,7 @@ public class AESThemeUtil {
return false; return false;
} }
public static <T extends AppCompatActivity> boolean onWinBoLLThemeItemSelected(T activity, MenuItem item) { public static <T extends AppCompatActivity> boolean onWinBollThemeItemSelected(T activity, MenuItem item) {
int nThemeStyleID; int nThemeStyleID;
if (R.id.item_depththeme == item.getItemId()) { if (R.id.item_depththeme == item.getItemId()) {
nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEPTH); nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEPTH);
@@ -162,7 +162,7 @@ public class AESThemeUtil {
return false; return false;
} }
public static <T extends DrawerFragmentActivity> boolean onWinBoLLThemeItemSelected(T activity, MenuItem item) { public static <T extends DrawerFragmentActivity> boolean onWinBollThemeItemSelected(T activity, MenuItem item) {
int nThemeStyleID; int nThemeStyleID;
if (R.id.item_depththeme == item.getItemId()) { if (R.id.item_depththeme == item.getItemId()) {
nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEPTH); nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEPTH);

View File

@@ -3,7 +3,7 @@ package cc.winboll.studio.libaes.winboll;
/** /**
* @Author ZhanGSKen@AliYun.Com * @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/24 15:08:52 * @Date 2025/03/24 15:08:52
* @Describe WinBoLL应用介绍视图 * @Describe WinBoll应用介绍视图
*/ */
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -43,7 +43,7 @@ public class AboutView extends LinearLayout {
Context mContext; Context mContext;
APPInfo mAPPInfo; APPInfo mAPPInfo;
WinBoLLServiceStatusView mWinBoLLServiceStatusView; WinBollServiceStatusView mWinBollServiceStatusView;
OnRequestDevUserInfoAutofillListener mOnRequestDevUserInfoAutofillListener; OnRequestDevUserInfoAutofillListener mOnRequestDevUserInfoAutofillListener;
String mszAppName = ""; String mszAppName = "";
String mszAppAPKFolderName = ""; String mszAppAPKFolderName = "";
@@ -57,7 +57,7 @@ public class AboutView extends LinearLayout {
String mszHomePage = ""; String mszHomePage = "";
String mszGitea = ""; String mszGitea = "";
int mnAppIcon = 0; int mnAppIcon = 0;
String mszWinBoLLServerHost; String mszWinBollServerHost;
String mszReleaseAPKName; String mszReleaseAPKName;
EditText metDevUserName; EditText metDevUserName;
EditText metDevUserPassword; EditText metDevUserPassword;
@@ -107,7 +107,7 @@ public class AboutView extends LinearLayout {
mszAppDescription = mAPPInfo.getAppDescription(); mszAppDescription = mAPPInfo.getAppDescription();
mnAppIcon = mAPPInfo.getAppIcon(); mnAppIcon = mAPPInfo.getAppIcon();
mszWinBoLLServerHost = GlobalApplication.isDebuging() ? "https://dev.winboll.cc": "https://www.winboll.cc"; mszWinBollServerHost = GlobalApplication.isDebuging() ? "https://dev.winboll.cc": "https://www.winboll.cc";
try { try {
mszAppVersionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName; mszAppVersionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
@@ -115,7 +115,7 @@ public class AboutView extends LinearLayout {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
} }
mszCurrentAppPackageName = mszAppAPKName + "_" + mszAppVersionName + ".apk"; mszCurrentAppPackageName = mszAppAPKName + "_" + mszAppVersionName + ".apk";
mszHomePage = mszWinBoLLServerHost + "/studio/details.php?app=" + mszAppAPKFolderName; mszHomePage = mszWinBollServerHost + "/studio/details.php?app=" + mszAppAPKFolderName;
if (mAPPInfo.getAppGitAPPBranch().equals("")) { if (mAPPInfo.getAppGitAPPBranch().equals("")) {
mszGitea = "https://gitea.winboll.cc/" + mAPPInfo.getAppGitOwner() + "/" + mszAppGitName; mszGitea = "https://gitea.winboll.cc/" + mAPPInfo.getAppGitOwner() + "/" + mszAppGitName;
} else { } else {
@@ -132,9 +132,9 @@ public class AboutView extends LinearLayout {
metDevUserName.setText(PrefUtils.getString(mContext, "metDevUserName", "")); metDevUserName.setText(PrefUtils.getString(mContext, "metDevUserName", ""));
metDevUserPassword.setText(PrefUtils.getString(mContext, "metDevUserPassword", "")); metDevUserPassword.setText(PrefUtils.getString(mContext, "metDevUserPassword", ""));
//mDevelopHostConnectionStatusView = new DevelopHostConnectionStatusView(context); //mDevelopHostConnectionStatusView = new DevelopHostConnectionStatusView(context);
mWinBoLLServiceStatusView = addedView.findViewById(R.id.viewaboutdevWinBoLLServiceStatusView1); mWinBollServiceStatusView = addedView.findViewById(R.id.viewaboutdevWinBollServiceStatusView1);
mWinBoLLServiceStatusView.setServerHost(mszWinBoLLServerHost); mWinBollServiceStatusView.setServerHost(mszWinBollServerHost);
mWinBoLLServiceStatusView.setAuthInfo(metDevUserName.getText().toString(), metDevUserPassword.getText().toString()); mWinBollServiceStatusView.setAuthInfo(metDevUserName.getText().toString(), metDevUserPassword.getText().toString());
//llMain.addView(mDevelopHostConnectionStatusView); //llMain.addView(mDevelopHostConnectionStatusView);
llMain.addView(createAboutPage()); llMain.addView(createAboutPage());
addView(addedView); addView(addedView);
@@ -143,9 +143,9 @@ public class AboutView extends LinearLayout {
View addedView = inflater.inflate(R.layout.view_about_www, this, false); View addedView = inflater.inflate(R.layout.view_about_www, this, false);
LinearLayout llMain = addedView.findViewById(R.id.viewaboutwwwLinearLayout1); LinearLayout llMain = addedView.findViewById(R.id.viewaboutwwwLinearLayout1);
//mDevelopHostConnectionStatusView = new DevelopHostConnectionStatusView(context); //mDevelopHostConnectionStatusView = new DevelopHostConnectionStatusView(context);
mWinBoLLServiceStatusView = addedView.findViewById(R.id.viewaboutwwwWinBoLLServiceStatusView1); mWinBollServiceStatusView = addedView.findViewById(R.id.viewaboutwwwWinBollServiceStatusView1);
mWinBoLLServiceStatusView.setServerHost(mszWinBoLLServerHost); mWinBollServiceStatusView.setServerHost(mszWinBollServerHost);
mWinBoLLServiceStatusView.setAuthInfo("", ""); mWinBollServiceStatusView.setAuthInfo("", "");
//llMain.addView(mDevelopHostConnectionStatusView); //llMain.addView(mDevelopHostConnectionStatusView);
llMain.addView(createAboutPage()); llMain.addView(createAboutPage());
addView(addedView); addView(addedView);
@@ -291,7 +291,7 @@ public class AboutView extends LinearLayout {
GlobalApplication.setIsDebuging(true); GlobalApplication.setIsDebuging(true);
GlobalApplication.saveDebugStatus(); GlobalApplication.saveDebugStatus();
GlobalApplication.getWinBoLLActivityManager().finishAll(); GlobalApplication.getWinBollActivityManager().finishAll();
context.startActivity(intent); context.startActivity(intent);
} }
} }
@@ -303,7 +303,7 @@ public class AboutView extends LinearLayout {
GlobalApplication.setIsDebuging(false); GlobalApplication.setIsDebuging(false);
GlobalApplication.saveDebugStatus(); GlobalApplication.saveDebugStatus();
GlobalApplication.getWinBoLLActivityManager().finishAll(); GlobalApplication.getWinBollActivityManager().finishAll();
context.startActivity(intent); context.startActivity(intent);
} }
} }
@@ -323,7 +323,7 @@ public class AboutView extends LinearLayout {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
String szUrl = mszWinBoLLServerHost + "/studio/details.php?app=" + mszAppAPKFolderName; String szUrl = mszWinBollServerHost + "/studio/details.php?app=" + mszAppAPKFolderName;
// 构建包含认证信息的请求 // 构建包含认证信息的请求
String credential = ""; String credential = "";
if (GlobalApplication.isDebuging()) { if (GlobalApplication.isDebuging()) {
@@ -331,8 +331,8 @@ public class AboutView extends LinearLayout {
PrefUtils.saveString(mContext, "metDevUserName", metDevUserName.getText().toString()); PrefUtils.saveString(mContext, "metDevUserName", metDevUserName.getText().toString());
PrefUtils.saveString(mContext, "metDevUserPassword", metDevUserPassword.getText().toString()); PrefUtils.saveString(mContext, "metDevUserPassword", metDevUserPassword.getText().toString());
} else { } else {
String username = "WinBoLL"; String username = "WinBoll";
String password = "WinBoLLPowerByZhanGSKen"; String password = "WinBollPowerByZhanGSKen";
credential = Credentials.basic(username, password); credential = Credentials.basic(username, password);
} }
@@ -384,7 +384,7 @@ public class AboutView extends LinearLayout {
YesNoAlertDialog.OnDialogResultListener mIsDownlaodUpdateListener = new YesNoAlertDialog.OnDialogResultListener() { YesNoAlertDialog.OnDialogResultListener mIsDownlaodUpdateListener = new YesNoAlertDialog.OnDialogResultListener() {
@Override @Override
public void onYes() { public void onYes() {
String szUrl = mszWinBoLLServerHost + "/studio/download.php?appname=" + mszAppAPKFolderName + "&apkname=" + mszNewestAppPackageName; String szUrl = mszWinBollServerHost + "/studio/download.php?appname=" + mszAppAPKFolderName + "&apkname=" + mszNewestAppPackageName;
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(szUrl)); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(szUrl));
mContext.startActivity(browserIntent); mContext.startActivity(browserIntent);
} }

View File

@@ -11,15 +11,14 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.IBinder; import android.os.IBinder;
import cc.winboll.studio.libaes.beans.WinBoLLClientServiceBean; import cc.winboll.studio.libaes.winboll.WinBollClientService;
import cc.winboll.studio.libaes.winboll.AssistantService;
import cc.winboll.studio.libappbase.utils.ServiceUtils; import cc.winboll.studio.libappbase.utils.ServiceUtils;
public class AssistantService extends Service { public class AssistantService extends Service {
public final static String TAG = "AssistantService"; public final static String TAG = "AssistantService";
WinBoLLClientServiceBean mWinBoLLServiceBean; WinBollClientServiceBean mWinBollServiceBean;
MyServiceConnection mMyServiceConnection; MyServiceConnection mMyServiceConnection;
volatile boolean mIsServiceRunning; volatile boolean mIsServiceRunning;
@@ -31,7 +30,7 @@ public class AssistantService extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
mWinBoLLServiceBean = WinBoLLClientServiceBean.loadWinBoLLClientServiceBean(this); mWinBollServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
if (mMyServiceConnection == null) { if (mMyServiceConnection == null) {
mMyServiceConnection = new MyServiceConnection(); mMyServiceConnection = new MyServiceConnection();
} }
@@ -56,8 +55,8 @@ public class AssistantService extends Service {
// 运行服务内容 // 运行服务内容
// //
void run() { void run() {
mWinBoLLServiceBean = WinBoLLClientServiceBean.loadWinBoLLClientServiceBean(this); mWinBollServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
if (mWinBoLLServiceBean.isEnable()) { if (mWinBollServiceBean.isEnable()) {
if (mIsServiceRunning == false) { if (mIsServiceRunning == false) {
// 设置运行状态 // 设置运行状态
mIsServiceRunning = true; mIsServiceRunning = true;
@@ -71,11 +70,11 @@ public class AssistantService extends Service {
// 唤醒和绑定主进程 // 唤醒和绑定主进程
// //
void wakeupAndBindMain() { void wakeupAndBindMain() {
if (ServiceUtils.isServiceRunning(getApplicationContext(), WinBoLLClientService.class.getName()) == false) { if (ServiceUtils.isServiceRunning(getApplicationContext(), WinBollClientService.class.getName()) == false) {
startForegroundService(new Intent(AssistantService.this, WinBoLLClientService.class)); startForegroundService(new Intent(AssistantService.this, WinBollClientService.class));
} }
bindService(new Intent(AssistantService.this, WinBoLLClientService.class), mMyServiceConnection, Context.BIND_IMPORTANT); bindService(new Intent(AssistantService.this, WinBollClientService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
} }
// //
@@ -88,8 +87,8 @@ public class AssistantService extends Service {
@Override @Override
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
mWinBoLLServiceBean = WinBoLLClientServiceBean.loadWinBoLLClientServiceBean(AssistantService.this); mWinBollServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(AssistantService.this);
if (mWinBoLLServiceBean.isEnable()) { if (mWinBollServiceBean.isEnable()) {
wakeupAndBindMain(); wakeupAndBindMain();
} }
} }

View File

@@ -3,7 +3,7 @@ package cc.winboll.studio.libaes.winboll;
/** /**
* @Author ZhanGSKen@AliYun.Com * @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/28 19:11:27 * @Date 2025/03/28 19:11:27
* @Describe WinBoLL UI 状态图标枚举 * @Describe WinBoll UI 状态图标枚举
*/ */
import cc.winboll.studio.libaes.R; import cc.winboll.studio.libaes.R;

View File

@@ -0,0 +1,17 @@
package cc.winboll.studio.libaes.winboll;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/28 19:08:45
* @Describe WinBollService 服务 Binder。
*/
import android.graphics.drawable.Drawable;
public interface IWinBollClientServiceBinder {
public static final String TAG = "IWinBollClientServiceBinder";
public WinBollClientService getService();
public Drawable getCurrentStatusIconDrawable();
}

View File

@@ -1,38 +0,0 @@
package cc.winboll.studio.libaes.winboll;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
/**
* @Author ZhanGSKen
* @Date 2025/05/03 19:14
*/
public class WinBoLLServiceStatusView extends LinearLayout {
public static final String TAG = "WinBoLLServiceStatusView";
public WinBoLLServiceStatusView(Context context) {
super(context);
}
public WinBoLLServiceStatusView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WinBoLLServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public WinBoLLServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
void setServerHost(String szWinBoLLServerHost) {
}
void setAuthInfo(String szDevUserName, String szDevUserPassword) {
}
}

View File

@@ -0,0 +1,192 @@
package cc.winboll.studio.libaes.winboll;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/28 19:06:54
* @Describe WinBoll 客户端服务
*/
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import cc.winboll.studio.libaes.winboll.AssistantService;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.utils.ServiceUtils;
import cc.winboll.studio.libapputils.utils.PrefUtils;
import com.hjq.toast.ToastUtils;
public class WinBollClientService extends Service implements IWinBollClientServiceBinder {
public static final String TAG = "WinBollClientService";
WinBollClientServiceBean mWinBollClientServiceBean;
MyServiceConnection mMyServiceConnection;
volatile boolean mIsWinBollClientThreadRunning;
volatile boolean mIsEnableService;
volatile WinBollClientThread mWinBollClientThread;
public boolean isWinBollClientThreadRunning() {
return mIsWinBollClientThreadRunning;
}
@Override
public WinBollClientService getService() {
return WinBollClientService.this;
}
@Override
public Drawable getCurrentStatusIconDrawable() {
return mIsWinBollClientThreadRunning ?
getDrawable(EWUIStatusIconDrawable.getIconDrawableId(EWUIStatusIconDrawable.NORMAL))
: getDrawable(EWUIStatusIconDrawable.getIconDrawableId(EWUIStatusIconDrawable.NEWS));
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
//ToastUtils.show("onCreate");
super.onCreate();
mWinBollClientThread = null;
mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
mIsEnableService = mWinBollClientServiceBean.isEnable();
if (mMyServiceConnection == null) {
mMyServiceConnection = new MyServiceConnection();
}
// 由系统启动时,应用可以通过下面函数实例化实际服务进程。
runMainThread();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//ToastUtils.show("onStartCommand");
// 由应用 Intent 启动时,应用可以通过下面函数实例化实际服务进程。
runMainThread();
// 返回运行参数持久化存储后,服务状态控制参数
// 无论 Intent 传入如何,服务状态一直以持久化存储后的参数控制,
// PS: 另外当然可以通过 Intent 传入的指标来修改 mWinBollServiceBean
// 不过本服务的应用方向会变得繁琐,
// 现阶段只要满足手机端启动与停止本服务WinBoll 客户端实例运行在手机端就可以了。
return mIsEnableService ? Service.START_STICKY: super.onStartCommand(intent, flags, startId);
}
synchronized void runMainThread() {
if (mWinBollClientThread == null) {
//ToastUtils.show("runMainThread()");
mWinBollClientThread = new WinBollClientThread();
mWinBollClientThread.start();
}
}
void syncWinBollClientThreadStatus() {
mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
mIsEnableService = mWinBollClientServiceBean.isEnable();
LogUtils.d(TAG, String.format("mIsEnableService %s", mIsEnableService));
}
// 唤醒和绑定守护进程
//
void wakeupAndBindAssistant() {
if (ServiceUtils.isServiceRunning(getApplicationContext(), AssistantService.class.getName()) == false) {
startService(new Intent(WinBollClientService.this, AssistantService.class));
//LogUtils.d(TAG, "call wakeupAndBindAssistant() : Binding... AssistantService");
bindService(new Intent(WinBollClientService.this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
}
}
// 主进程与守护进程连接时需要用到此类
//
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override
public void onServiceDisconnected(ComponentName name) {
mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(WinBollClientService.this);
if (mWinBollClientServiceBean.isEnable()) {
// 唤醒守护进程
wakeupAndBindAssistant();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
//ToastUtils.show("onDestroy");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
void setWinBollServiceEnableStatus(boolean isEnable) {
WinBollClientServiceBean bean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
bean.setIsEnable(isEnable);
WinBollClientServiceBean.saveWinBollServiceBean(this, bean);
}
boolean getWinBollServiceEnableStatus(Context context) {
mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(context);
return mWinBollClientServiceBean.isEnable();
}
/*public interface OnServiceStatusChangeListener {
void onServerStatusChange(boolean isServiceAlive);
}
public void setOnServerStatusChangeListener(OnServiceStatusChangeListener l) {
mOnServerStatusChangeListener = l;
}*/
class WinBollClientThread extends Thread {
@Override
public void run() {
super.run();
LogUtils.d(TAG, "run syncWinBollClientThreadStatus");
syncWinBollClientThreadStatus();
if (mIsEnableService) {
if (mIsWinBollClientThreadRunning == false) {
// 设置运行状态
mIsWinBollClientThreadRunning = true;
LogUtils.d(TAG, "WinBollClientThread run()");
// 唤醒守护进程
//wakeupAndBindAssistant();
while (mIsEnableService) {
// 显示运行状态
WinBollServiceStatusView.startConnection();
LogUtils.d(TAG, String.format("while mIsEnableService is %s", mIsEnableService));
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
syncWinBollClientThreadStatus();
}
// 服务进程退出, 重置进程运行状态
WinBollServiceStatusView.stopConnection();
mIsWinBollClientThreadRunning = false;
mWinBollClientThread = null;
}
}
}
}
}

View File

@@ -1,8 +1,9 @@
package cc.winboll.studio.libaes.beans; package cc.winboll.studio.libaes.winboll;
/** /**
* @Author ZhanGSKen * @Author ZhanGSKen@AliYun.Com
* @Date 2025/05/03 19:16 * @Date 2025/03/28 19:05:15
* @Describe WinBollService 运行参数配置
*/ */
import android.content.Context; import android.content.Context;
import android.util.JsonReader; import android.util.JsonReader;
@@ -10,19 +11,14 @@ import android.util.JsonWriter;
import cc.winboll.studio.libappbase.BaseBean; import cc.winboll.studio.libappbase.BaseBean;
import java.io.IOException; import java.io.IOException;
public class WinBoLLClientServiceBean extends BaseBean { public class WinBollClientServiceBean extends BaseBean {
public static final String TAG = "WinBoLLClientServiceBean"; public static final String TAG = "WinBollClientServiceBean";
// 服务是否正在使用中
boolean isEnable;
public WinBoLLClientServiceBean() {
this.isEnable = false;
}
public WinBoLLClientServiceBean(boolean isEnable) { volatile boolean isEnable;
this.isEnable = isEnable;
public WinBollClientServiceBean() {
isEnable = false;
} }
public void setIsEnable(boolean isEnable) { public void setIsEnable(boolean isEnable) {
@@ -33,27 +29,26 @@ public class WinBoLLClientServiceBean extends BaseBean {
return isEnable; return isEnable;
} }
@Override @Override
public String getName() { public String getName() {
return WinBoLLClientServiceBean.class.getName(); return WinBollClientServiceBean.class.getName();
} }
@Override @Override
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
super.writeThisToJsonWriter(jsonWriter); super.writeThisToJsonWriter(jsonWriter);
WinBoLLClientServiceBean bean = this; WinBollClientServiceBean bean = this;
//jsonWriter.name("logLevel").value(bean.getLogLevel().ordinal()); jsonWriter.name("isEnable").value(bean.isEnable());
} }
@Override @Override
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException { public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else { if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
// if (name.equals("logLevel")) { if (name.equals("isEnable")) {
// setLogLevel(LogUtils.LOG_LEVEL.values()[jsonReader.nextInt()]); setIsEnable(jsonReader.nextBoolean());
// } else { } else {
// return false; return false;
// } }
} }
return true; return true;
} }
@@ -72,7 +67,12 @@ public class WinBoLLClientServiceBean extends BaseBean {
return this; return this;
} }
public static WinBoLLClientServiceBean loadWinBoLLClientServiceBean(Context context) { public static WinBollClientServiceBean loadWinBollClientServiceBean(Context context) {
return new WinBoLLClientServiceBean(); WinBollClientServiceBean bean = WinBollClientServiceBean.loadBean(context, WinBollClientServiceBean.class);
return bean == null ? new WinBollClientServiceBean() : bean;
}
public static boolean saveWinBollServiceBean(WinBollClientService service, WinBollClientServiceBean bean) {
return WinBollClientServiceBean.saveBean(service, bean);
} }
} }

View File

@@ -1,21 +1,22 @@
package cc.winboll.studio.libaes.winboll; package cc.winboll.studio.libaes.winboll;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/28 19:13:20
* @Describe WinBoll 邮件服务
*/
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
/** public class WinBollMail extends Service {
* @Author ZhanGSKen
* @Date 2025/05/03 19:28 public static final String TAG = "WinBollMail";
*/
public class WinBoLLClientService extends Service {
public static final String TAG = "WinBoLLClientService";
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return null;
} }
} }

View File

@@ -0,0 +1,106 @@
package cc.winboll.studio.libaes.winboll;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/29 15:57:28
* @Describe WinBoll 服务器服务情况测试访问进程。
*/
import cc.winboll.studio.libappbase.LogUtils;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
// 新增自定义回调接口
interface TextCallback {
void onSuccess(String text);
void onFailure(Exception e);
}
public class WinBollServerConnectionThread extends Thread {
public static final String TAG = "WinBollClientService";
private final String url;
private final String username;
private final String password;
private final int connectTimeout;
private final int readTimeout;
private final int maxRetries;
private final TextCallback callback; // 新增回调成员变量
// 新增带回调的构造函数
public WinBollServerConnectionThread(String url, String username, String password, TextCallback callback) {
this(url, username, password, 10000, 10000, 5, callback);
}
// 修改原有构造函数,添加回调参数
public WinBollServerConnectionThread(String url, String username, String password,
int connectTimeout, int readTimeout, int maxRetries, TextCallback callback) {
this.url = url;
this.username = username;
this.password = password;
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
this.maxRetries = maxRetries;
this.callback = callback;
}
@Override
public void run() {
LogUtils.d(TAG, String.format("run() url %s\nusername %s\npassword %s", url, username, password));
String credential = Credentials.basic(username, password);
LogUtils.d(TAG, String.format("credential %s", credential));
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.header("Accept", "text/plain")
.header("Authorization", credential)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 优先调用自定义回调
if (callback != null) {
callback.onFailure(e);
} else {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
if (callback != null) {
callback.onFailure(new Exception("Unexpected code " + response));
} else {
LogUtils.d(TAG, "Unexpected code " + response, Thread.currentThread().getStackTrace());
}
return;
}
try {
String text = response.body().string();
// 优先调用自定义回调
if (callback != null) {
callback.onSuccess(text);
} else {
LogUtils.d(TAG, text);
}
} catch (Exception e) {
if (callback != null) {
callback.onFailure(e);
} else {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
}
});
}
}

View File

@@ -0,0 +1,473 @@
package cc.winboll.studio.libaes.winboll;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/28 17:41:55
* @Describe WinBoll 服务主机连接状态视图
*/
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import cc.winboll.studio.libaes.winboll.WinBollClientService;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libapputils.R;
import cc.winboll.studio.libapputils.utils.PrefUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
//import okhttp3.Authenticator;
//import okhttp3.Credentials;
//import okhttp3.OkHttpClient;
//import okhttp3.Request;
//import okhttp3.Response;
//import okhttp3.Route;
public class WinBollServiceStatusView extends LinearLayout {
public static final String TAG = "WinBollServiceStatusView";
public static final int MSG_CONNECTION_INFO = 0;
public static final int MSG_UPDATE_CONNECTION_STATUS = 1;
static WinBollServiceStatusView _WinBollServiceStatusView;
Context mContext;
//boolean mIsConnected;
volatile ConnectionThread mConnectionThread;
String mszServerHost;
WinBollClientService mWinBollService;
ImageView mImageView;
TextView mTextView;
WinBollServiceViewHandler mWinBollServiceViewHandler;
//WebView mWebView;
static volatile ConnectionStatus mConnectionStatus;
View.OnClickListener mViewOnClickListener;
static String _mUserName;
static String _mPassword;
static enum ConnectionStatus {
DISCONNECTED,
START_CONNECT,
CONNECTING,
CONNECTED;
};
boolean isBound = false;
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IWinBollClientServiceBinder binder = (IWinBollClientServiceBinder) service;
mWinBollService = binder.getService();
isBound = true;
// 可以在这里调用Service的方法进行通信比如获取数据
mImageView.setBackgroundDrawable(mWinBollService.getCurrentStatusIconDrawable());
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};
public WinBollServiceStatusView(Context context) {
super(context);
mContext = context;
initView();
}
public WinBollServiceStatusView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
}
public WinBollServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initView();
}
public WinBollServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mContext = context;
initView();
}
ConnectionStatus getConnectionStatus() {
return false ?
ConnectionStatus.CONNECTED
: ConnectionStatus.DISCONNECTED;
}
void initView() {
_WinBollServiceStatusView = this;
mImageView = new ImageView(mContext);
setImageViewByConnection(mImageView, false);
mConnectionStatus = getConnectionStatus();
//mIsConnected = false;
//mWinBollServerHostConnectionStatus = WinBollServerHostConnectionStatus.DISCONNECTED;
//ToastUtils.show("initView()");
mViewOnClickListener = new View.OnClickListener(){
@Override
public void onClick(View v) {
LogUtils.d(TAG, "onClick()");
if (mConnectionStatus == ConnectionStatus.CONNECTED) {
LogUtils.d(TAG, "Click to stop service.");
WinBollClientServiceBean bean = WinBollClientServiceBean.loadWinBollClientServiceBean(mContext);
bean.setIsEnable(false);
WinBollClientServiceBean.saveBean(mContext, bean);
Intent intent = new Intent(mContext, WinBollClientService.class);
mContext.stopService(intent);
//stopConnectionThread();
mTextView.setText("");
setImageViewByConnection(mImageView, false);
mConnectionStatus = ConnectionStatus.DISCONNECTED;
} else if (mConnectionStatus == ConnectionStatus.DISCONNECTED) {
LogUtils.d(TAG, "Click to start service.");
WinBollClientServiceBean bean = WinBollClientServiceBean.loadWinBollClientServiceBean(mContext);
bean.setIsEnable(true);
WinBollClientServiceBean.saveBean(mContext, bean);
Intent intent = new Intent(mContext, WinBollClientService.class);
mContext.startService(intent);
//startConnectionThread();
}
}
};
setOnClickListener(mViewOnClickListener);
addView(mImageView);
mTextView = new TextView(mContext);
mWinBollServiceViewHandler = new WinBollServiceViewHandler(this);
addView(mTextView);
/*mWebView = new WebView(mContext);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
// 弹出系统基本HTTP验证窗口
handler.proceed("username", "password");
}
});
addView(mWebView);*/
}
void checkWinBollServerStatusAndUpdateCurrentView() {
LogUtils.d(TAG, "checkWinBollServerStatusAndUpdateCurrentView()");
/*if (getConnectionStatus() == ConnectionStatus.CONNECTED) {
mConnectionStatus = ConnectionStatus.CONNECTED;
} else {
mConnectionStatus = ConnectionStatus.DISCONNECTED;
}*/
}
public void setServerHost(String szWinBollServerHost) {
mszServerHost = szWinBollServerHost;
}
public void setAuthInfo(String username, String password) {
_mUserName = username;
_mPassword = password;
}
void setImageViewByConnection(ImageView imageView, boolean isConnected) {
//mIsConnected = isConnected;
// 获取vector drawable
Drawable drawable = mContext.getDrawable(isConnected ? R.drawable.ic_dev_connected : R.drawable.ic_dev_disconnected);
if (drawable != null) {
imageView.setImageDrawable(drawable);
}
}
TextCallback apiTextCallback = new TextCallback() {
@Override
public void onSuccess(String text) {
// 处理成功响应
LogUtils.d(TAG, text);
}
@Override
public void onFailure(Exception e) {
// 处理失败情况
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
};
TextCallback cipTextCallback = new TextCallback() {
@Override
public void onSuccess(String text) {
// 处理成功响应
LogUtils.d(TAG, text);
LogUtils.d(TAG, "Develop Host Connection IP is : " + text);
mConnectionStatus = ConnectionStatus.CONNECTED;
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义时间格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
// 按照指定格式格式化时间并输出
String formattedDateTime = now.format(formatter);
String msg = "ClientIP<" + formattedDateTime + ">: " + text;
mWinBollServiceViewHandler.postMessageText(msg);
mWinBollServiceViewHandler.postMessageConnectionStatus(true);
}
@Override
public void onFailure(Exception e) {
// 处理失败情况
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
// 处理网络请求失败
setImageViewByConnection(mImageView, false);
mWinBollServiceViewHandler.postMessageText(e.getMessage());
mWinBollServiceViewHandler.postMessageConnectionStatus(false);
}
};
public void requestAPIWithBasicAuth() {
String targetUrl = "https://" + (GlobalApplication.isDebuging() ?"dev.winboll": "winboll") + ".cc/api/"; // 替换为实际测试的URL
requestWithBasicAuth(targetUrl, apiTextCallback);
}
public void requestCIPWithBasicAuth() {
String targetUrl = mszServerHost + "/cip/?simple=true";
requestWithBasicAuth(targetUrl, cipTextCallback);
}
public void requestWithBasicAuth(String targetUrl, TextCallback callback) {
String username = "";
String password = "";
if (GlobalApplication.isDebuging()) {
username = PrefUtils.getString(mContext, "metDevUserName", "");
password = PrefUtils.getString(mContext, "metDevUserPassword", "");
} else {
username = "WinBoll";
password = "WinBollPowerByZhanGSKen";
}
LogUtils.d(TAG, String.format("Connection Start. targetUrl %s", targetUrl));
WinBollServerConnectionThread thread = new WinBollServerConnectionThread(
targetUrl,
username,
password,
cipTextCallback
);
thread.start();
}
/*void requestWithBasicAuth(final WinBollServiceViewHandler textViewHandler, String targetUrl, final String username, final String password) {
// 用户名和密码,替换为实际的认证信息
//String username = "your_username";
//String password = "your_password";
LogUtils.d(TAG, "requestWithBasicAuth(...)");
LogUtils.d(TAG, String.format("targetUrl %s", targetUrl));
// 构建包含认证信息的请求
String credential = Credentials.basic(username, password);
LogUtils.d(TAG, String.format("credential %s", credential));
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(targetUrl)
.header("Accept", "text/plain") // 设置正确的Content-Type头
.header("Authorization", credential)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 处理网络请求失败
setImageViewByConnection(mImageView, false);
textViewHandler.postMessageText(e.getMessage());
textViewHandler.postMessageConnectionStatus(false);
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
//String sz = "请求失败,状态码: " + response.code();
//setImageViewByConnection(mImageView, false);
//LogUtils.d(TAG, sz);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
setImageViewByConnection(mImageView, false);
textViewHandler.postMessageText("Unexpected code " + response);
textViewHandler.postMessageConnectionStatus(false);
LogUtils.d(TAG, "Unexpected code " + response, Thread.currentThread().getStackTrace());
return;
}
try {
// 读取响应体作为字符串,注意这里可能需要解码
String text = response.body().string();
LogUtils.d(TAG, "Develop Host Connection IP is : " + text);
mConnectionStatus = ConnectionStatus.CONNECTED;
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义时间格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
// 按照指定格式格式化时间并输出
String formattedDateTime = now.format(formatter);
textViewHandler.postMessageText("ClientIP<" + formattedDateTime + ">: " + text);
textViewHandler.postMessageConnectionStatus(true);
//org.jsoup.nodes.Document doc = org.jsoup.Jsoup.parse(text);
//LogUtils.d(TAG, doc.text());
// 使用id选择器找到具有特定id的元素
//org.jsoup.nodes.Element elementWithId = doc.select("#LastRelease").first(); // 获取第一个匹配的元素
// 提取并打印元素的文本内容
//mszNewestAppPackageName = elementWithId.text();
//ToastUtils.delayedShow(text + "\n" + mszNewestAppPackageName, 5000);
//mHandler.sendMessage(mHandler.obtainMessage(MSG_APPUPDATE_CHECKED));
//System.out.println(response.body().string());
// mConnectionStatus = ConnectionStatus.CONNECTED;
// // 获取当前时间
// LocalDateTime now = LocalDateTime.now();
//
// // 定义时间格式
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
// // 按照指定格式格式化时间并输出
// String formattedDateTime = now.format(formatter);
// //System.out.println(formattedDateTime);
// textViewHandler.postMessageText("ClientIP<" + formattedDateTime + ">: " + response.body().string());
// textViewHandler.postMessageConnectionStatus(true);
} catch (Exception e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
});
}*/
class WinBollServiceViewHandler extends Handler {
WinBollServiceStatusView mDevelopHostConnectionStatusView;
public WinBollServiceViewHandler(WinBollServiceStatusView view) {
mDevelopHostConnectionStatusView = view;
}
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_CONNECTION_INFO) {
mDevelopHostConnectionStatusView.mTextView.setText((String)msg.obj);
} else if (msg.what == MSG_UPDATE_CONNECTION_STATUS) {
mDevelopHostConnectionStatusView.setImageViewByConnection(mImageView, (boolean)msg.obj);
mDevelopHostConnectionStatusView.mConnectionStatus = ((boolean)msg.obj) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED;
}
super.handleMessage(msg);
}
void postMessageText(String szMSG) {
Message msg = new Message();
msg.what = MSG_CONNECTION_INFO;
msg.obj = szMSG;
sendMessage(msg);
}
void postMessageConnectionStatus(boolean isConnected) {
Message msg = new Message();
msg.what = MSG_UPDATE_CONNECTION_STATUS;
msg.obj = isConnected;
sendMessage(msg);
}
}
public static void startConnection() {
if (_WinBollServiceStatusView != null) {
_WinBollServiceStatusView.startConnectionThread();
}
}
public static void stopConnection() {
if (_WinBollServiceStatusView != null) {
_WinBollServiceStatusView.stopConnectionThread();
}
}
void startConnectionThread() {
if (mConnectionStatus == ConnectionStatus.DISCONNECTED) {
mConnectionStatus = ConnectionStatus.START_CONNECT;
LogUtils.d(TAG, "startConnectionThread");
if (mConnectionThread != null) {
LogUtils.d(TAG, "mConnectionThread != null");
mConnectionThread.mIsExist = true;
}
mConnectionThread = new ConnectionThread();
mConnectionThread.start();
} else if (mConnectionStatus == ConnectionStatus.CONNECTING) {
//LogUtils.d(TAG, "mConnectionStatus == ConnectionStatus.CONNECTING");
} else if (mConnectionStatus == ConnectionStatus.CONNECTED) {
//LogUtils.d(TAG, "mConnectionStatus == ConnectionStatus.CONNECTED");
} else {
LogUtils.d(TAG, String.format("Unknow mConnectionStatus %s, can not start ConnectionThread.", mConnectionStatus));
}
}
void stopConnectionThread() {
LogUtils.d(TAG, "stopConnectionThread");
if (mConnectionThread != null) {
LogUtils.d(TAG, "mConnectionThread != null");
mConnectionThread.mIsExist = true;
mConnectionThread = null;
}
}
class ConnectionThread extends Thread {
public volatile boolean mIsExist;
//DevelopHostConnectionStatusViewHandler mDevelopHostConnectionStatusViewHandler;
//public ConnectionThread(DevelopHostConnectionStatusViewHandler developHostConnectionStatusViewHandler) {
//mDevelopHostConnectionStatusViewHandler = developHostConnectionStatusViewHandler;
//}
public ConnectionThread() {
mIsExist = false;
}
@Override
public void run() {
super.run();
while (mIsExist == false) {
if (mConnectionStatus == ConnectionStatus.START_CONNECT) {
mConnectionStatus = ConnectionStatus.CONNECTING;
//requestAPIWithBasicAuth();
requestCIPWithBasicAuth();
} else if (mConnectionStatus == ConnectionStatus.CONNECTED
|| mConnectionStatus == ConnectionStatus.DISCONNECTED) {
//ToastUtils.show("mWinBollServerHostConnectionStatus " + mConnectionStatus);
LogUtils.d(TAG, String.format("mConnectionStatus done %s", mConnectionStatus));
} else {
LogUtils.d(TAG, String.format("mConnectionStatus unknow %s", mConnectionStatus));
}
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
//ToastUtils.show("ConnectionThread exit.");
LogUtils.d(TAG, "ConnectionThread exit.");
}
}
/*WinBollService.OnServiceStatusChangeListener mOnServerStatusChangeListener = new WinBollService.OnServiceStatusChangeListener(){
@Override
public void onServerStatusChange(boolean isServiceAlive) {
}
};*/
}

View File

@@ -53,10 +53,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_horizontal"> android:gravity="center_horizontal">
<cc.winboll.studio.libaes.winboll.WinBoLLServiceStatusView <cc.winboll.studio.libaes.winboll.WinBollServiceStatusView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/viewaboutdevWinBoLLServiceStatusView1"/> android:id="@+id/viewaboutdevWinBollServiceStatusView1"/>
</LinearLayout> </LinearLayout>

View File

@@ -12,10 +12,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_horizontal"> android:gravity="center_horizontal">
<cc.winboll.studio.libaes.winboll.WinBoLLServiceStatusView <cc.winboll.studio.libaes.winboll.WinBollServiceStatusView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/viewaboutwwwWinBoLLServiceStatusView1"/> android:id="@+id/viewaboutwwwWinBollServiceStatusView1"/>
</LinearLayout> </LinearLayout>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:background="@drawable/toast_frame"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textStyle="bold"
android:textColor="#FFFFFFFF"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/ic_launcher"/>
<TextView
android:id="@android:id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:textColor="#FFFFFFFF"/>
</LinearLayout>
</LinearLayout>

View File

@@ -2,7 +2,7 @@
<resources> <resources>
<string name="lib_name">libaes</string> <string name="lib_name">libaes</string>
<string name="lib_description">云宝APP应用安卓元素类库示例。源码仅供调试参考请勿直接引用。(WinBoLL APP application Android element class library example. The source is just for demo debug test, Do not quote directly.)</string> <string name="lib_description">云宝APP应用安卓元素类库示例。源码仅供调试参考请勿直接引用。(WinBoll APP application Android element class library example. The source is just for demo debug test, Do not quote directly.)</string>
<string name="lib_home">https://winboll.cc/aes</string> <string name="lib_home">https://winboll.cc/aes</string>
<string name="text_about">关于</string> <string name="text_about">关于</string>
<string name="text_AppTheme">应用主题</string> <string name="text_AppTheme">应用主题</string>

View File

@@ -2,7 +2,7 @@
<resources> <resources>
<string name="lib_name">libaes</string> <string name="lib_name">libaes</string>
<string name="lib_description">云宝APP应用安卓元素类库示例。源码仅供调试参考请勿直接引用。(WinBoLL APP application Android element class library example. The source is just for demo debug test, Do not quote directly.)</string> <string name="lib_description">云宝APP应用安卓元素类库示例。源码仅供调试参考请勿直接引用。(WinBoll APP application Android element class library example. The source is just for demo debug test, Do not quote directly.)</string>
<string name="lib_home">https://winboll.cc/libaes</string> <string name="lib_home">https://winboll.cc/libaes</string>
<string name="text_about">About</string> <string name="text_about">About</string>
<string name="text_AppTheme">AppTheme</string> <string name="text_AppTheme">AppTheme</string>

View File

@@ -10,7 +10,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 29
} }
buildTypes { buildTypes {
release { release {
@@ -22,4 +22,25 @@ android {
dependencies { dependencies {
api fileTree(dir: 'libs', include: ['*.jar']) api fileTree(dir: 'libs', include: ['*.jar'])
// Android 类库
//api 'com.android.support:appcompat-v7:28.0.0'
api('com.android.support:appcompat-v7:28.0.0'){
//exclude group: "com.android.support", module: "support-vector-drawable"
exclude group: "com.android.support:animated-vector-drawable:28.0.0"
}
// https://mvnrepository.com/artifact/com.android.support/support-compat
//api 'com.android.support:support-compat:28.0.0' // 保留原有依赖(可选)
// https://mvnrepository.com/artifact/com.android.support/support-v4
api 'com.android.support:support-v4:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-media-compat
api 'com.android.support:support-media-compat:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-core-utils
api 'com.android.support:support-core-utils:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-core-ui
api 'com.android.support:support-core-ui:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-fragment
api 'com.android.support:support-fragment:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/recyclerview-v7
api 'com.android.support:recyclerview-v7:28.0.0'
} }

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sat May 03 10:32:21 GMT 2025 #Sun Apr 27 00:07:35 GMT 2025
stageCount=7 stageCount=7
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.7 baseVersion=15.2
publishVersion=15.7.6 publishVersion=15.2.6
buildCount=4 buildCount=0
baseBetaVersion=15.7.7 baseBetaVersion=15.2.7

View File

@@ -12,7 +12,7 @@ import android.content.pm.PackageManager;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import cc.winboll.studio.libappbase.utils.ToastUtils; import cc.winboll.studio.libappbase.utils.ToastUtils;
import cc.winboll.studio.libappbase.winboll.WinBoLLActivityManager; import cc.winboll.studio.libappbase.winboll.WinBollActivityManager;
import cc.winboll.studio.libappbase.winboll.MyActivityLifecycleCallbacks; import cc.winboll.studio.libappbase.winboll.MyActivityLifecycleCallbacks;
public class GlobalApplication extends Application { public class GlobalApplication extends Application {
@@ -46,8 +46,8 @@ public class GlobalApplication extends Application {
return isDebuging; return isDebuging;
} }
public static WinBoLLActivityManager getWinBoLLActivityManager() { public static WinBollActivityManager getWinBollActivityManager() {
return WinBoLLActivityManager.getInstance(_GlobalApplication); return WinBollActivityManager.getInstance(_GlobalApplication);
} }
@Override @Override
@@ -77,7 +77,7 @@ public class GlobalApplication extends Application {
setIsDebuging(appBaseModel.isDebuging()); setIsDebuging(appBaseModel.isDebuging());
} }
getWinBoLLActivityManager().setWinBoLLUI_TYPE(WinBoLLActivityManager.WinBoLLUI_TYPE.Service); getWinBollActivityManager().setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Service);
// 注册窗口回调监听 // 注册窗口回调监听
mMyActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks(); mMyActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks();
registerActivityLifecycleCallbacks(mMyActivityLifecycleCallbacks); registerActivityLifecycleCallbacks(mMyActivityLifecycleCallbacks);

View File

@@ -15,8 +15,8 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toolbar;
import cc.winboll.studio.libappbase.R; import cc.winboll.studio.libappbase.R;
import android.widget.Toolbar;
public class GlobalCrashReportView extends LinearLayout { public class GlobalCrashReportView extends LinearLayout {

View File

@@ -0,0 +1,3 @@
package cc.winboll.studio.libappbase;

View File

@@ -3,7 +3,7 @@ package cc.winboll.studio.libappbase.sos;
/** /**
* @Author ZhanGSKen@AliYun.Com * @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/02 09:36:29 * @Date 2025/03/02 09:36:29
* @Describe WinBoLL 应用 SOS 机理保护类 * @Describe WinBoll 应用 SOS 机理保护类
*/ */
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;

View File

@@ -0,0 +1,39 @@
package cc.winboll.studio.libappbase.sos;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/02 09:54:28
* @Describe WinBoll 系列应用通用管理类
*/
import android.content.Context;
import android.content.Intent;
import cc.winboll.studio.libappbase.LogUtils;
public class WinBoll {
public static final String TAG = "WinBoll";
public static final String ACTION_BIND = WinBoll.class.getName() + ".ACTION_BIND";
public static final String EXTRA_APPMODEL = "EXTRA_APPMODEL";
public static void bindToAPPBase(Context context, String appMainService) {
LogUtils.d(TAG, "bindToAPPBase(...)");
String toPackage = "cc.winboll.studio.appbase";
startBind(context, toPackage, appMainService);
}
public static void bindToAPPBaseBeta(Context context, String appMainService) {
LogUtils.d(TAG, "bindToAPPBaseBeta(...)");
String toPackage = "cc.winboll.studio.appbase.beta";
startBind(context, toPackage, appMainService);
}
static void startBind(Context context, String toPackage, String appMainService) {
Intent intent = new Intent(ACTION_BIND);
intent.putExtra(EXTRA_APPMODEL, (new APPModel(toPackage, appMainService)).toString());
intent.setPackage(toPackage);
LogUtils.d(TAG, String.format("ACTION_BIND :\nTo Package : %s\nAPP Main Service : %s", toPackage, appMainService));
context.sendBroadcast(intent);
}
}

View File

@@ -0,0 +1,18 @@
package cc.winboll.studio.libappbase.winboll;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/24 08:23:40
* @Describe WinBoll 活动窗口通用接口
*/
import android.app.Activity;
import android.widget.Toolbar;
public interface IWinBollActivity {
public static final String TAG = "IWinBollActivity";
// 获取活动窗口
abstract public Activity getActivity();
abstract public String getTag();
}

View File

@@ -13,7 +13,7 @@ import cc.winboll.studio.libappbase.LogView;
import cc.winboll.studio.libappbase.R; import cc.winboll.studio.libappbase.R;
import cc.winboll.studio.libappbase.utils.ToastUtils; import cc.winboll.studio.libappbase.utils.ToastUtils;
public class LogActivity extends Activity implements IWinBoLLActivity { public class LogActivity extends Activity implements IWinBollActivity {
public static final String TAG = "LogActivity"; public static final String TAG = "LogActivity";

View File

@@ -0,0 +1,356 @@
package cc.winboll.studio.libappbase.winboll;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/24 08:25:43
* @Describe 应用活动窗口管理器
* 参考
* android 类似微信小程序多任务窗口 及 设置 TaskDescription 修改 icon 和 label
* https://blog.csdn.net/qq_29364417/article/details/109379915?app_version=6.4.2&code=app_1562916241&csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22109379915%22%2C%22source%22%3A%22weixin_38986226%22%7D&uLinkId=usr1mkqgl919blen&utm_source=app
*/
import android.app.ActivityManager;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.utils.ToastUtils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class WinBollActivityManager {
public static final String TAG = "WinBollActivityManager";
public static final String EXTRA_TAG = "EXTRA_TAG";
public static enum WinBollUI_TYPE {
Aplication, // 退出应用后,保持最近任务栏任务记录主窗口
Service // 退出应用后,清理所有最近任务栏任务记录窗口
};
// 应用类型标志
static volatile WinBollUI_TYPE _mWinBollUI_TYPE = WinBollUI_TYPE.Service;
GlobalApplication mGlobalApplication;
static volatile WinBollActivityManager _Instance;
static volatile Map<String, IWinBollActivity> _mapIWinBollList;
volatile IWinBollActivity mFirstIWinBollActivity;
WinBollActivityManager(GlobalApplication application) {
mGlobalApplication = application;
_mapIWinBollList = new HashMap<String, IWinBollActivity>();
}
public static synchronized WinBollActivityManager getInstance(GlobalApplication application) {
LogUtils.d(TAG, "getInstance");
if (_Instance == null) {
LogUtils.d(TAG, "_Instance == null");
_Instance = new WinBollActivityManager(application);
}
return _Instance;
}
//
// 设置 WinBoll 应用 UI 类型
//
public synchronized static void setWinBollUI_TYPE(WinBollUI_TYPE mWinBollUI_TYPE) {
_mWinBollUI_TYPE = mWinBollUI_TYPE;
}
//
// 获取 WinBoll 应用 UI 类型
//
public synchronized static WinBollUI_TYPE getWinBollUI_TYPE() {
return _mWinBollUI_TYPE;
}
//
// 把Activity添加到管理中
//
public <T extends IWinBollActivity> void add(T iWinBoll) {
String tag = ((IWinBollActivity)iWinBoll).getTag();
LogUtils.d(TAG, String.format("add(T iWinBoll) tag is %s", tag));
if (isActive(tag)) {
LogUtils.d(TAG, String.format("isActive(tag) is true, tag : %s.", tag));
} else {
// 设置起始活动窗口,以便最后退出时提问
if (mFirstIWinBollActivity == null && _mapIWinBollList.size() == 0) {
LogUtils.d(TAG, "Set firstIWinBollActivity, iWinBoll.getTag() is %s" + iWinBoll.getTag());
mFirstIWinBollActivity = iWinBoll;
}
// 添加到活动窗口列表
_mapIWinBollList.put(iWinBoll.getTag(), iWinBoll);
LogUtils.d(TAG, String.format("Add activity : %s\n_mapActivityList.size() : %d", iWinBoll.getTag(), _mapIWinBollList.size()));
}
}
//
// activity: 为 null 时,
// intent.putExtra 函数 EXTRA_TAG 参数为 tag
// activity: 不为 null 时,
// intent.putExtra 函数 "tag" 参数为 activity.getTag()
//
public <T extends IWinBollActivity> void startWinBollActivity(Context context, Class<T> clazz) {
try {
// 如果窗口已存在就重启窗口
String tag = ((IWinBollActivity)clazz.newInstance()).getTag();
LogUtils.d(TAG, String.format("startWinBollActivity(Context context, Class<T> clazz) tag is %s", tag));
if (isActive(tag)) {
resumeActivity(context, tag);
return;
}
//ToastUtils.show("startWinBollActivity(Context context, Class<T> clazz)");
// 新建一个任务窗口
Intent intent = new Intent(context, clazz);
//打开多任务窗口 flags
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_TAG, tag);
context.startActivity(intent);
} catch (InstantiationException | IllegalAccessException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
public <T extends IWinBollActivity> void startWinBollActivity(Context context, Intent intent, Class<T> clazz) {
try {
// 如果窗口已存在就重启窗口
String tag = ((IWinBollActivity)clazz.newInstance()).getTag();
LogUtils.d(TAG, String.format("startWinBollActivity(Context context, Intent intent, Class<T> clazz) tag is %s", tag));
if (isActive(tag)) {
resumeActivity(context, tag);
return;
}
// 新建一个任务窗口
//Intent intent = new Intent(context, clazz);
//打开多任务窗口 flags
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_TAG, tag);
context.startActivity(intent);
} catch (InstantiationException | IllegalAccessException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
public <T extends IWinBollActivity> void startLogActivity(Context context) {
// 如果窗口已存在就重启窗口
String tag = LogActivity.TAG;
if (isActive(tag)) {
resumeActivity(context, tag);
return;
}
// 新建一个任务窗口
Intent intent = new Intent(context, LogActivity.class);
//打开多任务窗口 flags
// Define the bounds.
// Rect bounds = new Rect(0, 0, 800, 200);
// // Set the bounds as an activity option.
// ActivityOptions options = ActivityOptions.makeBasic();
// options.setLaunchBounds(bounds);
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.putExtra(EXTRA_TAG, tag);
//context.startActivity(intent, options.toBundle());
context.startActivity(intent);
}
public boolean isFirstIWinBollActivity(IWinBollActivity iWinBollActivity) {
return mFirstIWinBollActivity != null && mFirstIWinBollActivity == iWinBollActivity;
}
//
// 判断 tag绑定的 MyActivity是否存在
//
public boolean isActive(String tag) {
LogUtils.d(TAG, String.format("isActive(String tag) tag is %s", tag));
//printIWinBollListInfo();
IWinBollActivity iWinBoll = getIWinBoll(tag);
if (iWinBoll != null) {
//LogUtils.d(TAG, "isActive(...) activity != null tag " + tag);
//ToastUtils.show("activity != null tag " + tag);
//判断是否为 BaseActivity,如果已经销毁,则移除
if (iWinBoll.getActivity().isFinishing() || iWinBoll.getActivity().isDestroyed()) {
_mapIWinBollList.remove(iWinBoll.getTag());
//_mWinBollActivityList.remove(activity);
LogUtils.d(TAG, String.format("isActive(...) remove activity.\ntag : %s", tag));
return false;
} else {
LogUtils.d(TAG, String.format("isActive(...) activity is exist.\ntag : %s", tag));
return true;
}
} else {
LogUtils.d(TAG, String.format("isActive(...) iWinBoll is null tag by %s", tag));
return false;
}
}
static IWinBollActivity getIWinBoll(String tag) {
LogUtils.d(TAG, String.format("getIWinBoll(String tag) %s", tag));
return _mapIWinBollList.get(tag);
}
//
// 找到tag 绑定的 BaseActivity ,通过 getTaskId() 移动到前台
//
public <T extends IWinBollActivity> void resumeActivity(Context context, String tag) {
LogUtils.d(TAG, "resumeActivity(Context context, String tag)");
T iWinBoll = (T)getIWinBoll(tag);
LogUtils.d(TAG, String.format("iWinBoll.getTag() %s", iWinBoll.getTag()));
//LogUtils.d(TAG, "activity " + activity.getTag());
if (iWinBoll != null && !iWinBoll.getActivity().isFinishing() && !iWinBoll.getActivity().isDestroyed()) {
resumeActivity(context, iWinBoll);
}
}
//
// 找到tag 绑定的 BaseActivity ,通过 getTaskId() 移动到前台
//
public <T extends IWinBollActivity> void resumeActivity(Context context, T iWinBoll) {
LogUtils.d(TAG, "resumeActivity(Context context, T iWinBoll)");
ActivityManager am = (ActivityManager) mGlobalApplication.getSystemService(Context.ACTIVITY_SERVICE);
//返回启动它的根任务home 或者 MainActivity
Intent intent = new Intent(mGlobalApplication, iWinBoll.getClass());
TaskStackBuilder stackBuilder = TaskStackBuilder.create(mGlobalApplication);
stackBuilder.addNextIntentWithParentStack(intent);
stackBuilder.startActivities();
//moveTaskToFront(YourTaskId, 0);
//ToastUtils.show("resumeActivity am.moveTaskToFront");
LogUtils.d(TAG, String.format("iWinBoll.getActivity().getTaskId() %d", iWinBoll.getActivity().getTaskId()));
am.moveTaskToFront(iWinBoll.getActivity().getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION);
LogUtils.d(TAG, "am.moveTaskToFront");
}
//
// 结束所有 Activity
//
public void finishAll() {
try {
for (String key : _mapIWinBollList.keySet()) {
//System.out.println("Key: " + key + ", Value: " + _mapActivityList.get(key));
IWinBollActivity iWinBoll = _mapIWinBollList.get(key);
//ToastUtils.show("finishAll() activity");
if (iWinBoll != null && !iWinBoll.getActivity().isFinishing() && !iWinBoll.getActivity().isDestroyed()) {
//ToastUtils.show("activity != null ...");
if (getWinBollUI_TYPE() == WinBollUI_TYPE.Service) {
// 结束窗口和最近任务栏, 建议前台服务类应用使用,可以方便用户再次调用 UI 操作。
iWinBoll.getActivity().finishAndRemoveTask();
//ToastUtils.show("finishAll() activity.finishAndRemoveTask();");
} else if (getWinBollUI_TYPE() == WinBollUI_TYPE.Aplication) {
// 结束窗口保留最近任务栏,建议前台服务类应用使用,可以保持应用的系统自觉性。
iWinBoll.getActivity().finish();
//ToastUtils.show("finishAll() activity.finish();");
} else {
LogUtils.d(TAG, "WinBollApplication.WinBollUI_TYPE error.");
//ToastUtils.show("WinBollApplication.WinBollUI_TYPE error.");
}
}
}
} catch (Exception e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
//
// 结束指定Activity
//
public <T extends IWinBollActivity> void finish(T iWinBoll) {
try {
if (iWinBoll != null && !iWinBoll.getActivity().isFinishing() && !iWinBoll.getActivity().isDestroyed()) {
//根据tag 移除 MyActivity
//String tag= activity.getTag();
//_mWinBollActivityList.remove(tag);
//ToastUtils.show("remove");
//ToastUtils.show("_mWinBollActivityArrayMap.size() " + Integer.toString(_mWinBollActivityArrayMap.size()));
// 窗口回调规则:
// [] 当前窗口位置 >> 调度出的窗口位置
// ★:[0] 1 2 3 4 >> 1
// ★0 1 [2] 3 4 >> 1
// ★0 1 2 [3] 4 >> 2
// ★0 1 2 3 [4] >> 3
// ★:[0] >> 直接关闭当前窗口
//LogUtils.d(TAG, "finish no yet.");
IWinBollActivity preIWinBoll = getPreIWinBoll(iWinBoll);
iWinBoll.getActivity().finish();
if (preIWinBoll != null) {
resumeActivity(mGlobalApplication, preIWinBoll);
}
}
} catch (Exception e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
//
// 获取窗口队列中的前一个窗口
//
IWinBollActivity getPreIWinBoll(IWinBollActivity iWinBoll) {
try {
boolean bingo = false;
IWinBollActivity preIWinBoll = null;
for (Map.Entry<String, IWinBollActivity> entity : _mapIWinBollList.entrySet()) {
if (entity.getKey().equals(iWinBoll.getTag())) {
bingo = true;
//LogUtils.d(TAG, "bingo");
break;
}
preIWinBoll = entity.getValue();
}
if (bingo) {
return preIWinBoll;
}
} catch (Exception e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
return null;
}
//
// 从管理列表中移除管理项
//
public <T extends IWinBollActivity> boolean registeRemove(T activity) {
IWinBollActivity iWinBollTest = _mapIWinBollList.get(activity.getTag());
if (iWinBollTest != null) {
_mapIWinBollList.remove(activity.getTag());
return true;
}
return false;
}
//
// 打印管理列表项列表里的信息
//
public static void printIWinBollListInfo() {
//LogUtils.d(TAG, "printAvtivityListInfo");
if (!_mapIWinBollList.isEmpty()) {
StringBuilder sb = new StringBuilder("Map entries : " + Integer.toString(_mapIWinBollList.size()));
Iterator<Map.Entry<String, IWinBollActivity>> iterator = _mapIWinBollList.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, IWinBollActivity> entry = iterator.next();
sb.append("\nKey: " + entry.getKey() + ", \nValue: " + entry.getValue().getTag());
//ToastUtils.show("\nKey: " + entry.getKey() + ", Value: " + entry.getValue().getTag());
}
sb.append("\nMap entries end.");
LogUtils.d(TAG, sb.toString());
} else {
LogUtils.d(TAG, "The map is empty.");
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -7,7 +7,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/viewglobalcrashreportLinearLayout1"> android:id="@+id/viewglobalcrashreportLinearLayout1">
<android.widget.Toolbar <android.support.v7.widget.Toolbar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/viewglobalcrashreportToolbar1"/> android:id="@+id/viewglobalcrashreportToolbar1"/>

View File

@@ -1,20 +1,25 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@+id/item_minimal" android:id="@+id/item_minimal"
android:title="MINIMAL" android:title="MINIMAL"
android:icon="@drawable/ic_winboll_point"/> android:icon="@drawable/ic_winboll_point"
app:showAsAction="always"/>
<item <item
android:id="@+id/item_about" android:id="@+id/item_about"
android:title="ABOUT" android:title="ABOUT"
android:icon="@drawable/ic_winboll_logo"/> android:icon="@drawable/ic_winboll_logo"
app:showAsAction="always"/>
<item <item
android:id="@+id/item_help" android:id="@+id/item_help"
android:title="HELP" android:title="HELP"
android:icon="@drawable/ic_winboll_help"/> android:icon="@drawable/ic_winboll_help"
app:showAsAction="always"/>
<item <item
android:id="@+id/item_log" android:id="@+id/item_log"
android:title="LOG" android:title="LOG"
android:icon="@drawable/ic_winboll_log"/> android:icon="@drawable/ic_winboll_log"
app:showAsAction="always"/>
</menu> </menu>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="APPBaseTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar"> <style name="APPBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="themeGlobalCrashActivity">@style/GlobalCrashActivityTheme</item> <item name="themeGlobalCrashActivity">@style/GlobalCrashActivityTheme</item>
</style> </style>

View File

@@ -9,7 +9,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 29
} }
buildTypes { buildTypes {
release { release {
@@ -21,7 +21,29 @@ android {
dependencies { dependencies {
api fileTree(dir: 'libs', include: ['*.jar']) api fileTree(dir: 'libs', include: ['*.jar'])
api 'cc.winboll.studio:libappbase:15.7.6' // Android 类库
//api 'com.android.support:appcompat-v7:28.0.0'
api('com.android.support:appcompat-v7:28.0.0'){
//exclude group: "com.android.support", module: "support-vector-drawable"
exclude group: "com.android.support:animated-vector-drawable:28.0.0"
}
// https://mvnrepository.com/artifact/com.android.support/support-compat
//api 'com.android.support:support-compat:28.0.0' // 保留原有依赖(可选)
// https://mvnrepository.com/artifact/com.android.support/support-v4
api 'com.android.support:support-v4:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-media-compat
api 'com.android.support:support-media-compat:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-core-utils
api 'com.android.support:support-core-utils:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-core-ui
api 'com.android.support:support-core-ui:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/support-fragment
api 'com.android.support:support-fragment:28.0.0'
// https://mvnrepository.com/artifact/com.android.support/recyclerview-v7
api 'com.android.support:recyclerview-v7:28.0.0'
//api 'cc.winboll.studio:libappbase:15.2.0'
api project(':libappbase')
// 二维码类库 // 二维码类库
api 'com.google.zxing:core:3.4.1' api 'com.google.zxing:core:3.4.1'

Some files were not shown because too many files have changed in this diff Show More