Compare commits

..

24 Commits

Author SHA1 Message Date
ZhanGSKen
8dd41a0c3a <powerbell>APK 15.2.2 release Publish. 2025-03-31 20:11:58 +08:00
ZhanGSKen
ca4814744f 更新类库,修复调试模式设置。 2025-03-31 20:11:08 +08:00
ZhanGSKen
5a9ee81c30 <powerbell>APK 15.2.1 release Publish. 2025-03-31 15:08:28 +08:00
ZhanGSKen
841d526b0d <powerbell>APK 15.2.0 release Publish. 2025-03-31 15:06:43 +08:00
ZhanGSKen
11d2db6bf9 更新应用简介。 2025-03-31 15:05:02 +08:00
ZhanGSKen
93d8fa15db 修改主题配置,修复日志菜单栏显示问题。 2025-03-31 14:59:54 +08:00
ZhanGSKen
99ff741a22 更新类库,设置版本号。 2025-03-31 14:53:33 +08:00
ZhanGSKen
5bc7581db1 Merge remote-tracking branch 'origin/androidxdemo' into powerbell 2025-03-31 14:39:31 +08:00
ZhanGSKen
fde0712439 Merge remote-tracking branch 'origin/appbase' into powerbell 2025-03-31 14:39:26 +08:00
ZhanGSKen
4ff54c785e <powerbell>APK 15.0.3 release Publish. 2025-03-25 02:43:07 +08:00
ZhanGSKen
b961468e1e <powerbell>APK 15.0.2 release Publish. 2025-03-25 02:42:42 +08:00
ZhanGSKen
575ef9aac0 内容提供配置调整 2025-03-25 02:42:10 +08:00
ZhanGSKen
16b118f83b <powerbell>APK 15.0.1 release Publish. 2025-03-25 02:36:56 +08:00
ZhanGSKen
1eeba4e4c6 <powerbell>APK 15.0.0 release Publish. 2025-03-25 02:34:56 +08:00
ZhanGSKen
66eb8e06ea 应用介绍页基本调试完成 2025-03-25 02:30:45 +08:00
ZhanGSKen
51775620db 更新类库,调试应用介绍... 2025-03-24 20:24:31 +08:00
ZhanGSKen
deaa9caadd Merge remote-tracking branch 'origin/appbase' into powerbell 2025-03-24 14:33:17 +08:00
ZhanGSKen
58af5ba074 <powerbell>APK 4.0.7 release Publish. 2025-03-22 16:06:33 +08:00
ZhanGSKen
19743d30ef 修复编译参数 2025-03-22 16:05:10 +08:00
ZhanGSKen
3c2b720e20 调整背景图片设置窗口按钮布局 2025-03-22 16:03:08 +08:00
ZhanGSKen
5a052e4b22 添加电池报告窗口雏形 2025-03-22 15:54:18 +08:00
ZhanGSKen
4ccf6824a6 <powerbell>APK 4.0.6 release Publish. 2025-03-22 06:01:46 +08:00
ZhanGSKen
508c8b0b97 适配小米15,修改通知模块。 2025-03-22 05:53:58 +08:00
ZhanGSKen
0d21994291 编译配置精简 2025-03-22 03:06:40 +08:00
191 changed files with 6632 additions and 1362 deletions

View File

@@ -9,8 +9,8 @@
## WinBoll 项目组研发计划
致力于把 WinBoll-APP 应用在手机端 Android 项目开发。
也在探索 https://gitea.winboll.cc/<WinBoll 项目组>/APP.git 应用于 WinBoll-APP APK 分发。
更想进阶 https://github.com/<WinBoll 项目组>/APP.git 应用于 WinBoll-APP Beta APK 分发。
也在探索 https://gitea.winboll.cc/<WinBoll 项目组>/WinBoll-APP.git 应用于 WinBoll-APP APK 分发。
更想进阶 https://github.com/<WinBoll 项目组>/WinBoll-APP.git 应用于 WinBoll-APP Beta APK 分发。
## WinBoll-APP 汗下...
#### ☁应用何置如此呢。且观用户云云。
@@ -55,10 +55,10 @@
☁ WinBoll 主机建立 1Panel Gitea 应用。
☁ WinBoll 主机设置 WinBoll 应用为非登录状态。
☁ WinBoll 主机建立 WinBoll 账户与 WinBoll 用户组。
☁ WinBoll 账户 User ID 为: J
☁ WinBoll 用户组 Group ID 为: Studio
☁ WinBoll 账户 User ID 为: winboll
☁ WinBoll 用户组 Group ID 为: winboll
☁ WinBoll 主机 WinBoll 1Panel Gitea 建立 WinBoll 工作组。
☁ WinBoll 主机 WinBoll 1Panel Gitea 用户项目 APK 编译输出目录为 /sdcard/WinBollStudio/<用户名>/APKs/
☁ WinBoll 主机 WinBoll 1Panel Gitea 用户项目 APK 编译输出目录为 /sdcard/<用户名>/WinBoll/app/
☁ WinBoll 项目配置文件示例为 "<WinBoll 项目根目录>/.winboll/winboll.properties-demo"(WinBoll 项目已设置)
☁ WinBoll 项目配置文件为 "<WinBoll 项目根目录>/.winboll/winboll.properties"
☁ WinBoll 项目配置文件设定为源码提交时忽略。(WinBoll 项目已设置)
@@ -72,17 +72,17 @@
☁ MySQL winbollclient 数据库中
WinBoll 客户端用户信息设定为:
<用户名, 验证密码, 验证邮箱, 验证手机, 唯一存储令牌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/winboll/winboll.git中。
☁ WinBoll 主机提供 WinBoll 1Panel Gitea 应用的 WinBoll 项目源码仓库存取功能。Gitea 应用已提供)
☁ WinBoll 主机提供 WinBoll Gitea 项目仓库存档功能。Gitea 应用已提供)
☁ 提供 WinBoll 客户端用户登录功能。Gitea 应用已提供)
### ☁ 看远方 ☁ ###
### ☁ 心忧虑 ☁ WinBoll-APP 应用前置需求
☁ WinBoll-APP WinBoll 项目根目录设定为手机的 /sdcard/WinBollStudio/Sources 目录。(需要用户手动建立文件夹)
☁ WinBoll-APP WinBoll 项目根目录设定为手机的 /sdcard/WinBoll 目录。(需要用户手动建立文件夹)
☁ WinBoll-APP 具有手机 /sdcard/WinBoll 目录的存储权限。(需要手机操作系统授权)
☁ WinBoll-APP WinBoll 项目仓库源码存储路径为 /sdcard/WinBollStudio/Sources/APP.git需要用户手动建立文件夹
☁ WinBoll-APP 项目 APK 编译输出目录为 /sdcard/WinBollStudio/APKs/
☁ WinBoll-APP WinBoll 项目仓库源码存储路径为 /sdcard/WinBoll/repositories/winboll.git需要用户手动建立文件夹
☁ WinBoll-APP 项目 APK 编译输出目录为 /sdcard/WinBoll/app/
☁ WinBoll-APP 应用签名验证可定制化。WinBoll 项目已提供)
☁ WinBoll-APP 与系列衍生 APP 应用共享 cc.winboll.studio 命名空间资源。WinBoll 项目已提供)
☁ WinBoll-APP 用户客户端信息存储在命名空间为 WinBoll APP MySQLLite 应用的 winbollappclient 数据库中。
@@ -92,7 +92,7 @@
### ☁ 云游四方 ☁ ###
### ☁ 呔! ☁ WinBoll-APP 应用需求规划
☁ WinBoll-APP 提供手机目录 /sdcard/WinBollStudio/Sources 的 WinBoll 项目源码管理功能。
☁ WinBoll-APP 提供手机目录 /sdcard/WinBoll 的 WinBoll 项目源码管理功能。
### ☁ 吁! ☁ WinBoll-APP 共享计划前景
☁ WinBoll-APP 将会实现 https://winboll.cc/api 访问功能。

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Apr 02 20:09:04 HKT 2025
stageCount=6
#Mon Mar 31 02:04:47 HKT 2025
stageCount=4
libraryProject=libaes
baseVersion=15.2
publishVersion=15.2.5
publishVersion=15.2.3
buildCount=0
baseBetaVersion=15.2.6
baseBetaVersion=15.2.4

View File

@@ -5,26 +5,19 @@ package cc.winboll.studio.aes;
* @Date 2024/06/13 19:03:58
* @Describe AES应用类
*/
import android.view.Gravity;
import cc.winboll.studio.libappbase.GlobalApplication;
import com.hjq.toast.ToastUtils;
public class App extends GlobalApplication {
public static final String TAG = "App";
@Override
public void onCreate() {
super.onCreate();
// 初始化 Toast 框架
ToastUtils.init(this);
// 设置 Toast 布局样式
ToastUtils.setView(R.layout.view_toast);
//ToastUtils.setStyle(new WhiteToastStyle());
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
//ToastUtils.show("App onCreate");
}
}

View File

@@ -6,7 +6,6 @@ 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
@@ -48,13 +47,4 @@ public class WinBollActivity extends AppCompatActivity implements IWinBollActivi
//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

@@ -49,8 +49,7 @@ dependencies {
// 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"
exclude group: "com.android.support", module: "support-vector-drawable"
}
// https://mvnrepository.com/artifact/com.android.support/support-compat
api 'com.android.support:support-compat:28.0.0' // 保留原有依赖(可选)

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Apr 02 12:22:30 GMT 2025
#Sat Mar 29 04:34:14 GMT 2025
stageCount=0
libraryProject=
baseVersion=15.0
publishVersion=15.0.0
buildCount=20
buildCount=15
baseBetaVersion=15.0.1

View File

@@ -67,7 +67,7 @@ dependencies {
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
//api 'androidx.fragment:fragment:1.1.0'
api 'cc.winboll.studio:libaes:15.2.5'
api 'cc.winboll.studio:libaes:15.2.3'
api 'cc.winboll.studio:libapputils:15.2.1'
api 'cc.winboll.studio:libappbase:15.2.2'
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Apr 02 12:13:40 GMT 2025
#Mon Mar 31 03:57:35 GMT 2025
stageCount=0
libraryProject=
baseVersion=15.0
publishVersion=15.0.0
buildCount=16
buildCount=12
baseBetaVersion=15.0.1

View File

@@ -14,7 +14,6 @@ import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
@@ -22,9 +21,7 @@ import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import cc.winboll.studio.androidxdemo.R;
import cc.winboll.studio.libappbase.GlobalApplication;
import com.hjq.toast.ToastUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@@ -49,14 +46,6 @@ public class App extends GlobalApplication {
@Override
public void onCreate() {
super.onCreate();
// 初始化 Toast 框架
ToastUtils.init(this);
// 设置 Toast 布局样式
ToastUtils.setView(R.layout.view_toast);
//ToastUtils.setStyle(new WhiteToastStyle());
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
//CrashHandler.getInstance().registerGlobal(this);
//CrashHandler.getInstance().registerPart(this);
}

View File

@@ -4,7 +4,6 @@ import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libappbase.LogView;
import com.hjq.toast.ToastUtils;
public class MainActivity extends AppCompatActivity {
@@ -19,8 +18,6 @@ public class MainActivity extends AppCompatActivity {
setSupportActionBar(toolbar);
mLogView = findViewById(R.id.logview);
ToastUtils.show("onCreate");
}
@Override

0
app/app.md Normal file
View File

0
app/app.perl Normal file
View File

0
app/app.php Normal file
View File

0
app/app.py Normal file
View File

0
app/app.sh Normal file
View File

0
app/app.txt Normal file
View File

View File

@@ -19,17 +19,17 @@ def genVersionName(def versionName){
android {
compileSdkVersion 32
buildToolsVersion "32.0.0"
buildToolsVersion "33.0.3"
defaultConfig {
applicationId "cc.winboll.studio.app"
minSdkVersion 24
targetSdkVersion 29
minSdkVersion 21
targetSdkVersion 30
versionCode 1
// versionName 更新后需要手动设置
// 项目模块目录的 build.gradle 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.0"
versionName "1.8"
if(true) {
versionName = genVersionName("${versionName}")
}
@@ -41,32 +41,14 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
// 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 'com.github.getActivity:ToastUtils:10.5'
// 网络连接类库
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 'cc.winboll.studio:libaes:15.2.4'
api 'cc.winboll.studio:libapputils:15.2.1'
api 'cc.winboll.studio:libappbase:15.2.2'
api project(':winboll-shared')
api fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Tue Apr 01 13:50:28 HKT 2025
stageCount=2
libraryProject=
baseVersion=15.0
publishVersion=15.0.1
#Sun Jan 05 07:55:24 HKT 2025
stageCount=17
libraryProject=winboll-shared
baseVersion=1.8
publishVersion=1.8.16
buildCount=0
baseBetaVersion=15.0.2
baseBetaVersion=1.8.17

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">APP+</string>
<string name="app_name">WinBoll-APP+</string>
</resources>

View File

@@ -11,7 +11,7 @@
android:allowBackup="true"
android:icon="@drawable/ic_winboll"
android:label="@string/app_name"
android:theme="@style/AESTheme"
android:theme="@style/WinBoll.SupportThemeNoActionBar"
android:supportsRtl="true">
<activity
@@ -42,7 +42,6 @@
</provider>
<activity android:name=".AboutActivity"/>
</application>

View File

@@ -1,88 +0,0 @@
package cc.winboll.studio.app;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/24 23:52:29
* @Describe 应用介绍窗口
*/
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.app.R;
import cc.winboll.studio.libaes.winboll.APPInfo;
import cc.winboll.studio.libaes.winboll.AboutView;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
public class AboutActivity extends WinBollActivity implements IWinBollActivity {
public static final String TAG = "AboutActivity";
Context mContext;
Toolbar mToolbar;
@Override
public Activity getActivity() {
return this;
}
@Override
public String getTag() {
return TAG;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_about);
mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mToolbar.setSubtitle(TAG);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
AboutView aboutView = CreateAboutView();
// 在 Activity 的 onCreate 或其他生命周期方法中调用
// LinearLayout layout = new LinearLayout(this);
// layout.setOrientation(LinearLayout.VERTICAL);
// // 创建布局参数(宽度和高度)
// ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
// ViewGroup.LayoutParams.MATCH_PARENT,
// ViewGroup.LayoutParams.MATCH_PARENT
// );
// addContentView(aboutView, params);
LinearLayout layout = findViewById(R.id.aboutviewroot_ll);
// 创建布局参数(宽度和高度)
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
layout.addView(aboutView, params);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public AboutView CreateAboutView() {
String szBranchName = "app";
APPInfo appInfo = new APPInfo();
appInfo.setAppName("APP");
appInfo.setAppIcon(cc.winboll.studio.libaes.R.drawable.ic_winboll);
appInfo.setAppDescription("WinBoll APP");
appInfo.setAppGitName("APP");
appInfo.setAppGitOwner("Studio");
appInfo.setAppGitAPPBranch(szBranchName);
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=APP");
appInfo.setAppAPKName("APP");
appInfo.setAppAPKFolderName("APP");
return new AboutView(mContext, appInfo);
}
}

View File

@@ -5,26 +5,20 @@ package cc.winboll.studio.app;
* @Date 2024/12/08 15:10:51
* @Describe 全局应用类
*/
import android.view.Gravity;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.winboll.WinBollActivityManager;
import com.hjq.toast.ToastUtils;
import cc.winboll.studio.shared.app.WinBollApplication;
import cc.winboll.studio.shared.log.LogUtils;
public class App extends GlobalApplication {
public class App extends WinBollApplication {
public static final String TAG = "App";
@Override
public void onCreate() {
// 必须在调用基类前设置应用调试标志,
// 这样可以预先设置日志与数据的存储根目录。
//setIsDebug(BuildConfig.DEBUG);
super.onCreate();
// 初始化 Toast 框架
ToastUtils.init(this);
// 设置 Toast 布局样式
//ToastUtils.setView(R.layout.toast_custom_view);
//ToastUtils.setStyle(new WhiteToastStyle());
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
getWinBollActivityManager().setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Service);
LogUtils.d(TAG, "onCreate");
}
}

View File

@@ -1,26 +1,98 @@
package cc.winboll.studio.app;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.app.R;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog;
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import cc.winboll.studio.libappbase.winboll.WinBollActivityManager;
import cc.winboll.studio.shared.app.WinBollActivity;
import cc.winboll.studio.shared.app.WinBollActivityManager;
import cc.winboll.studio.shared.app.WinBollApplication;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.shared.util.UriUtils;
import cc.winboll.studio.shared.view.StringToQrCodeView;
import cc.winboll.studio.shared.view.YesNoAlertDialog;
import cc.winboll.studio.unittest.UnitTestActivity;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;
final public class MainActivity extends WinBollActivity implements IWinBollActivity {
final public class MainActivity extends WinBollActivity {
public static final String TAG = "MainActivity";
Toolbar mToolbar;
public static final int REQUEST_HOME_ACTIVITY = 0;
public static final int REQUEST_ABOUT_ACTIVITY = 1;
@Override
public Activity getActivity() {
return this;
protected boolean isEnableDisplayHomeAsUp() {
return false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// 接收并处理 Intent 数据,函数 Intent 处理接收就直接返回
if (prosessIntents(getIntent())) return;
// 以下正常创建主窗口
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 设置 WinBoll 应用 UI 类型
WinBollApplication.setWinBollUI_TYPE(WinBollApplication.WinBollUI_TYPE.Aplication);
//ToastUtils.show("WinBollUI_TYPE " + WinBollApplication.getWinBollUI_TYPE());
LogUtils.d(TAG, "BuildConfig.DEBUG : " + Boolean.toString(BuildConfig.DEBUG));
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setSubTitle("");
}
//
// 处理传入的 Intent 数据
//
boolean prosessIntents(Intent intent) {
if (intent == null
|| intent.getAction() == null
|| intent.getAction().equals(""))
return false;
if (intent.getAction().equals(StringToQrCodeView.ACTION_UNITTEST_QRCODE)) {
try {
WinBollActivity clazzActivity = UnitTestActivity.class.newInstance();
String tag = clazzActivity.getTag();
LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag);
Intent subIntent = new Intent(this, UnitTestActivity.class);
subIntent.setAction(intent.getAction());
File file = new File(getCacheDir(), UUID.randomUUID().toString());
//取出文件uri
Uri uri = intent.getData();
if (uri == null) {
uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
}
//获取文件真实地址
String szSrcPath = UriUtils.getFileFromUri(getApplication(), uri);
if (TextUtils.isEmpty(szSrcPath)) {
return false;
}
Files.copy(Paths.get(szSrcPath), Paths.get(file.getPath()));
//startWinBollActivity(subIntent, tag);
WinBollActivityManager.getInstance(this).startWinBollActivity(this, subIntent, UnitTestActivity.class);
} catch (IllegalAccessException | InstantiationException | IOException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
// 函数处理异常返回失败
return false;
}
} else {
LogUtils.d(TAG, "prosessIntents|" + intent.getAction() + "|yet");
return false;
}
return true;
}
@Override
@@ -28,25 +100,10 @@ final public class MainActivity extends WinBollActivity implements IWinBollActiv
return TAG;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
LogUtils.d(TAG, "onCreate(Bundle savedInstanceState)");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mToolbar.setSubtitle(TAG);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
super.onDestroy();
protected boolean isAddWinBollToolBar() {
return true;
}
@Override
@@ -59,7 +116,7 @@ final public class MainActivity extends WinBollActivity implements IWinBollActiv
@Override
public void onYes() {
App.getWinBollActivityManager().finishAll();
WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
}
@Override
@@ -69,23 +126,43 @@ final public class MainActivity extends WinBollActivity implements IWinBollActiv
YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activitymainToolbar1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_main, menu);
getMenuInflater().inflate(R.menu.toolbar_winboll_app_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item_log) {
App.getWinBollActivityManager().startLogActivity(this);
} else if (item.getItemId() == R.id.item_about) {
App.getWinBollActivityManager().startWinBollActivity(this, AboutActivity.class);
if (item.getItemId() == R.id.item_unittest) {
WinBollActivityManager.getInstance(this).startWinBollActivity(this, UnitTestActivity.class);
} else if (item.getItemId() == R.id.item_exit) {
exit();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) {
case REQUEST_HOME_ACTIVITY : {
LogUtils.d(TAG, "REQUEST_HOME_ACTIVITY");
break;
}
case REQUEST_ABOUT_ACTIVITY : {
LogUtils.d(TAG, "REQUEST_ABOUT_ACTIVITY");
break;
}
default : {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
}

View File

@@ -1,66 +0,0 @@
package cc.winboll.studio.app;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/04/01 12:55:32
* @Describe 应用窗口基类
*/
import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;
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;
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();
super.onCreate(savedInstanceState);
App.getWinBollActivityManager().add(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
App.getWinBollActivityManager().registeRemove(this);
}
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

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<cc.winboll.studio.libaes.views.ASupportToolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:id="@+id/aboutviewroot_ll"/>
</LinearLayout>

View File

@@ -5,10 +5,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<cc.winboll.studio.libaes.views.ASupportToolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"/>
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activitymainToolbar1"/>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
</menu>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">APP</string>
<string name="app_name">WinBoll-APP</string>
</resources>

View File

@@ -19,17 +19,17 @@ def genVersionName(def versionName){
android {
compileSdkVersion 32
buildToolsVersion "32.0.0"
buildToolsVersion "33.0.3"
defaultConfig {
applicationId "cc.winboll.studio.apputils"
minSdkVersion 26
targetSdkVersion 29
minSdkVersion 21
targetSdkVersion 30
versionCode 1
// versionName 更新后需要手动设置
// 项目模块目录的 build.gradle 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.2"
versionName "9.2"
if(true) {
versionName = genVersionName("${versionName}")
}
@@ -41,9 +41,15 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
dependencies {
api project(':libapputils')
api 'cc.winboll.studio:libappbase:1.0.3'
api fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sat Mar 29 12:14:55 HKT 2025
#Sat Jan 18 13:03:10 HKT 2025
stageCount=2
libraryProject=libapputils
baseVersion=15.2
publishVersion=15.2.1
baseVersion=9.2
publishVersion=9.2.1
buildCount=0
baseBetaVersion=15.2.2
baseBetaVersion=9.2.2

View File

@@ -8,7 +8,7 @@
android:allowBackup="true"
android:icon="@drawable/ic_winboll"
android:label="@string/app_name"
android:theme="@style/MyUtilsTheme"
android:theme="@style/WinBoll.SupportThemeNoActionBar"
android:supportsRtl="true">
<activity
@@ -27,13 +27,9 @@
</activity>
<activity android:name=".TestStringToQRCodeViewActivity"/>
<activity android:name=".TestWinBollActivity"/>
<activity android:name=".TestBBMorseCodeActivity"/>
<activity android:name=".AssetsHtmlActivity"/>
<activity android:name=".QRCodeDecodeActivity"/>
<activity android:name=".TestStringToQrCodeViewActivity"/>
</application>

View File

@@ -5,16 +5,27 @@ package cc.winboll.studio.apputils;
* @Date 2024/12/08 15:10:51
* @Describe 全局应用类
*/
import android.app.Application;
import android.content.Context;
import cc.winboll.studio.libappbase.GlobalApplication;
import android.view.Gravity;
import cc.winboll.studio.libapputils.app.WinBollApplication;
import com.hjq.toast.ToastUtils;
import com.hjq.toast.style.WhiteToastStyle;
public class App extends GlobalApplication {
public class App extends WinBollApplication {
public static final String TAG = "App";
public static final String _ACTION_DEBUGVIEW = WinBollApplication.class.getName() + "_ACTION_DEBUGVIEW";
@Override
public void onCreate() {
super.onCreate();
// 初始化 Toast 框架
//
ToastUtils.init(this);
// 设置 Toast 布局样式
//ToastUtils.setView(R.layout.view_toast);
ToastUtils.setStyle(new WhiteToastStyle());
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
}
}

View File

@@ -1,60 +1,38 @@
package cc.winboll.studio.apputils;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import android.widget.Toolbar;
import cc.winboll.studio.apputils.R;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.LogView;
import cc.winboll.studio.libappbase.utils.ToastUtils;
import java.util.List;
import java.util.Set;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity;
import cc.winboll.studio.libapputils.activities.QRCodeDecodeActivity;
import cc.winboll.studio.libapputils.app.WinBollActivity;
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
import cc.winboll.studio.libapputils.log.LogActivity;
import cc.winboll.studio.libapputils.log.LogUtils;
import com.hjq.toast.ToastUtils;
final public class MainActivity extends Activity {
final public class MainActivity extends WinBollActivity {
public static final String TAG = "MainActivity";
public static final int REQUEST_QRCODEDECODE_ACTIVITY = 0;
Toolbar mToolbar;
LogView mLogView;
//
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
protected boolean isEnableDisplayHomeAsUp() {
return false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLogView = findViewById(R.id.logview);
mLogView.start();
// 初始化工具栏
mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar);
// if (isEnableDisplayHomeAsUp()) {
// // 显示后退按钮
// getActionBar().setDisplayHomeAsUpEnabled(true);
// }
// getActionBar().setSubtitle(getTag());
checkResolveActivity();
archiveInstance();
//Toolbar toolbar = findViewById(R.id.activitymainToolbar1);
//setActionBar(toolbar);
// 接收并处理 Intent 数据,函数 Intent 处理接收就直接返回
//if (prosessIntents(getIntent())) return;
@@ -66,94 +44,44 @@ final public class MainActivity extends Activity {
// LogUtils.d(TAG, "BuildConfig.DEBUG : " + Boolean.toString(BuildConfig.DEBUG));
}
boolean checkResolveActivity() {
PackageManager packageManager = getPackageManager();
//Intent intent = new Intent("your_action_here");
Intent intent = getIntent();
if (intent != null) {
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfoList.size() > 0) {
// 传入的Intent action在Activity清单的intent-filter的action节点里有定义
if (intent.getAction() != null) {
// if (intent.getAction().equals(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW)) {
// App.setIsDebug(true);
// //ToastUtils.show!("WinBollApplication.setIsDebug(true) by action : " + intent.getAction());
//
// }
}
return true;
} else {
// 传入的Intent action在Activity清单的intent-filter的action节点里没有定义
//ToastUtils.show("false : " + intent.getAction());
return false;
}
}
// action在清单文件中没有声明
ToastUtils.show("false");
return false;
}
void archiveInstance() {
Intent intent = getIntent();
StringBuilder sb = new StringBuilder("\n### Archive Instance ###\n");
if (intent != null) {
ComponentName componentName = intent.getComponent();
if (componentName != null) {
String packageName = componentName.getPackageName();
//Log.d("AppStarter", "启动本应用的应用包名: " + packageName);
sb.append("启动本应用的应用包名: \n" + packageName);
}
sb.append("\nImplicit Intent Tracker \n接收到的 Intent 动作: \n" + intent.getAction());
Set<String> categories = intent.getCategories();
if (categories != null) {
for (String category : categories) {
sb.append("\n接收到的 Intent 类别 :\n" + category);
}
}
Uri data = intent.getData();
if (data != null) {
sb.append("\n接收到的 Intent 数据 :\n" + data.toString());
}
} else {
sb.append("Intent is null.");
}
sb.append("\n\n");
LogUtils.d(TAG, sb.toString());
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// 缓存当前 activity
//WinBollActivityManager.getInstance(this).add(this);
}
@Override
public void onDestroy() {
//WinBollActivityManager.getInstance(this).registeRemove(this);
super.onDestroy();
}
public void onTestLogClick(View view) {
LogUtils.d(TAG, "onTestLogClick");
Toast.makeText(getApplication(), "onTestLogClick", Toast.LENGTH_SHORT).show();
}
public void onTestLogActivity(View view) {
// Intent intent = new Intent(this, LogActivity.class);
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
// intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
// startActivity(intent);
//WinBollActivityManager.getInstance().printAvtivityListInfo();
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
public void onLogUtilsClick(View view) {
Intent intent = new Intent(this, LogActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// setSubTitle("");
}
@Override
public void onBackPressed() {
// exit();
}
// void exit() {
// YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
//
// @Override
// public void onYes() {
// WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
// }
//
// @Override
// public void onNo() {
// }
// };
// YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
// }
//
// 处理传入的 Intent 数据
//
@@ -198,106 +126,57 @@ final public class MainActivity extends Activity {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//ToastUtils.show("onCreateOptionsMenu");
getMenuInflater().inflate(R.menu.toolbar_main, menu);
// if (isAddWinBollToolBar()) {
// //ToastUtils.show("mIWinBoll.isAddWinBollToolBar()");
// getMenuInflater().inflate(R.menu.toolbar_winboll_shared_main, menu);
// }
if (App.isDebuging()) {
getMenuInflater().inflate(R.menu.toolbar_studio_debug, menu);
}
public String getTag() {
return TAG;
}
@Override
protected boolean isAddWinBollToolBar() {
return true;
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activitymainToolbar1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item_exit) {
//exit();
return true;
if (item.getItemId() == R.id.item_testwinboll) {
WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestWinBollActivity.class);
} else if (item.getItemId() == R.id.item_teststringtoqrcodeview) {
Intent intent = new Intent(this, TestStringToQRCodeViewActivity.class);
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) {
Intent intent = new Intent(this, QRCodeDecodeActivity.class);
startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY);
} else if (item.getItemId() == R.id.item_testcrashreport) {
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
getString(i);
}
return true;
} else if (item.getItemId() == R.id.item_log) {
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
return true;
} else if (item.getItemId() == R.id.item_exitdebug) {
//AboutView.setApp2NormalMode(this);
return true;
} else if (item.getItemId() == android.R.id.home) {
//WinBollActivityManager.getInstance(this).finish(this);
return true;
}
return super.onOptionsItemSelected(item);
}
// void exit() {
// YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
//
// @Override
// public void onYes() {
// //WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
// }
//
// @Override
// public void onNo() {
// }
// };
// YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
//
// }
@Override
public void onBackPressed() {
// if (WinBollActivityManager.getInstance(getApplicationContext()).isFirstIWinBollActivity(this)) {
// exit();
// } else {
// WinBollActivityManager.getInstance(this).finish(this);
// super.onBackPressed();
// }
}
public void onTestAssetsHtmlActivity(View view) {
public void onTestJavascriptHtmlActivity(View view) {
Intent intent = new Intent(this, AssetsHtmlActivity.class);
intent.putExtra(AssetsHtmlActivity.EXTRA_HTMLFILENAME, "javascript_test.html");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AssetsHtmlActivity.class);
WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AssetsHtmlActivity.class);
}
@Override
protected void onResume() {
super.onResume();
mLogView.start();
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_QRCODEDECODE_ACTIVITY : {
String text = data.getStringExtra(QRCodeDecodeActivity.EXTRA_RESULT);
ToastUtils.show(text);
break;
}
default : {
ToastUtils.show(String.format("%d, %d", requestCode, resultCode));
super.onActivityResult(requestCode, resultCode, data);
}
}
}
/*@Override
protected void onActivithyResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_QRCODEDECODE_ACTIVITY : {
if (data != null) {
String text = data.getStringExtra(QRCodeDecodeActivity.EXTRA_RESULT);
ToastUtils.show(text);
}
break;
}
default : {
//ToastUtils.show(String.format("%d, %d", requestCode, resultCode));
super.prosessActivityResult(requestCode, resultCode, data);
}
}
}*/
}

View File

@@ -1,20 +0,0 @@
package cc.winboll.studio.apputils;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/23 16:14:45
*/
import android.app.Activity;
import android.os.Bundle;
public class TestBBMorseCodeActivity extends Activity {
public static final String TAG = "TestBBMorseCodeActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testbbmorsecode);
}
}

View File

@@ -0,0 +1,50 @@
package cc.winboll.studio.apputils;
import android.os.Bundle;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libapputils.app.WinBollActivity;
import cc.winboll.studio.libapputils.view.StringToQrCodeView;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2025/01/17 19:50:46
*/
public class TestStringToQrCodeViewActivity extends WinBollActivity {
public static final String TAG = "TestStringToQrCodeViewActivity";
StringToQrCodeView mStringToQrCodeView;
@Override
public String getTag() {
return TAG;
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activityteststringtoqrcodeviewToolbar1);
}
@Override
protected boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
protected boolean isAddWinBollToolBar() {
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teststringtoqrcodeview);
mStringToQrCodeView = findViewById(R.id.activityteststringtoqrcodeviewStringToQrCodeView1);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setSubTitle(TAG);
}
}

View File

@@ -0,0 +1,52 @@
package cc.winboll.studio.apputils;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity;
import cc.winboll.studio.libapputils.app.WinBollActivity;
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2025/01/13 15:09:46
*/
public class TestWinBollActivity extends WinBollActivity {
public static final String TAG = "TestWinBollActivity";
@Override
public String getTag() {
return TAG;
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activitytestwinbollToolbar1);
}
@Override
protected boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
protected boolean isAddWinBollToolBar() {
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testwinboll);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setSubTitle(TAG);
}
}

View File

@@ -1,52 +0,0 @@
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,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"/>
<cc.winboll.studio.libapputils.views.SimpleWebView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:id="@+id/activityassetshtmlSimpleWebView1"/>
</LinearLayout>

View File

@@ -5,10 +5,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"/>
android:id="@+id/activitymainToolbar1"/>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -27,39 +27,32 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestLog"
android:textAllCaps="false"
android:textAllCaps="false"
android:onClick="onTestLogClick"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestLogActivity"
android:text="LogUtils"
android:textAllCaps="false"
android:onClick="onTestLogActivity"/>
android:onClick="onLogUtilsClick"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="TestAssetsHtmlActivity"
android:onClick="onTestAssetsHtmlActivity"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Test Javascript Html Activity"
android:onClick="onTestJavascriptHtmlActivity"/>
</LinearLayout>
<cc.winboll.studio.libappbase.LogView
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Button"
android:id="@+id/logview"
android:layout_weight="1.0"/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="QRCodeDecodeActivity"/>
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/activityqrcodedecodeDecoratedBarcodeView1"/>
</LinearLayout>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>

View File

@@ -6,10 +6,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"/>
android:id="@+id/activityteststringtoqrcodeviewToolbar1"/>
<LinearLayout
android:orientation="vertical"
@@ -17,7 +17,7 @@
android:layout_height="0dp"
android:layout_weight="1.0">
<cc.winboll.studio.libapputils.views.StringToQrCodeView
<cc.winboll.studio.libapputils.view.StringToQrCodeView
android:layout_width="300dp"
android:layout_height="300dp"
android:id="@+id/activityteststringtoqrcodeviewStringToQrCodeView1"/>

View File

@@ -7,7 +7,7 @@
android:layout_height="match_parent"
android:background="#FF36B5B3">
<android.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activitytestwinbollToolbar1"/>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_gradient"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp">
<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="#FF000000"
android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_testwinboll"
android:title="TestWinBollActivity"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/item_teststringtoqrcodeview"
android:title="TestStringToQRCodeViewActivity"/>
android:title="TestStringToQrCodeViewActivity"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/item_testqrcodedecodeactivity"
android:title="TestQRCodeDecodeActivity"/>
<item
android:id="@+id/item_testcrashreport"
android:title="TestCrashReportActivity"/>
android:title="TestQRCodeDecodeActivity"
app:showAsAction="ifRoom"/>
</menu>

View File

@@ -4,4 +4,7 @@
<color name="colorPrimary">#FF196ABC</color>
<color name="colorPrimaryDark">#FF002B57</color>
<color name="colorAccent">#FF80BFFF</color>
<color name="colorToastFrame">#FFA9A9A9</color>
<color name="colorToastShadow">#FF000000</color>
<color name="colorToastBackgroung">#FFFFFFFF</color>
</resources>

View File

@@ -1,14 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyUtilsTheme" parent="UtilsTheme">
<item name="attrColorPrimary">@color/colorPrimary</item>
<item name="themeGlobalCrashActivity">@style/MyUtilsGlobalCrashActivityTheme</item>
</style>
<style name="MyUtilsGlobalCrashActivityTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
<item name="colorTittle">#FFF2F2F2</item>
<item name="colorTittleBackgound">#FF55ABF8</item>
<item name="colorText">#FF55ABF8</item>
<item name="colorTextBackgound">#FFF2F2F2</item>
</style>
</resources>

View File

@@ -18,18 +18,18 @@ def genVersionName(def versionName){
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 32
buildToolsVersion "33.0.3"
defaultConfig {
applicationId "cc.winboll.studio.autoinstaller"
minSdkVersion 26
targetSdkVersion 29
minSdkVersion 24
targetSdkVersion 30
versionCode 2
// versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.2"
versionName "5.0"
if(true) {
versionName = genVersionName("${versionName}")
}
@@ -41,33 +41,30 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
// 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 'cc.winboll.studio:winboll-shared:1.1.0'
api 'io.github.medyo:android-about-page:2.0.0'
// 吐司类库
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'
// 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 'cc.winboll.studio:libaes:15.2.5'
api 'cc.winboll.studio:libapputils:15.2.1'
api 'cc.winboll.studio:libappbase:15.2.2'
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
#Wed Apr 02 21:25:51 HKT 2025
stageCount=1
#Thu Jan 02 02:39:56 HKT 2025
stageCount=4
libraryProject=
baseVersion=15.2
publishVersion=15.2.0
baseVersion=5.0
publishVersion=5.0.3
buildCount=0
baseBetaVersion=15.2.1
baseBetaVersion=5.0.4

View File

@@ -33,7 +33,7 @@
android:persistent="true"
android:supportsRtl="true"
android:requestLegacyExternalStorage="true"
android:theme="@style/MyAppTheme">
android:theme="@style/Theme.Application">
<activity
android:name=".MainActivity"

View File

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

View File

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

View File

@@ -12,15 +12,15 @@ import android.widget.RadioButton;
import android.widget.SimpleAdapter;
import android.widget.Switch;
import android.widget.TextClock;
import android.widget.Toast;
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.models.APKModel;
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.utils.NotificationUtil;
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 java.io.File;
import java.util.ArrayList;
@@ -31,8 +31,7 @@ public class MainActivity extends Activity {
public static final String TAG = "MainActivity";
private static final int INSTALL_PERMISSION_CODE = 1;
ArrayList<APKModel> _APKModelList = new ArrayList<APKModel>();
LogView mLogView;
TextClock mTextClock;
EditText mEditText;
@@ -132,24 +131,14 @@ 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) {
String szInstalledPackageName = getLastApkPackageName();
if (szInstalledPackageName.trim().equals("")) {
if (mszInstalledPackageName.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 {
// 若没能获取到启动意图,可进行相应提示等操作,比如跳转到应用商店让用户下载该应用(示例)
@@ -206,7 +195,7 @@ public class MainActivity extends Activity {
//
if (szFilePath.trim().equals("")) {
sw.setChecked(false);
ToastUtils.show("监控路径为空。");
Toast.makeText(getApplication(), "监控路径为空。", Toast.LENGTH_SHORT).show();
return;
}
@@ -262,6 +251,8 @@ public class MainActivity extends Activity {
Intent intentService = new Intent(MainActivity.this, MainService.class);
//intentService.putExtra(MainService.EXTRA_APKFILEPATH, szAPKFilePath);
startService(intentService);
}
/*

View File

@@ -1,4 +1,4 @@
package cc.winboll.studio.autoinstaller.models;
package cc.winboll.studio.autoinstaller.beans;
/**
* @Author ZhanGSKen@QQ.COM
@@ -8,13 +8,13 @@ package cc.winboll.studio.autoinstaller.models;
import android.content.Context;
import android.util.JsonReader;
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.libappbase.LogUtils;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import cc.winboll.studio.shared.log.LogUtils;
public class AppConfigs implements Serializable {

View File

@@ -4,9 +4,9 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
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.libappbase.LogUtils;
import cc.winboll.studio.shared.log.LogUtils;
/**
* @Author ZhanGSKen@QQ.COM

View File

@@ -6,7 +6,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
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;
/**

View File

@@ -12,26 +12,23 @@ import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;
import androidx.core.content.FileProvider;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.autoinstaller.FileListener;
import cc.winboll.studio.autoinstaller.MainActivity;
import cc.winboll.studio.autoinstaller.models.APKModel;
import cc.winboll.studio.autoinstaller.models.AppConfigs;
import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.services.AssistantService;
import cc.winboll.studio.autoinstaller.services.MainService;
import cc.winboll.studio.autoinstaller.utils.NotificationUtil;
import cc.winboll.studio.autoinstaller.utils.PackageUtil;
import cc.winboll.studio.autoinstaller.utils.ServiceUtil;
import cc.winboll.studio.libappbase.LogUtils;
import com.hjq.toast.ToastUtils;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
public class MainService extends Service {
public static String TAG = "MainService";
ArrayList<APKModel> _APKModelList = new ArrayList<APKModel>();
private static boolean _mIsServiceAlive;
//String mszAPKFilePath;
//String mszAPKFileName;
@@ -78,7 +75,6 @@ public class MainService extends Service {
startWatchingFile(appConfigs.getWatchingFilePath());
LogUtils.d(TAG, "running...");
ToastUtils.show("running...");
} else {
LogUtils.d(TAG, "_mIsServiceAlive is " + Boolean.toString(_mIsServiceAlive));
@@ -180,9 +176,6 @@ public class MainService extends Service {
// 调用[应用信息查看器]打开应用包
//
private void installAPK(String szAPKFilePath) {
String szAPKPackageName = PackageUtil.getPackageNameFromApk(this, szAPKFilePath);
saveAPKInfo(szAPKPackageName);
long nTimeNow = System.currentTimeMillis();
/*SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault());
@@ -217,24 +210,15 @@ public class MainService extends Service {
//
void installAPK2(String szAPKFilePath) {
LogUtils.d(TAG, "installAPK2()");
String szAPKPackageName = PackageUtil.getPackageNameFromApk(this, szAPKFilePath);
saveAPKInfo(szAPKPackageName);
Intent intent = new Intent(this, MainActivity.class);
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.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
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 {

View File

@@ -8,7 +8,7 @@ package cc.winboll.studio.autoinstaller.utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.shared.log.LogUtils;
public class PackageUtil {

View File

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

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

@@ -0,0 +1 @@

67
demo/build.gradle Normal file
View File

@@ -0,0 +1,67 @@
apply plugin: 'com.android.application'
apply from: '../.winboll/winboll_app_build.gradle'
apply from: '../.winboll/winboll_lint_build.gradle'
def genVersionName(def versionName){
// 检查编译标志位配置
assert (winbollBuildProps['stageCount'] != null)
assert (winbollBuildProps['baseVersion'] != null)
// 保存基础版本号
winbollBuildProps.setProperty("baseVersion", "${versionName}");
//保存编译标志配置
FileOutputStream fos = new FileOutputStream(winbollBuildPropsFile)
winbollBuildProps.store(fos, "${winbollBuildPropsDesc}");
fos.close();
// 返回编译版本号
return "${versionName}." + winbollBuildProps['stageCount']
}
android {
compileSdkVersion 32
buildToolsVersion "33.0.3"
defaultConfig {
applicationId "cc.winboll.studio.demo"
minSdkVersion 24
targetSdkVersion 30
versionCode 1
// versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "1.0"
if(true) {
versionName = genVersionName("${versionName}")
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
//api 'cc.winboll.studio:winboll-shared:1.8.0'
api 'io.github.medyo:android-about-page:2.0.0'
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 'androidx.appcompat:appcompat:1.0.0'
api 'androidx.fragment:fragment:1.0.0'
api 'com.google.android.material:material:1.0.0'
api 'cc.winboll.studio:libapputils:9.2.0'
api 'cc.winboll.studio:libappbase:1.0.3'
api fileTree(dir: 'libs', include: ['*.jar'])
}

8
demo/build.properties Normal file
View File

@@ -0,0 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon Jan 13 07:34:21 GMT 2025
stageCount=8
libraryProject=
baseVersion=1.0
publishVersion=1.0.7
buildCount=11
baseBetaVersion=1.0.8

17
demo/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<application
tools:replace="android:icon"
android:icon="@drawable/ic_winbollbeta">
<!-- Put flavor specific code here -->
</application>
</manifest>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">WinBoll-Demo+</string>
</resources>

View File

@@ -0,0 +1,39 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.winboll.studio.demo"
android:sharedUserId="cc.winboll.studio">
<!-- 拥有完全的网络访问权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".App"
android:allowBackup="true"
android:icon="@drawable/ic_winboll"
android:label="@string/app_name"
android:theme="@style/WinBoll.SupportThemeNoActionBar"
android:supportsRtl="true">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="standard"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".activities.AboutActivity"
android:label="AboutActivity"/>
</application>
</manifest>

View File

@@ -0,0 +1,19 @@
package cc.winboll.studio.demo;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/11/28 15:42:47
* @Describe 全局应用类
*/
import cc.winboll.studio.libapputils.app.WinBollApplication;
public class App extends WinBollApplication {
public static final String TAG = "App";
@Override
public void onCreate() {
super.onCreate();
}
}

View File

@@ -0,0 +1,86 @@
package cc.winboll.studio.demo;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libapputils.app.WinBollActivity;
import cc.winboll.studio.libapputils.app.WinBollApplication;
import cc.winboll.studio.libapputils.log.LogUtils;
final public class MainActivity extends WinBollActivity {
public static final String TAG = "MainActivity";
public static final int REQUEST_HOME_ACTIVITY = 0;
public static final int REQUEST_ABOUT_ACTIVITY = 1;
@Override
protected boolean isEnableDisplayHomeAsUp() {
return false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 设置 WinBoll 应用 UI 类型
WinBollApplication.setWinBollUI_TYPE(WinBollApplication.WinBollUI_TYPE.Aplication);
//ToastUtils.show("WinBollUI_TYPE " + WinBollApplication.getWinBollUI_TYPE());
}
@Override
public String getTag() {
return TAG;
}
@Override
protected boolean isAddWinBollToolBar() {
return true;
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activitymainToolbar1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// if (item.getItemId() == R.id.item_about) {
// try {
// WinBollActivity clazzActivity = AboutActivity.class.newInstance();
// String tag = clazzActivity.getTag();
// LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag);
// Intent intent = new Intent(getApplicationContext(), AboutActivity.class);
// startWinBollActivity(intent, tag);
// } catch (IllegalAccessException e) {} catch (InstantiationException e) {}
// }
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) {
case REQUEST_HOME_ACTIVITY : {
LogUtils.d(TAG, "REQUEST_HOME_ACTIVITY");
break;
}
case REQUEST_ABOUT_ACTIVITY : {
LogUtils.d(TAG, "REQUEST_ABOUT_ACTIVITY");
break;
}
default : {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:clickable="true">
<item android:drawable="@drawable/ic_launcher_background"/>
<item
android:left="15dp"
android:top="15dp"
android:right="15dp"
android:bottom="15dp"
android:drawable="@drawable/ic_launcher_foreground"/>
</layer-list>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="@color/colorPrimary"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@@ -0,0 +1,10 @@
<?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="#FFFFFFFF"
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

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="180"
android:endColor="#FFFFFFFF"
android:startColor="#FFFFFFFF"
android:type="linear" />
<corners android:radius="10dp" />
</shape>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activitymainToolbar1"/>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center"
android:layout_weight="1.0">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, WinBoll!"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_gradient"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp">
<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="#FF000000"
android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_help"
android:title="HELP"/>
</menu>

View File

@@ -1,9 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_log"
android:title="Log"/>
<item
android:id="@+id/item_about"
android:title="About"/>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- WinBoll 默认方案 -->
<color name="colorPrimary">#FF196ABC</color>
<color name="colorPrimaryDark">#FF002B57</color>
<color name="colorAccent">#FF80BFFF</color>
<color name="colorToastFrame">#FFA9A9A9</color>
<color name="colorToastShadow">#FF000000</color>
<color name="colorToastBackgroung">#FFFFFFFF</color>
</resources>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">WinBoll-Demo</string>
</resources>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<application>
<!-- Put flavor specific code here -->
</application>
</manifest>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Put flavor specific strings here -->
</resources>

View File

@@ -51,6 +51,6 @@ dependencies {
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
//api 'androidx.fragment:fragment:1.1.0'
api 'cc.winboll.studio:libapputils:15.2.1'
api 'cc.winboll.studio:libappbase:15.2.2'
api 'cc.winboll.studio:libappbase:15.2.0'
api 'cc.winboll.studio:libapputils:15.2.0'
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Apr 02 20:08:50 HKT 2025
stageCount=6
#Mon Mar 31 02:04:35 HKT 2025
stageCount=4
libraryProject=libaes
baseVersion=15.2
publishVersion=15.2.5
publishVersion=15.2.3
buildCount=0
baseBetaVersion=15.2.6
baseBetaVersion=15.2.4

View File

@@ -118,7 +118,7 @@ public class AboutView extends LinearLayout {
} else {
mszGitea = "https://gitea.winboll.cc/" + mAPPInfo.getAppGitOwner() + "/" + mszAppGitName + "/src/branch/" + mAPPInfo.getAppGitAPPBranch() + "/" + mAPPInfo.getAppGitAPPSubProjectFolder();
}
if (GlobalApplication.isDebuging()) {
LayoutInflater inflater = LayoutInflater.from(mContext);
@@ -150,7 +150,7 @@ public class AboutView extends LinearLayout {
// 初始化标题栏
//setSubtitle(getContext().getString(R.string.text_about));
// LinearLayout llMain = findViewById(R.id.viewaboutLinearLayout1);
// llMain.addView(createAboutPage());
@@ -282,7 +282,6 @@ public class AboutView extends LinearLayout {
//intent.setAction(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
GlobalApplication.setIsDebuging(true);
GlobalApplication.saveDebugStatus();
GlobalApplication.getWinBollActivityManager().finishAll();
context.startActivity(intent);
@@ -294,7 +293,6 @@ public class AboutView extends LinearLayout {
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
GlobalApplication.setIsDebuging(false);
GlobalApplication.saveDebugStatus();
GlobalApplication.getWinBollActivityManager().finishAll();
context.startActivity(intent);
@@ -324,17 +322,14 @@ public class AboutView extends LinearLayout {
PrefUtils.saveString(mContext, "metDevUserName", metDevUserName.getText().toString());
PrefUtils.saveString(mContext, "metDevUserPassword", metDevUserPassword.getText().toString());
} else {
String username = "WinBoll";
String password = "WinBollPowerByZhanGSKen";
credential = Credentials.basic(username, password);
credential = Credentials.basic("WinBoll", "WinBollPowerByZhanGSKen");
}
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(szUrl)
.header("Accept", "text/plain") // 设置正确的Content-Type头
.header("Authorization", credential)
.build();
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override

View File

@@ -252,7 +252,6 @@ public class WinBollServiceStatusView extends LinearLayout {
username = "WinBoll";
password = "WinBollPowerByZhanGSKen";
}
LogUtils.d(TAG, String.format("Connection Start. targetUrl %s", targetUrl));
WinBollServerConnectionThread thread = new WinBollServerConnectionThread(
targetUrl,

View File

@@ -1,7 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#BF4C4C4C" />
<!-- 定义成圆角的 -->
<corners android:radius="15dp" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 边框阴影部分 -->
<!-- 相对边框的Offset设置(android:left, top, right, bottom) -->
<item
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp">
<shape android:shape="rectangle" >
<gradient
android:angle="270"
android:startColor="@color/colorToastShadow"
android:centerColor="@color/colorToastShadow"
android:endColor="@color/colorToastShadow"/>
<corners
android:bottomLeftRadius="10dip"
android:bottomRightRadius="10dip"
android:topLeftRadius="10dip"
android:topRightRadius="10dip" />
</shape>
</item>
<!-- 边框部分 -->
<item
android:left="0dp"
android:top="0dp"
android:right="1dp"
android:bottom="2dp">
<shape android:shape="rectangle" >
<gradient
android:angle="270"
android:startColor="@color/colorToastFrame"
android:centerColor="@color/colorToastFrame"
android:endColor="@color/colorToastFrame"/>
<corners
android:bottomLeftRadius="10dip"
android:bottomRightRadius="10dip"
android:topLeftRadius="10dip"
android:topRightRadius="10dip" />
</shape>
</item>
<!-- 背景主体部分 -->
<item
android:left="2dp"
android:top="2dp"
android:right="3dp"
android:bottom="3dp">
<shape android:shape="rectangle" >
<gradient
android:type="linear"
android:angle="90"
android:startColor="@color/colorToastBackgroung"
android:centerColor="@color/colorToastBackgroung"
android:endColor="@color/colorToastBackgroung"/>
<corners
android:bottomLeftRadius="10dip"
android:bottomRightRadius="10dip"
android:topLeftRadius="10dip"
android:topRightRadius="10dip" />
</shape>
</item>
</layer-list>

View File

@@ -1,38 +1,35 @@
<?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">
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"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:id="@+id/customtoastTextView1"
android:background="#FFFFFFFF"
android:gravity="center_horizontal"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#FFE8E8E8"/>
<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>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="Text"
android:id="@+id/customtoastTextView2"
android:background="#FFFFFFFF"
android:gravity="center_horizontal"/>
</LinearLayout>

View File

@@ -5,11 +5,11 @@ apply from: '../.winboll/winboll_lint_build.gradle'
android {
compileSdkVersion 32
buildToolsVersion "32.0.0"
buildToolsVersion "33.0.3"
defaultConfig {
minSdkVersion 24
targetSdkVersion 29
minSdkVersion 21
targetSdkVersion 30
}
buildTypes {
release {
@@ -17,43 +17,28 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
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'
api 'cc.winboll.studio:libappbase:15.2.0'
// 二维码类库
// 二维码使用的类库
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 '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'
// Html 解析
api 'org.jsoup:jsoup:1.13.1'
api 'androidx.appcompat:appcompat:1.0.0'
api 'androidx.fragment:fragment:1.0.0'
api 'com.google.android.material:material:1.0.0'
// SSH
//api 'com.jcraft:jsch:0.1.55'
api 'cc.winboll.studio:libappbase:1.0.3'
api fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sat Mar 29 12:14:39 HKT 2025
#Sat Jan 18 13:02:39 HKT 2025
stageCount=2
libraryProject=libapputils
baseVersion=15.2
publishVersion=15.2.1
baseVersion=9.2
publishVersion=9.2.1
buildCount=0
baseBetaVersion=15.2.2
baseBetaVersion=9.2.2

View File

@@ -18,12 +18,31 @@
<!-- 拍摄照片和视频 -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- 拥有完全的网络访问权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<application android:networkSecurityConfig="@xml/network_security_config">
<application
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".app.CrashHandler$CrashActiviy"
android:label="CrashActiviy"
android:launchMode="standard"/>
<activity
android:name=".log.LogActivity"
android:label="LogActivity"
android:launchMode="standard"/>
<activity
android:name=".activities.AboutActivity"
android:label="AboutActivity"
android:launchMode="standard"/>
<activity
android:name=".activities.AssetsHtmlActivity"
android:label="AssetsHtmlActivity"/>
<activity
android:name=".activities.QRCodeDecodeActivity"
android:label="QRCodeDecodeActivity"/>
</application>
</manifest>
</manifest>

View File

@@ -0,0 +1,87 @@
package cc.winboll.studio.libapputils.activities;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libapputils.R;
import cc.winboll.studio.libapputils.app.WinBollActivity;
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
import cc.winboll.studio.libapputils.log.LogUtils;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/07/14 13:20:33
* @Describe AboutFragment Test
*/
final public class AboutActivity extends WinBollActivity {
public static final String TAG = "AboutActivity";
@Override
public String getTag() {
return TAG;
}
@Override
protected boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
/*AboutView aboutView = findViewById(R.id.activityaboutAboutView1);
aboutView.setOnRequestDevUserInfoAutofillListener(new AboutView.OnRequestDevUserInfoAutofillListener(){
@Override
public void requestAutofill(EditText etDevUserName, EditText etDevUserPassword) {
AutofillManager autofillManager = (AutofillManager) getSystemService(AutofillManager.class);
if (autofillManager!= null) {
//ToastUtils.show("0");
autofillManager.requestAutofill(findViewById(R.id.usernameEditText));
autofillManager.requestAutofill(findViewById(R.id.passwordEditText));
}
}
});*/
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setSubTitle(TAG);
}
@Override
protected boolean isAddWinBollToolBar() {
return false;
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activityaboutToolbar1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_winboll_shared_about, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item_help) {
WinBollActivityManager.getInstance(this).startWinBollActivity(this, AssetsHtmlActivity.class);
}
// else if (item.getItemId() == android.R.id.home) {
// WinBollActivityManager.getInstance(this).finish(this);
// }
return super.onOptionsItemSelected(item);
}
}

View File

@@ -1,53 +1,59 @@
package cc.winboll.studio.apputils;
package cc.winboll.studio.libapputils.activities;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2025/01/03 11:02:49
* @Describe 一个可以浏览随 APP 附带的 Html 文档的窗口
*/
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toolbar;
import cc.winboll.studio.apputils.R;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import cc.winboll.studio.libapputils.views.SimpleWebView;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libapputils.R;
import cc.winboll.studio.libapputils.app.WinBollActivity;
import cc.winboll.studio.libapputils.log.LogUtils;
import cc.winboll.studio.libapputils.view.SimpleWebView;
import com.hjq.toast.ToastUtils;
import java.io.IOException;
import java.io.InputStream;
import android.os.PersistableBundle;
public class AssetsHtmlActivity extends WinBollActivityBase implements IWinBollActivity {
@Override
public Activity getActivity() {
return super.getActivity();
}
@Override
public String getTag() {
return TAG;
}
public class AssetsHtmlActivity extends WinBollActivity {
public static final String TAG = "AssetsHtmlActivity";
public static final String EXTRA_HTMLFILENAME = "EXTRA_HTMLFILENAME";
String mszHelpIndexFilePath = "";
Uri mszHelpIndexFileUri;
Context mContext;
// Assets 文件夹里的 Html 文件的名称
String mszHtmlFileName;
//
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
public String getTag() {
return TAG;
}
@Override
protected boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
protected boolean isAddWinBollToolBar() {
return false;
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activityassetshtmlToolbar1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
@@ -67,10 +73,6 @@ public class AssetsHtmlActivity extends WinBollActivityBase implements IWinBollA
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_assetshtml);
// 初始化工具栏
Toolbar mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar);
mszHtmlFileName = "index.html";
Intent intent = getIntent();
@@ -79,7 +81,7 @@ public class AssetsHtmlActivity extends WinBollActivityBase implements IWinBollA
if (szTemp != null && !szTemp.trim().equals("")) {
mszHtmlFileName = szTemp.trim();
}
//ToastUtils.show(mszHtmlFileName);
ToastUtils.show(mszHtmlFileName);
}
// 与其他应用分享 html 帮助
@@ -105,6 +107,13 @@ public class AssetsHtmlActivity extends WinBollActivityBase implements IWinBollA
// myWebView.loadUrl(mszHelpIndexFileUri.toString());
}
@Override
public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
setSubTitle(mszHtmlFileName);
//setSubTitle(TAG);
}
//
void initWebViewFromAssets(String szHtmlFileName) {
try {

View File

@@ -1,59 +1,72 @@
package cc.winboll.studio.apputils;
package cc.winboll.studio.libapputils.activities;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2025/01/18 10:32:21
* @Describe 二维码扫码解码窗口
*/
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toolbar;
import cc.winboll.studio.apputils.R;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import cc.winboll.studio.libapputils.R;
import cc.winboll.studio.libapputils.app.WinBollActivity;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import java.util.List;
public class QRCodeDecodeActivity extends Activity {
public class QRCodeDecodeActivity extends WinBollActivity {
public static final String TAG = "QRCodeDecodeActivity";
public static final String EXTRA_RESULT = "EXTRA_RESULT";
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final int REQUEST_CAMERA_PERMISSION = 1;
TextView resultTextView;
DecoratedBarcodeView barcodeView;
@Override
public String getTag() {
return TAG;
}
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
protected boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
protected boolean isAddWinBollToolBar() {
return false;
}
@Override
protected Toolbar initToolBar() {
return findViewById(R.id.activityqrcodedecodeToolbar1);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qrcodedecode);
// 初始化工具栏
// Toolbar mToolbar = findViewById(R.id.toolbar);
// setActionBar(mToolbar);
//resultTextView = findViewById(R.id.activityqrcodedecodeTextView1);
resultTextView = findViewById(R.id.activityqrcodedecodeTextView1);
barcodeView = findViewById(R.id.activityqrcodedecodeDecoratedBarcodeView1);
// 请求相机权限
// if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
// != PackageManager.PERMISSION_GRANTED) {
// ActivityCompat.requestPermissions(this,
// new String[]{android.Manifest.permission.CAMERA},
// REQUEST_CAMERA_PERMISSION);
// } else {
// startScanning();
// }
startScanning();
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION);
} else {
startScanning();
}
}
private void startScanning() {

View File

@@ -0,0 +1,240 @@
package cc.winboll.studio.libapputils.ads;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/12/09 15:37:35
* @Describe WinBoll 应用推广视图
*/
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.RelativeLayout;
import com.hjq.toast.ToastUtils;
public class ADsView extends RelativeLayout {
public static final String TAG = "ADsView";
public volatile boolean mIsHandling;
public volatile boolean mIsAddNewLog;
Context mContext;
WebView mWebView;
//ScrollView mScrollView;
//TextView mTextView;
//CheckBox mSelectableCheckBox;
//LogViewThread mLogViewThread;
//LogViewHandler mLogViewHandler;
//Spinner mLogLevelSpinner;
//ArrayAdapter<CharSequence> mLogLevelSpinnerAdapter;
public ADsView(Context context) {
super(context);
initView(context);
}
public ADsView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public ADsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public ADsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initView(context);
}
// public void start() {
// mLogViewThread = new LogViewThread(LogView.this);
// mLogViewThread.start();
// // 显示日志
// showAndScrollLogView();
// }
//
// public void scrollLogUp() {
// mScrollView.post(new Runnable() {
// @Override
// public void run() {
// mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
// // 日志显示结束
// mLogViewHandler.setIsHandling(false);
// // 检查是否添加了新日志
// if (mLogViewHandler.isAddNewLog()) {
// // 有新日志添加,先更改新日志标志
// mLogViewHandler.setIsAddNewLog(false);
// // 再次发送显示日志的显示
// Message message = mLogViewHandler.obtainMessage(LogViewHandler.MSG_LOGVIEW_UPDATE);
// mLogViewHandler.sendMessage(message);
// }
// }
// });
// }
void initView(Context context) {
mContext = context;
// mLogViewHandler = new LogViewHandler();
// 加载视图布局
View viewMain = inflate(mContext, cc.winboll.studio.libapputils.R.layout.view_ads, null);
mWebView = viewMain.findViewById(cc.winboll.studio.libapputils.R.id.viewadsWebView1);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
ToastUtils.show(url);
return true;
}
});
// // 初始化日志子控件视图
// //
// mScrollView = findViewById(cc.winboll.studio.libapputils.R.id.viewlogScrollViewLog);
// mTextView = findViewById(cc.winboll.studio.libapputils.R.id.viewlogTextViewLog);
// // 获取Log Level spinner实例
// mLogLevelSpinner = findViewById(cc.winboll.studio.libapputils.R.id.viewlogSpinner1);
//
// (findViewById(cc.winboll.studio.libapputils.R.id.viewlogButtonClean)).setOnClickListener(new View.OnClickListener(){
//
// @Override
// public void onClick(View v) {
// LogUtils.cleanLog();
// LogUtils.d(TAG, "Log is cleaned.");
// }
// });
// (findViewById(cc.winboll.studio.libapputils.R.id.viewlogButtonCopy)).setOnClickListener(new View.OnClickListener(){
//
// @Override
// public void onClick(View v) {
//
// ClipboardManager cm = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
// cm.setPrimaryClip(ClipData.newPlainText(mContext.getPackageName(), LogUtils.loadLog()));
// LogUtils.d(TAG, "Log is copied.");
// }
// });
// mSelectableCheckBox = findViewById(cc.winboll.studio.libapputils.R.id.viewlogCheckBoxSelectable);
// mSelectableCheckBox.setOnClickListener(new View.OnClickListener(){
// @Override
// public void onClick(View v) {
// if (mSelectableCheckBox.isChecked()) {
// setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
// } else {
// setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
// }
// }
// });
//
// // 设置日志级别列表
// ArrayList<String> adapterItems = new ArrayList<>();
// for (LogUtils.LOG_LEVEL e : LogUtils.LOG_LEVEL.values()) {
// adapterItems.add(e.name());
// }
// // 假设你有一个字符串数组作为选项列表
// //String[] options = {"Option 1", "Option 2", "Option 3"};
// // 创建一个ArrayAdapter来绑定数据到spinner
// mLogLevelSpinnerAdapter = ArrayAdapter.createFromResource(
// context, cc.winboll.studio.libapputils.R.array.enum_loglevel_array, android.R.layout.simple_spinner_item);
// mLogLevelSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//
// // 设置适配器并将它应用到spinner上
// mLogLevelSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // 设置下拉视图样式
// mLogLevelSpinner.setAdapter(mLogLevelSpinnerAdapter);
// // 为Spinner添加监听器
// mLogLevelSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
// @Override
// public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// //String selectedOption = mLogLevelSpinnerAdapter.getItem(position);
// // 处理选中的选项...
// LogUtils.setLogLevel(LogUtils.LOG_LEVEL.values()[position]);
// }
// @Override
// public void onNothingSelected(AdapterView<?> parent) {
// // 如果没有选择,则执行此操作...
// }
// });
// // 获取默认值的索引
// int defaultValueIndex = LogUtils.getLogLevel().ordinal();
//
// if (defaultValueIndex != -1) {
// // 如果找到了默认值,设置默认选项
// mLogLevelSpinner.setSelection(defaultValueIndex);
// }
//
// // 设置滚动时不聚焦日志
// setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
}
public void loadUrl(String url) {
mWebView.loadUrl(url);
//webView.loadUrl("https://www.winboll.cc");
//webView.loadUrl("https://ads.winboll.cc");
}
// public void updateLogView() {
// if (mLogViewHandler.isHandling() == true) {
// // 正在处理日志显示,
// // 就先设置一个新日志标志位
// // 以便日志显示完后,再次显示新日志内容
// mLogViewHandler.setIsAddNewLog(true);
// } else {
// //LogUtils.d(TAG, "LogListener showLog(String path)");
// Message message = mLogViewHandler.obtainMessage(LogViewHandler.MSG_LOGVIEW_UPDATE);
// mLogViewHandler.sendMessage(message);
// mLogViewHandler.setIsAddNewLog(false);
// }
// }
//
// void showAndScrollLogView() {
// mTextView.setText(LogUtils.loadLog());
// scrollLogUp();
// }
//
// class LogViewHandler extends Handler {
//
// final static int MSG_LOGVIEW_UPDATE = 0;
// volatile boolean isHandling;
// volatile boolean isAddNewLog;
//
// public LogViewHandler() {
// setIsHandling(false);
// setIsAddNewLog(false);
// }
//
// public void setIsHandling(boolean isHandling) {
// this.isHandling = isHandling;
// }
//
// public boolean isHandling() {
// return isHandling;
// }
//
// public void setIsAddNewLog(boolean isAddNewLog) {
// this.isAddNewLog = isAddNewLog;
// }
//
// public boolean isAddNewLog() {
// return isAddNewLog;
// }
//
// public void handleMessage(Message msg) {
// switch (msg.what) {
// case MSG_LOGVIEW_UPDATE:{
// if (isHandling() == false) {
// setIsHandling(true);
// showAndScrollLogView();
// }
// break;
// }
// default:
// break;
// }
// super.handleMessage(msg);
// }
// }
}

View File

@@ -0,0 +1,153 @@
package cc.winboll.studio.libapputils.app;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/08/12 14:45:35
* @Describe 应用版本工具集
*/
import com.hjq.toast.ToastUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AppVersionUtils {
public static final String TAG = "AppVersionUtils";
//
// 检查新版本是否成立
// szCurrentCode : 当前版本应用包名
// szNextCode : 新版本应用包名
// 返回 情况1当前版本是发布版
// 返回 true (新版本 > 当前版本)
// 情况1当前版本是Beta版
// true 新版本 == 当前版本
//
public static boolean isHasNewVersion2(String szCurrentName, String szNextName) {
//szCurrentName = "AES_6.2.0-beta0_3234.apk";
//szNextName = "AES_6.1.12.apk";
//szCurrentName = "AES_6.2.0-beta0_3234.apk";
//szNextName = "AES_6.2.0.apk";
//szCurrentName = "AES_6.2.0-beta0_3234.apk";
//szNextName = "AES_6.2.2.apk";
//szCurrentName = "AES_6.2.0-beta0_3234.apk";
//szNextName = "AES_6.2.0.apk";
//szCurrentName = "AES_6.1.0.apk";
//szNextName = "AES_6.2.0.apk";
//LogUtils.d(TAG, "szCurrentName : " + szCurrentName);
//LogUtils.d(TAG, "szNextName : " + szNextName);
//boolean isVersionNewer = false;
//if(szCurrentName.equals(szNextName)) {
// isVersionNewer = false;
//} else {
//ToastUtils.show("szCurrent : " + szCurrent + "\nszNext : " + szNext);
//int nApk = szNextName.lastIndexOf(".apk");
//ToastUtils.show("nApk : " + Integer.toString(nApk));
//String szNextNoApkName = szNextName.substring(0, nApk);
//ToastUtils.show("szNextNoApkName : " + szNextNoApkName);
//String szCurrentNoApkName = szCurrentName.substring(0, szNextNoApkName.length());
//ToastUtils.show("szCurrentNoApkName : " + szCurrentNoApkName);
//String str1 = "3.4.50";
//String str2 = "3.3.60";
//String str1 = getCodeInPackageName(szCurrentName);
//String str2 = getCodeInPackageName(szNextName);
//String str1 = getCodeInPackageName(szNextName);
//String str2 = getCodeInPackageName(szCurrentName);
//Boolean isVersionNewer2 = checkNewVersion(str1,str2);
//ToastUtils.show("isVersionNewer2 : " + Boolean.toString(isVersionNewer2));
//ToastUtils.show(checkNewVersion(getCodeInPackageName(szCurrentName), getCodeInPackageName(szNextName)));
//return checkNewVersion(getCodeInPackageName(szCurrentName), getCodeInPackageName(szNextName));
//}
//return isVersionNewer;
if (checkNewVersion(getCodeInPackageName(szCurrentName), getCodeInPackageName(szNextName))) {
// 比 AES_6.2.0.apk 版本大,如 AES_6.2.1.apk。
// 比 AES_6.2.0-beta0_3234.apk 大,如 AES_6.2.1.apk。
//LogUtils.d(TAG, "App newer stage version is released. Release name : " + szNextName);
return true;
}
if (szCurrentName.matches(".*_\\d+\\.\\d+\\.\\d+-beta.*\\.apk")) {
String szCurrentReleasePackageName = getReleasePackageName(szCurrentName);
//LogUtils.d(TAG, "szCurrentReleasePackageName : " + szCurrentReleasePackageName);
if (szCurrentReleasePackageName.equals(szNextName)) {
// 与 AES_6.2.0-beta0_3234.apk 版本相同,如 AES_6.2.0.apk。
//LogUtils.d(TAG, "App stage version is released. Release name : " + szNextName);
return true;
}
}
//LogUtils.d(TAG, "App version is the newest. ");
return false;
}
public static boolean isHasNewStageReleaseVersion(String szCurrentName, String szNextName) {
//szCurrentName = "AES_6.2.12.apk";
//szNextName = "AES_6.3.12.apk";
if (checkNewVersion(getCodeInPackageName(szCurrentName), getCodeInPackageName(szNextName))) {
// 比 AES_6.2.0.apk 版本大,如 AES_6.2.1.apk。
//LogUtils.d(TAG, "App newer stage version is released. Release name : " + szNextName);
return true;
}
return false;
}
//
// 检查新版本是否成立
// szCurrentCode : 当前版本
// szNextCode : 新版本
// 返回 true 新版本 > 当前版本
//
public static Boolean checkNewVersion(String szCurrentCode, String szNextCode) {
boolean isNew = false;
String[] appVersionCurrent = szCurrentCode.split("\\.");
String[] appVersionNext = szNextCode.split("\\.");
//根据位数最短的判断
int lim = appVersionCurrent.length > appVersionNext.length ? appVersionNext.length : appVersionCurrent.length;
//根据位数循环判断各个版本
for (int i = 0; i < lim; i++) {
if (Integer.parseInt(appVersionNext[i]) > Integer.parseInt(appVersionCurrent[i])) {
isNew = true;
return isNew;
} else if(Integer.parseInt(appVersionNext[i]) == Integer.parseInt(appVersionCurrent[i])) {
continue ;
} else {
isNew = false;
return isNew;
}
}
return isNew;
}
//
// 截取应用包名称版本号信息
// 如 AppUtils_7.0.4-beta1_0120.apk 版本号为 7.0.4
// 如 AppUtils_7.0.4.apk 版本号为 7.0.4
//
public static String getCodeInPackageName(String apkName) {
//String apkName = "AppUtils_7.0.0.apk";
Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+");
Matcher matcher = pattern.matcher(apkName);
if (matcher.find()) {
String version = matcher.group();
return version;
//System.out.println("Version number: " + version); // 输出7.0.0
}
return "";
}
//
// 根据Beta版名称生成发布版应用包名称
// 如 AppUtils_7.0.4-beta1_0120.apk
// 发布版名称就为AppUtils_7.0.4.apk
//
public static String getReleasePackageName(String szBetaPackageName) {
//String szBetaPackageName = "AppUtils_7.0.4-beta1_0120.apk";
Pattern pattern = Pattern.compile(".*\\d+\\.\\d+\\.\\d+");
Matcher matcher = pattern.matcher(szBetaPackageName);
if (matcher.find()) {
String szReleasePackageName = matcher.group();
return szReleasePackageName + ".apk";
//System.out.println("Version number: " + version); // 输出7.0.0
}
return "";
}
}

View File

@@ -0,0 +1,215 @@
package cc.winboll.studio.libapputils.app;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/08/12 13:22:12
* @Describe 异常处理类
*/
import android.app.Activity;
import android.app.Application;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import android.widget.TextView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public final class CrashHandler {
public static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler();
public static void init(Application app) {
init(app, null);
}
public static void init(final Application app, final String crashDir) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
try {
tryUncaughtException(thread, throwable);
} catch (Throwable e) {
e.printStackTrace();
if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null)
DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(thread, throwable);
}
}
private void tryUncaughtException(Thread thread, Throwable throwable) {
final String time = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss", Locale.getDefault()).format(new Date());
File crashFile = new File(TextUtils.isEmpty(crashDir) ? new File(app.getExternalFilesDir(null), "crash")
: new File(crashDir), "crash_" + time + ".txt");
String versionName = "unknown";
long versionCode = 0;
try {
PackageInfo packageInfo = app.getPackageManager().getPackageInfo(app.getPackageName(), 0);
versionName = packageInfo.versionName;
versionCode = Build.VERSION.SDK_INT >= 28 ? packageInfo.getLongVersionCode()
: packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException ignored) {}
String fullStackTrace; {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwable.printStackTrace(pw);
fullStackTrace = sw.toString();
pw.close();
}
StringBuilder sb = new StringBuilder();
sb.append("************* Crash Head ****************\n");
sb.append("Time Of Crash : ").append(time).append("\n");
sb.append("Device Manufacturer: ").append(Build.MANUFACTURER).append("\n");
sb.append("Device Model : ").append(Build.MODEL).append("\n");
sb.append("Android Version : ").append(Build.VERSION.RELEASE).append("\n");
sb.append("Android SDK : ").append(Build.VERSION.SDK_INT).append("\n");
sb.append("App VersionName : ").append(versionName).append("\n");
sb.append("App VersionCode : ").append(versionCode).append("\n");
sb.append("************* Crash Head ****************\n");
sb.append("\n").append(fullStackTrace);
String errorLog = sb.toString();
try {
writeFile(crashFile, errorLog);
} catch (IOException ignored) {}
gotoCrashActiviy: {
Intent intent = new Intent(app, CrashActiviy.class);
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK
);
intent.putExtra(CrashActiviy.EXTRA_CRASH_INFO, errorLog);
try {
app.startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null)
DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(thread, throwable);
}
}
}
private void writeFile(File file, String content) throws IOException {
File parentFile = file.getParentFile();
if (parentFile != null && !parentFile.exists()) {
parentFile.mkdirs();
}
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
fos.write(content.getBytes());
try {
fos.close();
} catch (IOException e) {}
}
});
}
public static final class CrashActiviy extends Activity implements MenuItem.OnMenuItemClickListener {
private static final String EXTRA_CRASH_INFO = "crashInfo";
private static final int MENUITEM_COPY = 0;
private static final int MENUITEM_RESTART = 1;
private String mLog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLog = getIntent().getStringExtra(EXTRA_CRASH_INFO);
setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
setContentView: {
ScrollView contentView = new ScrollView(this);
contentView.setFillViewport(true);
HorizontalScrollView hw = new HorizontalScrollView(this);
hw.setBackgroundColor(Color.GRAY);
TextView message = new TextView(this); {
int padding = dp2px(16);
message.setPadding(padding, padding, padding, padding);
message.setText(mLog);
message.setTextIsSelectable(true);
}
hw.addView(message);
contentView.addView(hw, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
setContentView(contentView);
}
}
@Override
public void onBackPressed() {
restart();
}
private void restart() {
PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(getPackageName());
if (intent != null) {
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK
);
startActivity(intent);
}
finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
private int dp2px(final float dpValue) {
final float scale = Resources.getSystem().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case MENUITEM_COPY:
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), mLog));
break;
case MENUITEM_RESTART:
restart();
break;
}
return false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, MENUITEM_COPY, 0, "Copy").setOnMenuItemClickListener(this)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(0, MENUITEM_RESTART, 0, "Restart").setOnMenuItemClickListener(this)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
return true;
}
}
}

View File

@@ -0,0 +1,101 @@
package cc.winboll.studio.libapputils.app;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/12/24 11:02:08
*/
import android.app.Activity;
import android.app.Application;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import cc.winboll.studio.libapputils.log.LogUtils;
import com.hjq.toast.ToastUtils;
import java.util.Set;
public class MyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
public static final String TAG = "MyActivityLifecycleCallbacks";
public String mInfo = "";
public MyActivityLifecycleCallbacks(WinBollApplication application) {
}
void createActivityeInfo(Activity activity) {
StringBuilder sb = new StringBuilder();
Intent receivedIntent = activity.getIntent();
sb.append("\nCallingActivity : \n");
if (activity.getCallingActivity() != null) {
sb.append(activity.getCallingActivity().getPackageName());
}
sb.append("\nReceived Intent Package : \n");
sb.append(receivedIntent.getPackage());
Bundle extras = receivedIntent.getExtras();
if (extras != null) {
for (String key : extras.keySet()) {
sb.append("\nIntentInfo");
sb.append("\n键: ");
sb.append(key);
sb.append(", 值: ");
sb.append(extras.get(key));
//Log.d("IntentInfo", "键: " + key + ", 值: " + extras.get(key));
}
}
mInfo = sb.toString();
//Log.d("IntentInfo", "发送Intent的应用包名: " + senderPackage);
}
public void showActivityeInfo() {
ToastUtils.show("ActivityeInfo : " + mInfo);
LogUtils.d(TAG, "ActivityeInfo : " + mInfo);
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
// 在这里可以做一些初始化相关的操作例如记录Activity的创建时间等
//System.out.println(activity.getLocalClassName() + " was created");
LogUtils.d(TAG, activity.getLocalClassName() + " was created");
createActivityeInfo(activity);
}
@Override
public void onActivityStarted(Activity activity) {
//System.out.println(activity.getLocalClassName() + " was started");
LogUtils.d(TAG, activity.getLocalClassName() + " was started");
//createActivityeInfo(activity);
}
@Override
public void onActivityResumed(Activity activity) {
//System.out.println(activity.getLocalClassName() + " was resumed");
LogUtils.d(TAG, activity.getLocalClassName() + " was resumed");
//createActivityeInfo(activity);
}
@Override
public void onActivityPaused(Activity activity) {
//System.out.println(activity.getLocalClassName() + " was paused");
LogUtils.d(TAG, activity.getLocalClassName() + " was paused");
}
@Override
public void onActivityStopped(Activity activity) {
//System.out.println(activity.getLocalClassName() + " was stopped");
LogUtils.d(TAG, activity.getLocalClassName() + " was stopped");
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
// 可以在这里添加保存状态的自定义逻辑
}
@Override
public void onActivityDestroyed(Activity activity) {
//System.out.println(activity.getLocalClassName() + " was destroyed");
LogUtils.d(TAG, activity.getLocalClassName() + " was destroyed");
}
}

View File

@@ -0,0 +1,479 @@
package cc.winboll.studio.libapputils.app;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/08/12 14:32:08
* @Describe WinBoll 活动窗口基础类
*/
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import cc.winboll.studio.libapputils.R;
import cc.winboll.studio.libapputils.activities.AboutActivity;
import cc.winboll.studio.libapputils.log.LogActivity;
import cc.winboll.studio.libapputils.log.LogUtils;
import cc.winboll.studio.libapputils.view.AboutView;
import com.hjq.toast.ToastUtils;
import java.util.List;
import java.util.Set;
abstract public class WinBollActivity extends AppCompatActivity {
public static final String TAG = "WinBollActivity";
public static final int REQUEST_LOG_ACTIVITY = 0;
Toolbar mToolBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
checkResolveActivity();
LogUtils.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
archiveInstance();
}
boolean checkResolveActivity() {
PackageManager packageManager = getPackageManager();
//Intent intent = new Intent("your_action_here");
Intent intent = getIntent();
if (intent != null) {
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfoList.size() > 0) {
// 传入的Intent action在Activity清单的intent-filter的action节点里有定义
if (intent.getAction() != null) {
if (intent.getAction().equals(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW)) {
WinBollApplication.setIsDebug(true);
//ToastUtils.show!("WinBollApplication.setIsDebug(true) by action : " + intent.getAction());
}
}
return true;
} else {
// 传入的Intent action在Activity清单的intent-filter的action节点里没有定义
//ToastUtils.show("false : " + intent.getAction());
return false;
}
/* ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
if (resolveInfo != null) {
// action在清单文件中有声明
} else {
}*/
}
// action在清单文件中没有声明
ToastUtils.show("false");
return false;
}
void archiveInstance() {
Intent intent = getIntent();
StringBuilder sb = new StringBuilder("\n### Archive Instance ###\n");
if (intent != null) {
ComponentName componentName = intent.getComponent();
if (componentName != null) {
String packageName = componentName.getPackageName();
//Log.d("AppStarter", "启动本应用的应用包名: " + packageName);
sb.append("启动本应用的应用包名: \n" + packageName);
}
sb.append("\nImplicit Intent Tracker \n接收到的 Intent 动作: \n" + intent.getAction());
Set<String> categories = intent.getCategories();
if (categories != null) {
for (String category : categories) {
sb.append("\n接收到的 Intent 类别 :\n" + category);
}
}
Uri data = intent.getData();
if (data != null) {
sb.append("\n接收到的 Intent 数据 :\n" + data.toString());
}
} else {
sb.append("Intent is null.");
}
sb.append("\n\n");
LogUtils.d(TAG, sb.toString());
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mToolBar = initToolBar();
setSupportActionBar(mToolBar);
if (isEnableDisplayHomeAsUp() && mToolBar != null) {
// 显示后退按钮
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
// 缓存当前 activity
LogUtils.d(TAG, "ActManager.getInstance().add(this);");
//ToastUtils.show("getTag() " + getTag());
WinBollActivityManager.getInstance(this).add(this);
//WinBollActivityManager.getInstance().printAvtivityListInfo();
//ToastUtils.show("WinBollUI_TYPE " + WinBollApplication.getWinBollUI_TYPE());
//boolean isDebuging = WinBollApplication.loadDebugStatusIsDebuging();
//ToastUtils.show(String.valueOf(isDebuging));
//WinBollApplication.setIsDebug(true);
setSubTitle(getTag());
}
@Override
public void recreate() {
super.recreate();
}
@Override
protected void onDestroy() {
WinBollActivityManager.getInstance(this).registeRemove(this);
super.onDestroy();
}
@Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
}
@Override
public <T extends View> T findViewById(int id) {
return super.findViewById(id);
}
@Override
public MenuInflater getMenuInflater() {
return super.getMenuInflater();
}
public WinBollActivity getActivity() {
return this;
}
@Override
public Context getApplicationContext() {
return super.getApplicationContext();
}
public <T extends FragmentManager> T getWinBollActivitySupportFragmentManager() {
return (T)super.getSupportFragmentManager();
}
@Override
public ActionBar getSupportActionBar() {
return super.getSupportActionBar();
}
@Override
public void setSupportActionBar(Toolbar toolbar) {
super.setSupportActionBar(toolbar);
}
@Override
public void setActionBar(android.widget.Toolbar toolbar) {
super.setActionBar(toolbar);
}
public void setSubTitle(CharSequence title) {
LogUtils.d(TAG, "setSubTitle");
if (super.getSupportActionBar() != null) {
super.getSupportActionBar().setSubtitle(title);
LogUtils.d(TAG, String.format("setSubtitle title : %s", title));
}
}
public CharSequence getSubTitle() {
if (super.getSupportActionBar() != null) {
return super.getSupportActionBar().getSubtitle();
}
return "";
}
@Override
public void setTitle(CharSequence title) {
//super.setTitle(title);
if (super.getSupportActionBar() != null) {
super.getSupportActionBar().setTitle(title);
LogUtils.d(TAG, String.format("setSubtitle title : %s", title));
}
}
@Override
public void setTitle(int titleId) {
//super.setTitle(titleId);
if (super.getSupportActionBar() != null) {
super.getSupportActionBar().setTitle(titleId);
//LogUtils.d(TAG, String.format("setSubtitle title : %s", title));
}
}
@Override
public void setTheme(Resources.Theme theme) {
super.setTheme(theme);
}
@Override
public void setTheme(int resid) {
super.setTheme(resid);
}
@Override
public void setTitleColor(int textColor) {
super.setTitleColor(textColor);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
super.setContentView(view, params);
}
@Override
public void setContentView(View view) {
super.setContentView(view);
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return super.getSharedPreferences(name, mode);
}
@Override
public boolean releaseInstance() {
return super.releaseInstance();
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
return super.registerReceiver(receiver, filter, flags);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) {
return super.registerReceiver(receiver, filter, broadcastPermission, scheduler);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
return super.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags);
}
@Override
public void startActivities(Intent[] intents) {
super.startActivities(intents);
}
@Override
public void startActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {
super.startActivityFromFragment(fragment, intent, requestCode);
}
@Override
public void startActivityFromFragment(android.app.Fragment fragment, Intent intent, int requestCode, Bundle options) {
super.startActivityFromFragment(fragment, intent, requestCode, options);
}
@Override
public void startActivityFromChild(Activity child, Intent intent, int requestCode, Bundle options) {
super.startActivityFromChild(child, intent, requestCode, options);
}
@Override
public void startActivities(Intent[] intents, Bundle options) {
super.startActivities(intents, options);
}
@Override
public boolean startActivityIfNeeded(Intent intent, int requestCode) {
return super.startActivityIfNeeded(intent, requestCode);
}
@Override
public boolean startActivityIfNeeded(Intent intent, int requestCode, Bundle options) {
return super.startActivityIfNeeded(intent, requestCode, options);
}
@Override
public void startActivityFromChild(Activity child, Intent intent, int requestCode) {
super.startActivityFromChild(child, intent, requestCode);
}
@Override
public ComponentName startService(Intent service) {
return super.startService(service);
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
}
@Override
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
super.startActivityForResult(intent, requestCode, options);
}
@Override
public void startActivityFromFragment(android.app.Fragment fragment, Intent intent, int requestCode) {
super.startActivityFromFragment(fragment, intent, requestCode);
}
@Override
public void startActivityFromFragment(Fragment requestIndex, Intent fragment, int intent, Bundle requestCode) {
super.startActivityFromFragment(requestIndex, fragment, intent, requestCode);
}
@Override
public void startActivity(Intent intent, Bundle options) {
super.startActivity(intent, options);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (isAddWinBollToolBar()) {
getMenuInflater().inflate(R.menu.toolbar_winboll_shared_main, menu);
}
if (WinBollApplication.isDebug()) {
getMenuInflater().inflate(R.menu.toolbar_studio_debug, menu);
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
LogUtils.d(TAG, "onOptionsItemSelected");
if (item.getItemId() == R.id.item_log) {
LogUtils.d(TAG, "item_log not yet.");
//WinBollActivityManager.getInstance().printAvtivityListInfo();
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
} else if (item.getItemId() == R.id.item_exit) {
WinBollActivityManager.getInstance(this).finishAll();
} else if (item.getItemId() == R.id.item_info) {
WinBollApplication application = (WinBollApplication) getApplication();
application.getMyActivityLifecycleCallbacks().showActivityeInfo();
} else if (item.getItemId() == R.id.item_exitdebug) {
AboutView.setApp2NormalMode(getApplicationContext());
} else if (item.getItemId() == R.id.item_about) {
startAboutActivity();
} else if (item.getItemId() == android.R.id.home) {
WinBollActivityManager.getInstance(this).finish(this);
}
// else if (item.getItemId() == android.R.id.home) {
// 回到主窗口速度缓慢,方法备用。现在用 WinBollActivityManager resumeActivity 和 finish 方法管理。
// _mMainWinBollActivity 是 WinBollActivity 的静态属性
// onCreate 函数下 _mMainWinBollActivity 为空时就用 _mMainWinBollActivity = this 赋值。
//startWinBollActivity(new Intent(_mMainWinBollActivity, _mMainWinBollActivity.getClass()), _mMainWinBollActivity.getTag(), _mMainWinBollActivity);
//}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
//super.onBackPressed();
//ToastUtils.show("onBackPressed");
WinBollActivityManager.getInstance(this).finish(this);
}
/*public void getInstanse() {
startWinBollActivity(new Intent(), getTag(), null);
}*/
//
// activity: 为 null 时,
// intent.putExtra 函数 "tag" 参数为 tag
// activity: 不为 null 时,
// intent.putExtra 函数 "tag" 参数为 activity.getTag()
//
// protected <T extends WinBollActivity> void startWinBollActivity(Intent intent, String tag, T activity) {
// LogUtils.d(TAG, "startWinBollActivityForResult tag " + tag);
// //ToastUtils.show("startWinBollActivityForResult tag " + tag);
// //打开多任务窗口 flags
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
// intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
// if (activity != null) {
// intent.putExtra("tag", activity.getTag());
// } else {
// intent.putExtra("tag", tag);
// }
// //ToastUtils.show("super.startActivityForResult(intent, requestCode); tag " + tag);
// LogUtils.d(TAG, "startActivityForResult(intent, requestCode);" + tag);
// startActivity(intent);
// }
//
// activity: 为 null 时,
// intent.putExtra 函数 "tag" 参数为 tag
// activity: 不为 null 时,
// intent.putExtra 函数 "tag" 参数为 activity.getTag()
//
protected <T extends AboutActivity> void startAboutActivity() {
Intent intent = new Intent(this, AboutActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.putExtra("tag", AboutActivity.TAG);
startActivity(intent);
}
@Override
public void startActivity(Intent intent) {
//绑定唯一标识 tag存在 则根据 taskId 移动到前台
String tag = intent.getStringExtra("tag");
//ToastUtils.show("startActivityForResult tag " + tag);
//WinBollActivityManager.getInstance(this).printAvtivityListInfo();
if (WinBollActivityManager.getInstance(this).isActive(tag)) {
//ToastUtils.show("resumeActivity");
LogUtils.d(TAG, "resumeActivity");
WinBollActivityManager.getInstance(this).resumeActivity(this, tag);
} else {
//ToastUtils.show("super.startActivity(intent);");
super.startActivity(intent);
}
}
@Override
protected void onActivityResult(int requestCode, int targetFragment, Intent data) {
LogUtils.d(TAG, "onActivityResult");
switch (requestCode) {
case REQUEST_LOG_ACTIVITY : {
LogUtils.d(TAG, "REQUEST_LOG_ACTIVITY");
break;
}
default : {
super.onActivityResult(requestCode, targetFragment, data);
}
}
}
public boolean isAddWinBollInfoMenu() {
return true;
}
abstract public String getTag();
abstract protected Toolbar initToolBar();
abstract protected boolean isEnableDisplayHomeAsUp();
abstract protected boolean isAddWinBollToolBar();
}

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