Compare commits

...

52 Commits

Author SHA1 Message Date
ZhanGSKen
c9980db1d5 <apputils>APK 15.0.12 release Publish. 2025-03-24 14:42:07 +08:00
ZhanGSKen
ec08e89418 精简数据模型 2025-03-24 14:41:21 +08:00
ZhanGSKen
7391091480 <libapputils>Library Release 15.0.11 2025-03-24 09:46:41 +08:00
ZhanGSKen
133964aaf1 <apputils>APK 15.0.11 release Publish. 2025-03-24 09:46:26 +08:00
ZhanGSKen
a96696f261 整体UI优化 2025-03-24 09:44:18 +08:00
ZhanGSKen
f96fcbfe13 添加二维码测试窗口调用 2025-03-24 08:52:50 +08:00
ZhanGSKen
ad6e1bd51b 添加应用自带Html资源窗口测试 2025-03-24 08:47:04 +08:00
ZhanGSKen
0fa55b0291 添加日日志窗口测试 2025-03-24 08:43:35 +08:00
ZhanGSKen
32082c4dd0 移除冗余模块,其模块已转移至AES。 2025-03-24 08:41:06 +08:00
ZhanGSKen
3be42fbd59 <libapputils>Library Release 15.0.10 2025-03-24 08:10:15 +08:00
ZhanGSKen
85f8466450 <apputils>APK 15.0.10 release Publish. 2025-03-24 08:10:00 +08:00
ZhanGSKen
407f2b38ae <libapputils>Library Release 15.0.9 2025-03-24 08:09:51 +08:00
ZhanGSKen
550410d913 <apputils>APK 15.0.9 release Publish. 2025-03-24 08:09:02 +08:00
ZhanGSKen
6daa3bbd0f <apputils>APK 15.0.8 release Publish. 2025-03-24 08:08:19 +08:00
ZhanGSKen
8a29735130 更新编译工具版本 2025-03-24 08:06:52 +08:00
ZhanGSKen
272dd15427 Merge remote-tracking branch 'origin/appbase' into apputils 2025-03-24 08:05:24 +08:00
ZhanGSKen
5411d5e590 <libappbase>Library Release 15.0.8 2025-03-24 08:04:42 +08:00
ZhanGSKen
facf0b001d <appbase>APK 15.0.8 release Publish. 2025-03-24 08:04:27 +08:00
ZhanGSKen
df58c0355c 更新编译工具版本 2025-03-24 08:03:17 +08:00
ZhanGSKen
7c7b159a80 更新编译工具版本 2025-03-24 07:57:04 +08:00
ZhanGSKen
da23546bb4 Merge branch 'appbase' into apputils 2025-03-24 07:48:04 +08:00
ZhanGSKen
e657e45218 <libappbase>Library Release 15.0.7 2025-03-24 07:45:34 +08:00
ZhanGSKen
c22946f0a5 <appbase>APK 15.0.7 release Publish. 2025-03-24 07:44:12 +08:00
ZhanGSKen
1363a7dcce <appbase>APK 15.0.6 release Publish. 2025-03-24 07:43:28 +08:00
ZhanGSKen
e0ca5725f1 保持与旧版Gradle插件的兼容 2025-03-24 07:39:20 +08:00
ZhanGSKen
3c4988532f 函数命名更新 2025-03-24 07:30:59 +08:00
ZhanGSKen
b0a34579fa 命名空间重构 2025-03-24 07:17:22 +08:00
ZhanGSKen
fe12cf7ffe 添加BB工具集示例源码 2025-03-23 17:12:03 +08:00
ZhanGSKen
3192ae55b1 设置 Gradle 类库引用方式为 API 传递依赖。 2025-03-23 13:26:28 +08:00
ZhanGSKen
67d91aaf6c Merge branch 'appbase' into apputils 2025-03-21 01:15:54 +08:00
ZhanGSKen
dd08747edb 更新WinBoll maven库下载顺序 2025-03-21 00:42:41 +08:00
ZhanGSKen
e91bf7d422 <libapputils>Library Release 15.0.7 2025-03-20 01:24:10 +08:00
ZhanGSKen
a73b5a9199 <apputils>APK 15.0.7 release Publish. 2025-03-20 01:23:48 +08:00
ZhanGSKen
fe943fef85 更新类库,窗口管理模块置闲。 2025-03-20 01:22:05 +08:00
ZhanGSKen
dc1b138dd7 20250319_0130 2025-03-19 01:30:40 +08:00
ZhanGSKen
e867433f9c <libapputils>Library Release 15.0.6 2025-03-18 12:18:37 +08:00
ZhanGSKen
33eb58f33c <apputils>APK 15.0.6 release Publish. 2025-03-18 12:18:23 +08:00
ZhanGSKen
915c440cdd 主题配置方案尝试 2025-03-18 12:13:42 +08:00
ZhanGSKen
d21c92683d <libapputils>Library Release 15.0.5 2025-03-18 10:56:21 +08:00
ZhanGSKen
fe7ba6d38d <apputils>APK 15.0.5 release Publish. 2025-03-18 10:56:08 +08:00
ZhanGSKen
b3548bf1df 类库主题属性继承名称尝试 2025-03-18 10:55:13 +08:00
ZhanGSKen
d4b8b3bb35 <libapputils>Library Release 15.0.4 2025-03-18 10:46:52 +08:00
ZhanGSKen
603640b3cb <libappbase>Library Release 15.0.5 2025-03-18 10:15:14 +08:00
ZhanGSKen
5b06ce9699 <appbase>APK 15.0.5 release Publish. 2025-03-18 10:14:53 +08:00
ZhanGSKen
363fc6c7c1 修复编译参数 2025-03-18 10:13:01 +08:00
ZhanGSKen
7f43f8b5c5 <libappbase>Library Release 15.0.4 2025-03-18 10:09:49 +08:00
ZhanGSKen
a117e6e110 <appbase>APK 15.0.4 release Publish. 2025-03-18 10:09:21 +08:00
ZhanGSKen
c1f576e343 分开APP应用主题设置与类库主题预定设置。 2025-03-18 10:08:31 +08:00
ZhanGSKen
1dad84b65e <libappbase>Library Release 15.0.3 2025-03-17 09:51:28 +08:00
ZhanGSKen
1ae377e665 <appbase>APK 15.0.3 release Publish. 2025-03-17 09:51:04 +08:00
ZhanGSKen
02fa0a4134 优化调试窗口 2025-03-17 09:40:03 +08:00
ZhanGSKen
a730aa3f92 优化日志UI 2025-03-17 09:37:12 +08:00
65 changed files with 567 additions and 1219 deletions

View File

@@ -18,8 +18,8 @@ def genVersionName(def versionName){
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 32
buildToolsVersion "32.0.0"
defaultConfig {
applicationId "cc.winboll.studio.appbase"

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sat Mar 15 15:30:02 HKT 2025
stageCount=3
#Mon Mar 24 08:04:35 HKT 2025
stageCount=9
libraryProject=libappbase
baseVersion=15.0
publishVersion=15.0.2
publishVersion=15.0.8
buildCount=0
baseBetaVersion=15.0.3
baseBetaVersion=15.0.9

View File

@@ -7,7 +7,7 @@
android:name=".App"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/MyAppTheme"
android:theme="@style/MyAPPBaseTheme"
android:resizeableActivity="true">
<activity
@@ -49,6 +49,12 @@
android:name=".services.MainService"
android:exported="true"/>
<service android:name="cc.winboll.studio.appbase.services.TestDemoBindService"
android:exported="true"/>
<service android:name="cc.winboll.studio.appbase.services.TestDemoService"
android:exported="true"/>
<service android:name=".services.AssistantService"/>
<receiver android:name="cc.winboll.studio.appbase.receivers.MainReceiver">
@@ -81,13 +87,13 @@
</receiver>
<receiver android:name=".widgets.APPNewsWidgetClickListener">
<receiver android:name=".receivers.APPNewsWidgetClickListener">
<intent-filter>
<action android:name="cc.winboll.studio.appbase.widgets.APPNewsWidgetClickListener.ACTION_PRE"/>
<action android:name="cc.winboll.studio.appbase.receivers.APPNewsWidgetClickListener.ACTION_PRE"/>
<action android:name="cc.winboll.studio.appbase.widgets.APPNewsWidgetClickListener.ACTION_NEXT"/>
<action android:name="cc.winboll.studio.appbase.receivers.APPNewsWidgetClickListener.ACTION_NEXT"/>
</intent-filter>
@@ -97,12 +103,6 @@
android:name="android.max_aspect"
android:value="4.0"/>
<service android:name="cc.winboll.studio.appbase.services.TestDemoBindService"
android:exported="true"/>
<service android:name="cc.winboll.studio.appbase.services.TestDemoService"
android:exported="true"/>
</application>
</manifest>

View File

@@ -89,7 +89,7 @@ public class MainActivity extends Activity {
startService(intentService);
}
public void onTestSOS(View view) {
public void onTestDemoServiceSOS(View view) {
Intent intent = new Intent(this, TestDemoService.class);
stopService(intent);
if (App.isDebuging()) {

View File

@@ -7,7 +7,7 @@ package cc.winboll.studio.appbase;
import android.content.Context;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import cc.winboll.studio.appbase.beans.MainServiceBean;
import cc.winboll.studio.appbase.models.MainServiceBean;
import cc.winboll.studio.appbase.services.MainService;
public class MyTileService extends TileService {

View File

@@ -1,4 +1,4 @@
package cc.winboll.studio.appbase.beans;
package cc.winboll.studio.appbase.models;
/**
* @Author ZhanGSKen@AliYun.Com

View File

@@ -1,4 +1,4 @@
package cc.winboll.studio.appbase.beans;
package cc.winboll.studio.appbase.models;
/**
* @Author ZhanGSKen@AliYun.Com

View File

@@ -1,4 +1,4 @@
package cc.winboll.studio.appbase.beans;
package cc.winboll.studio.appbase.models;
/**
* @Author ZhanGSKen@AliYun.Com

View File

@@ -1,4 +1,4 @@
package cc.winboll.studio.appbase.beans;
package cc.winboll.studio.appbase.models;
/**
* @Author ZhanGSKen@AliYun.Com

View File

@@ -1,13 +1,13 @@
package cc.winboll.studio.appbase.widgets;
package cc.winboll.studio.appbase.receivers;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/15 17:20:46
* @Describe WidgetButtonClickListener
* @Date 2025/03/24 07:11:44
*/
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import cc.winboll.studio.appbase.widgets.APPNewsWidget;
import cc.winboll.studio.libappbase.LogUtils;
public class APPNewsWidgetClickListener extends BroadcastReceiver {

View File

@@ -10,7 +10,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import cc.winboll.studio.appbase.beans.WinBollNewsBean;
import cc.winboll.studio.appbase.models.WinBollNewsBean;
import cc.winboll.studio.appbase.services.MainService;
import cc.winboll.studio.appbase.widgets.APPNewsWidget;
import cc.winboll.studio.libappbase.AppUtils;

View File

@@ -11,7 +11,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import cc.winboll.studio.appbase.beans.MainServiceBean;
import cc.winboll.studio.appbase.models.MainServiceBean;
import cc.winboll.studio.appbase.services.AssistantService;
import cc.winboll.studio.appbase.services.MainService;
import cc.winboll.studio.libappbase.LogUtils;

View File

@@ -18,7 +18,7 @@ import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import cc.winboll.studio.appbase.MyTileService;
import cc.winboll.studio.appbase.beans.MainServiceBean;
import cc.winboll.studio.appbase.models.MainServiceBean;
import cc.winboll.studio.appbase.handlers.MainServiceHandler;
import cc.winboll.studio.appbase.receivers.MainReceiver;
import cc.winboll.studio.appbase.services.AssistantService;

View File

@@ -10,7 +10,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import cc.winboll.studio.appbase.beans.TestDemoBindServiceBean;
import cc.winboll.studio.appbase.models.TestDemoBindServiceBean;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.WinBoll;
import cc.winboll.studio.appbase.App;

View File

@@ -10,7 +10,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import cc.winboll.studio.appbase.beans.TestDemoServiceBean;
import cc.winboll.studio.appbase.models.TestDemoServiceBean;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.WinBoll;

View File

@@ -12,15 +12,16 @@ import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import cc.winboll.studio.appbase.R;
import cc.winboll.studio.appbase.beans.WinBollNewsBean;
import cc.winboll.studio.appbase.models.WinBollNewsBean;
import cc.winboll.studio.appbase.receivers.APPNewsWidgetClickListener;
import cc.winboll.studio.libappbase.AppUtils;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.sos.APPModel;
import cc.winboll.studio.libappbase.sos.WinBoll;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import cc.winboll.studio.libappbase.sos.APPModel;
import cc.winboll.studio.libappbase.sos.WinBoll;
public class APPNewsWidget extends AppWidgetProvider {

View File

@@ -72,6 +72,26 @@
android:layout_height="wrap_content"
android:gravity="right">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartCenter"
android:textAllCaps="false"
android:onClick="onStartCenter"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopCenter"
android:textAllCaps="false"
android:onClick="onStopCenter"/>
</LinearLayout>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -105,54 +125,41 @@
</LinearLayout>
</HorizontalScrollView>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SartTestDemoBindService"
android:textAllCaps="false"
android:onClick="onSartTestDemoBindService"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopTestDemoBindService"
android:textAllCaps="false"
android:onClick="onStopTestDemoBindService"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SartTestDemoBindService"
android:textAllCaps="false"
android:onClick="onSartTestDemoBindService"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopTestDemoBindServiceNoSettings"
android:textAllCaps="false"
android:onClick="onStopTestDemoBindServiceNoSettings"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopTestDemoBindService"
android:textAllCaps="false"
android:onClick="onStopTestDemoBindService"/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopTestDemoBindServiceNoSettings"
android:textAllCaps="false"
android:onClick="onStopTestDemoBindServiceNoSettings"/>
</LinearLayout>
</HorizontalScrollView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartCenter"
android:textAllCaps="false"
android:onClick="onStartCenter"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopCenter"
android:textAllCaps="false"
android:onClick="onStopCenter"/>
<Button
android:layout_width="wrap_content"
@@ -171,24 +178,24 @@
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestSOS"
android:text="TestDemoServiceSOS"
android:textAllCaps="false"
android:onClick="onTestSOS"/>
android:onClick="onTestDemoServiceSOS"/>
</LinearLayout>
</ScrollView>
<cc.winboll.studio.libappbase.LogView
android:layout_height="500dp"
android:layout_width="match_parent"
android:id="@+id/activitymainLogView1"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<cc.winboll.studio.libappbase.LogView
android:layout_height="300dp"
android:layout_width="match_parent"
android:id="@+id/activitymainLogView1"/>
</LinearLayout>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#005800FF</color>
<color name="colorPrimaryDark">#005800FF</color>
<color name="colorAccent">#005800FF</color>
<color name="colorPrimary">#FF00B322</color>
<color name="colorPrimaryDark">#FF005C12</color>
<color name="colorAccent">#FF8DFFA2</color>
<color name="colorText">#FFFFFB8D</color>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyAppTheme" parent="APPBaseTheme">
<style name="MyAPPBaseTheme" parent="APPBaseTheme">
<item name="attrColorPrimary">@color/colorPrimary</item>
<item name="themeGlobalCrashActivity">@style/MyGlobalCrashActivityTheme</item>
</style>

View File

@@ -18,8 +18,8 @@ def genVersionName(def versionName){
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 32
buildToolsVersion "32.0.0"
defaultConfig {
applicationId "cc.winboll.studio.apputils"
@@ -46,21 +46,4 @@ android {
dependencies {
api project(':libapputils')
api fileTree(dir: 'libs', include: ['*.jar'])
implementation 'cc.winboll.studio:libappbase:15.0.5'
// 二维码类库
implementation 'com.google.zxing:core:3.4.1'
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
// 网络连接类库
//implementation 'com.squareup.okhttp3:okhttp:4.4.1'
// Html 解析
//implementation 'org.jsoup:jsoup:1.13.1'
// SSH
//implementation 'com.jcraft:jsch:0.1.55'
// 应用介绍页类库
//implementation 'io.github.medyo:android-about-page:2.0.0'
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Tue Mar 18 10:46:39 HKT 2025
stageCount=5
#Mon Mar 24 14:42:07 HKT 2025
stageCount=13
libraryProject=libapputils
baseVersion=15.0
publishVersion=15.0.4
publishVersion=15.0.12
buildCount=0
baseBetaVersion=15.0.5
baseBetaVersion=15.0.13

View File

@@ -27,7 +27,9 @@
</activity>
<activity android:name=".TestStringToQrCodeViewActivity"/>
<activity android:name=".TestStringToQRCodeViewActivity"/>
<activity android:name=".TestBBMorseCodeActivity"/>
</application>

View File

@@ -10,8 +10,6 @@ import android.content.Context;
import android.widget.Toast;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libapputils.app.MyActivityLifecycleCallbacks;
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
import cc.winboll.studio.libapputils.bean.DebugBean;
public class App extends GlobalApplication {
@@ -21,7 +19,7 @@ public class App extends GlobalApplication {
public static final String _ACTION_DEBUGVIEW = App.class.getName() + "_ACTION_DEBUGVIEW";
//static volatile WinBollApplication _WinBollApplication = null;
MyActivityLifecycleCallbacks mMyActivityLifecycleCallbacks;
//MyActivityLifecycleCallbacks mMyActivityLifecycleCallbacks;
// 标记当前应用是否处于调试状态
static volatile boolean isDebug = false;
@@ -34,9 +32,9 @@ public class App extends GlobalApplication {
return isDebug;
}
MyActivityLifecycleCallbacks getMyActivityLifecycleCallbacks() {
return mMyActivityLifecycleCallbacks;
}
// MyActivityLifecycleCallbacks getMyActivityLifecycleCallbacks() {
// return mMyActivityLifecycleCallbacks;
// }
@Override
public Context getApplicationContext() {
@@ -74,10 +72,10 @@ public class App extends GlobalApplication {
}
// 应用窗口管理模块参数设置
//
mMyActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks();
registerActivityLifecycleCallbacks(mMyActivityLifecycleCallbacks);
//mMyActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks();
//registerActivityLifecycleCallbacks(mMyActivityLifecycleCallbacks);
// 设置默认 WinBoll 应用 UI 类型
WinBollActivityManager.getInstance(this).setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Service);
//WinBollActivityManager.getInstance(this).setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Service);
//ToastUtils.show("WinBollUI_TYPE " + getWinBollUI_TYPE());
} catch (Exception e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());

View File

@@ -20,15 +20,13 @@ import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity;
import cc.winboll.studio.libapputils.activities.LogActivity;
import cc.winboll.studio.libapputils.activities.QRCodeDecodeActivity;
import cc.winboll.studio.libapputils.app.AboutActivityFactory;
import cc.winboll.studio.libapputils.app.IWinBollActivity;
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
import cc.winboll.studio.libapputils.bean.APPInfo;
import cc.winboll.studio.libapputils.view.AboutView;
import cc.winboll.studio.libapputils.view.YesNoAlertDialog;
import java.util.List;
import java.util.Set;
final public class MainActivity extends Activity implements IWinBollActivity {
final public class MainActivity extends Activity {
public static final String TAG = "MainActivity";
@@ -36,50 +34,30 @@ final public class MainActivity extends Activity implements IWinBollActivity {
Toolbar mToolbar;
LogView mLogView;
//
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
public Activity getActivity() {
return this;
}
@Override
public APPInfo getAppInfo() {
String szBranchName = "apputils";
APPInfo appInfo = AboutActivityFactory.buildDefaultAPPInfo();
appInfo.setAppName("APPUtils");
appInfo.setAppIcon(cc.winboll.studio.libapputils.R.drawable.ic_winboll);
appInfo.setAppDescription("APPUtils Description");
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("APPUtils");
appInfo.setAppAPKFolderName("APPUtils");
return appInfo;
//return null;
}
@Override
public String getTag() {
return TAG;
}
@Override
public boolean isAddWinBollToolBar() {
return true;
}
@Override
public Toolbar initToolBar() {
return findViewById(R.id.activitymainToolbar1);
}
@Override
public boolean isEnableDisplayHomeAsUp() {
return false;
}
// @Override
// public APPInfo getAppInfo() {
// String szBranchName = "apputils";
//
// APPInfo appInfo = AboutActivityFactory.buildDefaultAPPInfo();
// appInfo.setAppName("APPUtils");
// appInfo.setAppIcon(cc.winboll.studio.libapputils.R.drawable.ic_winboll);
// appInfo.setAppDescription("APPUtils Description");
// 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("APPUtils");
// appInfo.setAppAPKFolderName("APPUtils");
// return appInfo;
// //return null;
// }
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -90,13 +68,13 @@ final public class MainActivity extends Activity implements IWinBollActivity {
mLogView.start();
// 初始化工具栏
mToolbar = findViewById(R.id.activitymainToolbar1);
mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar);
if (isEnableDisplayHomeAsUp()) {
// 显示后退按钮
getActionBar().setDisplayHomeAsUpEnabled(true);
}
getActionBar().setSubtitle(getTag());
// if (isEnableDisplayHomeAsUp()) {
// // 显示后退按钮
// getActionBar().setDisplayHomeAsUpEnabled(true);
// }
// getActionBar().setSubtitle(getTag());
checkResolveActivity();
archiveInstance();
@@ -177,12 +155,12 @@ final public class MainActivity extends Activity implements IWinBollActivity {
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// 缓存当前 activity
WinBollActivityManager.getInstance(this).add(this);
//WinBollActivityManager.getInstance(this).add(this);
}
@Override
public void onDestroy() {
WinBollActivityManager.getInstance(this).registeRemove(this);
//WinBollActivityManager.getInstance(this).registeRemove(this);
super.onDestroy();
}
@@ -191,14 +169,14 @@ final public class MainActivity extends Activity implements IWinBollActivity {
Toast.makeText(getApplication(), "onTestLogClick", Toast.LENGTH_SHORT).show();
}
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);
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);
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
}
//
@@ -248,10 +226,10 @@ final public class MainActivity extends Activity implements IWinBollActivity {
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 (isAddWinBollToolBar()) {
// //ToastUtils.show("mIWinBoll.isAddWinBollToolBar()");
// getMenuInflater().inflate(R.menu.toolbar_winboll_shared_main, menu);
// }
if (App.isDebug()) {
getMenuInflater().inflate(R.menu.toolbar_studio_debug, menu);
}
@@ -264,11 +242,13 @@ final public class MainActivity extends Activity implements IWinBollActivity {
if (item.getItemId() == R.id.item_exit) {
exit();
return true;
} else if (item.getItemId() == R.id.item_about) {
AboutActivityFactory.showAboutActivity(this, getAppInfo());
return true;
// } else if (item.getItemId() == R.id.item_about) {
// AboutActivityFactory.showAboutActivity(this, getAppInfo());
// return true;
} else if (item.getItemId() == R.id.item_teststringtoqrcodeview) {
WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestStringToQrCodeViewActivity.class);
Intent intent = new Intent(this, TestStringToQRCodeViewActivity.class);
startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY);
//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);
@@ -278,13 +258,13 @@ final public class MainActivity extends Activity implements IWinBollActivity {
}
return true;
} else if (item.getItemId() == R.id.item_log) {
WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
//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);
//WinBollActivityManager.getInstance(this).finish(this);
return true;
}
return super.onOptionsItemSelected(item);
@@ -301,7 +281,7 @@ final public class MainActivity extends Activity implements IWinBollActivity {
@Override
public void onYes() {
WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
//WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
}
@Override
@@ -314,22 +294,25 @@ final public class MainActivity extends Activity implements IWinBollActivity {
@Override
public void onBackPressed() {
if (WinBollActivityManager.getInstance(getApplicationContext()).isFirstIWinBollActivity(this)) {
exit();
} else {
WinBollActivityManager.getInstance(this).finish(this);
super.onBackPressed();
}
// if (WinBollActivityManager.getInstance(getApplicationContext()).isFirstIWinBollActivity(this)) {
// exit();
// } else {
// WinBollActivityManager.getInstance(this).finish(this);
// super.onBackPressed();
// }
}
public void onTestAboutActivity(View view) {
about();
}
public void onTestJavascriptHtmlActivity(View view) {
public void onTestAssetsHtmlActivity(View view) {
Intent intent = new Intent(this, AssetsHtmlActivity.class);
intent.putExtra(AssetsHtmlActivity.EXTRA_HTMLFILENAME, "javascript_test.html");
WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AssetsHtmlActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AssetsHtmlActivity.class);
}
@Override

View File

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

View File

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

View File

@@ -8,7 +8,7 @@
<android.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activitymainToolbar1"/>
android:id="@+id/toolbar"/>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -33,9 +33,9 @@
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LogUtils"
android:text="TestLogActivity"
android:textAllCaps="false"
android:onClick="onLogUtilsClick"/>
android:onClick="onTestLogActivity"/>
</LinearLayout>
@@ -49,8 +49,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Test Javascript Html Activity"
android:onClick="onTestJavascriptHtmlActivity"/>
android:text="TestAssetsHtmlActivity"
android:onClick="onTestAssetsHtmlActivity"/>
</LinearLayout>

View File

@@ -0,0 +1,9 @@
<?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

@@ -9,7 +9,7 @@
<android.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activityteststringtoqrcodeviewToolbar1"/>
android:id="@+id/toolbar"/>
<LinearLayout
android:orientation="vertical"

View File

@@ -1,12 +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_testwinboll"
android:title="TestWinBollActivity"/>
<item
android:id="@+id/item_teststringtoqrcodeview"
android:title="TestStringToQrCodeViewActivity"/>
android:title="TestStringToQRCodeViewActivity"/>
<item
android:id="@+id/item_testqrcodedecodeactivity"
android:title="TestQRCodeDecodeActivity"/>

View File

@@ -1,7 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyUtilsTheme" parent="APPBaseTheme">
<style name="MyUtilsTheme" parent="UtilsTheme">
<item name="attrColorPrimary">@color/colorPrimary</item>
<item name="themeGlobalCrashActivity">@style/GlobalCrashActivityTheme</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

@@ -1,6 +1,12 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
@@ -9,13 +15,6 @@ buildscript {
maven { url "https://jitpack.io" }
mavenCentral()
google()
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
mavenLocal()
}
dependencies {
@@ -27,6 +26,12 @@ buildscript {
allprojects {
repositories {
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
@@ -35,13 +40,6 @@ allprojects {
maven { url "https://jitpack.io" }
mavenCentral()
google()
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
mavenLocal()
}
ext {

View File

@@ -17,3 +17,5 @@ org.gradle.jvmargs=-Xmx2048m
android.useAndroidX=false
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=false
# 保持与旧版Gradle插件的兼容
android.disableAutomaticComponentCreation=true

View File

@@ -17,3 +17,5 @@ org.gradle.jvmargs=-Xmx2048m
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# 保持与旧版Gradle插件的兼容
android.disableAutomaticComponentCreation=true

View File

@@ -4,8 +4,8 @@ apply from: '../.winboll/winboll_lib_build.gradle'
apply from: '../.winboll/winboll_lint_build.gradle'
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 32
buildToolsVersion "32.0.0"
defaultConfig {
minSdkVersion 26

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sat Mar 15 15:29:07 HKT 2025
stageCount=3
#Mon Mar 24 08:04:27 HKT 2025
stageCount=9
libraryProject=libappbase
baseVersion=15.0
publishVersion=15.0.2
publishVersion=15.0.8
buildCount=0
baseBetaVersion=15.0.3
baseBetaVersion=15.0.9

View File

@@ -190,6 +190,7 @@ public class LogView extends RelativeLayout {
// 加载标签表
mListViewTags = findViewById(cc.winboll.studio.libappbase.R.id.tags_listview);
mListViewTags.setVerticalOffset(10);
mTAGListAdapter = new TAGListAdapter(mContext, mapTAGList);
mListViewTags.setAdapter(mTAGListAdapter);

View File

@@ -12,7 +12,9 @@ import android.widget.ListView;
import cc.winboll.studio.libappbase.LogUtils;
public class HorizontalListView extends ListView {
public static final String TAG = "HorizontalListView";
int verticalOffset = 0;
public HorizontalListView(Context context) {
super(context);
@@ -25,25 +27,10 @@ public class HorizontalListView extends ListView {
public HorizontalListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// @Override
// protected void onLayout(boolean changed, int l, int t, int r, int b) {
// super.onLayout(changed, l, t, r, b);
// int childCount = getChildCount();
// int left = getPaddingLeft();
// // 获取HorizontalListView的高度
// int viewHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
// for (int i = 0; i < childCount; i++) {
// View child = getChildAt(i);
// int width = child.getMeasuredWidth();
// int height = child.getMeasuredHeight();
// // 计算子项在垂直方向上的居中偏移量
// int verticalOffset = (viewHeight - height) / 2;
// // 设置子视图的位置,实现水平布局并垂直居中
// child.layout(left, getPaddingTop() + verticalOffset, left + width, getPaddingTop() + verticalOffset + height);
// left += width;
// }
// }
//
public void setVerticalOffset(int verticalOffset) {
this.verticalOffset = verticalOffset;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
@@ -52,7 +39,7 @@ public class HorizontalListView extends ListView {
int left = getPaddingLeft();
int viewHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
LogUtils.d(TAG, String.format("HorizontalListView的高度 %d", viewHeight));
int verticalOffset = 20;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
// 计算每个子视图的宽度和高度
@@ -60,7 +47,7 @@ public class HorizontalListView extends ListView {
int height = child.getMeasuredHeight();
//LogUtils.d(TAG, String.format("child : width %d , height %d", width, height));
// 设置子视图的位置,实现水平布局
child.layout(left, verticalOffset, left + width, verticalOffset + height);
left += width;
}
@@ -68,15 +55,11 @@ public class HorizontalListView extends ListView {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
//super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
//LogUtils.d(TAG, String.format("newWidthMeasureSpec %d, newHeightMeasureSpec %d", newWidthMeasureSpec, newHeightMeasureSpec));
super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
// ViewGroup.LayoutParams params = getLayoutParams();
// params.width = getMeasuredWidth();
}
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#000000" /> <!-- 这里可调整边框宽度和颜色 -->
<solid android:color="@android:color/transparent" />
<corners
android:bottomLeftRadius="6dip"
android:bottomRightRadius="6dip"
android:topLeftRadius="6dip"
android:topRightRadius="6dip" />
</shape>

View File

@@ -10,8 +10,8 @@
<shape android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#0F000000"
android:startColor="#0F000000" />
android:endColor="@color/colorAccent"
android:startColor="@color/colorAccent" />
<corners
android:bottomLeftRadius="6dip"
android:bottomRightRadius="6dip"

View File

@@ -5,18 +5,18 @@
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#FFEEEEEE">
android:background="@drawable/bg_border_round">
<TextView
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_marginLeft="5dp"
android:id="@+id/viewlogtagTextView1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="@dimen/button_height"
android:layout_marginLeft="5dp"
android:id="@+id/viewlogtagTextView1"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="24dp"
android:id="@+id/viewlogtagCheckBox1"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="@dimen/button_height"
android:id="@+id/viewlogtagCheckBox1"/>
</LinearLayout>

View File

@@ -72,27 +72,29 @@
android:layout_below="@+id/viewlogRelativeLayoutToolbar"
android:id="@+id/viewlogLinearLayout1"
android:gravity="center_vertical"
android:background="#FFC0F4C2">
android:background="@drawable/bg_shadow">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="@dimen/button_height"
android:text="ALL"
android:id="@+id/viewlogCheckBox1"/>
android:id="@+id/viewlogCheckBox1"
android:background="@drawable/bg_border_round"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
<HorizontalScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="@drawable/bg_border"
android:scrollbars="none"
android:layout_weight="1.0"
android:background="#FF97F2E3">
android:padding="5dp"
android:layout_weight="1.0">
<cc.winboll.studio.libappbase.views.HorizontalListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@drawable/view_border"
android:id="@+id/tags_listview"
android:paddingLeft="10dp"/>
android:id="@+id/tags_listview"/>
</HorizontalScrollView>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 定义一个名为text_size_normal的尺寸值为16sp -->
<dimen name="text_size_normal">16sp</dimen>
<!-- 定义一个名为margin_small的尺寸值为8dp -->
<dimen name="margin_small">8dp</dimen>
<!-- 定义一个名为image_width的尺寸值为200dp -->
<dimen name="button_height">24dp</dimen>
</resources>

View File

@@ -4,8 +4,8 @@ apply from: '../.winboll/winboll_lib_build.gradle'
apply from: '../.winboll/winboll_lint_build.gradle'
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 32
buildToolsVersion "32.0.0"
defaultConfig {
minSdkVersion 26
@@ -21,18 +21,22 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
implementation 'cc.winboll.studio:libappbase:15.0.5'
// 二维码类库
implementation 'com.google.zxing:core:3.4.1'
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
api 'com.google.zxing:core:3.4.1'
api 'com.journeyapps:zxing-android-embedded:3.6.0'
// 网络连接类库
//implementation 'com.squareup.okhttp3:okhttp:4.4.1'
//api 'com.squareup.okhttp3:okhttp:4.4.1'
// Html 解析
//implementation 'org.jsoup:jsoup:1.13.1'
//api 'org.jsoup:jsoup:1.13.1'
// SSH
//implementation 'com.jcraft:jsch:0.1.55'
//api 'com.jcraft:jsch:0.1.55'
// 应用介绍页类库
//api 'io.github.medyo:android-about-page:2.0.0'
api 'cc.winboll.studio:libappbase:15.0.5'
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Tue Mar 18 10:46:39 HKT 2025
stageCount=5
#Mon Mar 24 14:42:07 HKT 2025
stageCount=13
libraryProject=libapputils
baseVersion=15.0
publishVersion=15.0.4
publishVersion=15.0.12
buildCount=0
baseBetaVersion=15.0.5
baseBetaVersion=15.0.13

View File

@@ -21,7 +21,8 @@
<!-- 拥有完全的网络访问权限 -->
<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"

View File

@@ -5,58 +5,30 @@ package cc.winboll.studio.libapputils.activities;
* @Date 2024/07/14 13:20:33
* @Describe 应用介绍页
*/
import cc.winboll.studio.libapputils.R;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
import android.widget.Toolbar;
import cc.winboll.studio.libapputils.app.IWinBollActivity;
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
import cc.winboll.studio.libapputils.R;
import cc.winboll.studio.libapputils.bean.APPInfo;
import cc.winboll.studio.libapputils.view.AboutView;
final public class AboutActivity extends Activity implements IWinBollActivity {
final public class AboutActivity extends Activity {
public static final String TAG = "AboutActivity";
public static final String EXTRA_APPINFO = "EXTRA_APPINFO";
APPInfo mAPPInfo;
@Override
public Activity getActivity() {
public Context getApplicationContext() {
return this;
}
@Override
public APPInfo getAppInfo() {
return null;
}
@Override
public String getTag() {
return TAG;
}
@Override
public boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
public boolean isAddWinBollToolBar() {
return false;
}
@Override
public Toolbar initToolBar() {
return findViewById(R.id.activityaboutToolbar1);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -84,9 +56,9 @@ final public class AboutActivity extends Activity implements IWinBollActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item_help) {
WinBollActivityManager.getInstance(this).startWinBollActivity(this, AssetsHtmlActivity.class);
}
// if (item.getItemId() == R.id.item_help) {
// WinBollActivityManager.getInstance(this).startWinBollActivity(this, AssetsHtmlActivity.class);
// }
return super.onOptionsItemSelected(item);
}
}

View File

@@ -15,13 +15,12 @@ import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toolbar;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libapputils.app.IWinBollActivity;
import cc.winboll.studio.libapputils.bean.APPInfo;
import cc.winboll.studio.libapputils.view.SimpleWebView;
import java.io.IOException;
import java.io.InputStream;
public class AssetsHtmlActivity extends Activity implements IWinBollActivity {
public class AssetsHtmlActivity extends Activity {
public static final String TAG = "AssetsHtmlActivity";
@@ -33,37 +32,11 @@ public class AssetsHtmlActivity extends Activity implements IWinBollActivity {
// Assets 文件夹里的 Html 文件的名称
String mszHtmlFileName;
@Override
public Activity getActivity() {
return this;
}
@Override
public APPInfo getAppInfo() {
return null;
}
@Override
public String getTag() {
return TAG;
}
@Override
public boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
public boolean isAddWinBollToolBar() {
return false;
}
@Override
public Toolbar initToolBar() {
return findViewById(R.id.activityassetshtmlToolbar1);
}
//
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
@@ -82,6 +55,10 @@ public class AssetsHtmlActivity extends Activity implements IWinBollActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_assetshtml);
// 初始化工具栏
Toolbar mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar);
mszHtmlFileName = "index.html";

View File

@@ -11,44 +11,18 @@ import android.os.Bundle;
import android.widget.Toolbar;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.LogView;
import cc.winboll.studio.libapputils.app.IWinBollActivity;
import cc.winboll.studio.libapputils.bean.APPInfo;
public class LogActivity extends Activity implements IWinBollActivity {
public class LogActivity extends Activity {
public static final String TAG = "LogActivity";
LogView mLogView;
@Override
public Activity getActivity() {
return this;
}
@Override
public APPInfo getAppInfo() {
return null;
}
@Override
public String getTag() {
return TAG;
}
@Override
public Toolbar initToolBar() {
return null;
}
@Override
public boolean isEnableDisplayHomeAsUp() {
return false;
}
@Override
public boolean isAddWinBollToolBar() {
return false;
}
//
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
protected void onCreate(Bundle savedInstanceState) {

View File

@@ -5,22 +5,20 @@ package cc.winboll.studio.libapputils.activities;
* @Date 2025/01/18 10:32:21
* @Describe 二维码扫码解码窗口
*/
import cc.winboll.studio.libapputils.R;
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.libapputils.app.IWinBollActivity;
import cc.winboll.studio.libapputils.bean.APPInfo;
import cc.winboll.studio.libapputils.R;
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 implements IWinBollActivity {
public class QRCodeDecodeActivity extends Activity {
public static final String TAG = "QRCodeDecodeActivity";
@@ -30,42 +28,21 @@ public class QRCodeDecodeActivity extends Activity implements IWinBollActivity {
TextView resultTextView;
DecoratedBarcodeView barcodeView;
@Override
public Activity getActivity() {
return this;
}
@Override
public APPInfo getAppInfo() {
return null;
}
@Override
public String getTag() {
return TAG;
}
@Override
public boolean isEnableDisplayHomeAsUp() {
return true;
}
@Override
public boolean isAddWinBollToolBar() {
return false;
}
@Override
public Toolbar initToolBar() {
return findViewById(R.id.activityqrcodedecodeToolbar1);
}
// @Override
// public Activity getActivity() {
// return this;
// }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qrcodedecode);
resultTextView = findViewById(R.id.activityqrcodedecodeTextView1);
// 初始化工具栏
// Toolbar mToolbar = findViewById(R.id.toolbar);
// setActionBar(mToolbar);
//resultTextView = findViewById(R.id.activityqrcodedecodeTextView1);
barcodeView = findViewById(R.id.activityqrcodedecodeDecoratedBarcodeView1);
// 请求相机权限
// if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
@@ -77,8 +54,6 @@ public class QRCodeDecodeActivity extends Activity implements IWinBollActivity {
// startScanning();
// }
startScanning();
}
private void startScanning() {

View File

@@ -49,6 +49,6 @@ public class AboutActivityFactory {
Intent intent = new Intent(context, AboutActivity.class);
intent.putExtra(AboutActivity.EXTRA_APPINFO, (appInfo == null) ? AboutActivityFactory.buildDefaultAPPInfo():appInfo);
WinBollActivityManager.getInstance(context).startWinBollActivity(context, intent, AboutActivity.class);
//WinBollActivityManager.getInstance(context).startWinBollActivity(context, intent, AboutActivity.class);
}
}

View File

@@ -1,23 +0,0 @@
package cc.winboll.studio.libapputils.app;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/08 00:15:36
* @Describe WinBoll 活动窗口通用接口
*/
import android.app.Activity;
import android.widget.Toolbar;
import cc.winboll.studio.libapputils.bean.APPInfo;
public interface IWinBollActivity {
public static final String TAG = "IWinBollActivity";
// 获取当前具有 IWinBoll 特征的 AppCompatActivity 活动窗口
abstract public Activity getActivity();
abstract public APPInfo getAppInfo();
abstract public String getTag();
abstract public Toolbar initToolBar();
abstract public boolean isEnableDisplayHomeAsUp();
abstract public boolean isAddWinBollToolBar();
}

View File

@@ -1,98 +0,0 @@
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.Intent;
import android.os.Bundle;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.utils.ToastUtils;
public class MyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
public static final String TAG = "MyActivityLifecycleCallbacks";
public String mInfo = "";
public MyActivityLifecycleCallbacks() {
}
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

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

View File

@@ -1,287 +0,0 @@
package cc.winboll.studio.libapputils.bean;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2025/01/15 11:11:52
* @Describe Json Bean 基础类。
*/
import android.content.Context;
import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libapputils.util.FileUtils;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
public abstract class BaseBean<T extends BaseBean> {
public static final String TAG = "BaseBean";
static final String BEAN_NAME = "BeanName";
public BaseBean() {}
public abstract String getName();
public String getBeanJsonFilePath(Context context) {
return context.getExternalFilesDir(TAG) + "/" + getName() + ".json";
}
public String getBeanListJsonFilePath(Context context) {
return context.getExternalFilesDir(TAG) + "/" + getName() + "_List.json";
}
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
jsonWriter.name(BEAN_NAME).value(getName());
}
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
return false;
}
abstract public T readBeanFromJsonReader(JsonReader jsonReader) throws IOException;
public static <T extends BaseBean> String checkIsTheSameBeanListAndFile(String szFilePath, Class<T> clazz) {
StringBuilder sbResult = new StringBuilder();
String szErrorInfo = "Check Is The Same Bean List And File Error : ";
try {
int nSameCount = 0;
int nBeanListCout = 0;
T beanTemp = clazz.newInstance();
String szBeanSimpleName = beanTemp.getName();
String szListJson = FileUtils.readStringFromFile(szFilePath);
StringReader stringReader = new StringReader(szListJson);
JsonReader jsonReader = new JsonReader(stringReader);
jsonReader.beginArray();
while (jsonReader.hasNext()) {
nBeanListCout++;
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
if (name.equals(BEAN_NAME)) {
if (szBeanSimpleName.equals(jsonReader.nextString())) {
nSameCount++;
}
} else {
jsonReader.skipValue();
}
}
jsonReader.endObject();
}
jsonReader.endArray();
// 返回检查结果
if (nSameCount == nBeanListCout) {
// 检查一致直接返回空串
return "";
} else {
// 检查不一致返回对比信息
sbResult.append("Total : ");
sbResult.append(nBeanListCout);
sbResult.append(" Diff : ");
sbResult.append(nBeanListCout - nSameCount);
}
} catch (InstantiationException e) {
sbResult.append(szErrorInfo);
sbResult.append(e);
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IllegalAccessException e) {
sbResult.append(szErrorInfo);
sbResult.append(e);
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IOException e) {
sbResult.append(szErrorInfo);
sbResult.append(e);
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return sbResult.toString();
}
public static <T extends BaseBean> T parseStringToBean(String szBean, Class<T> clazz) throws IOException {
// 创建 JsonWriter 对象
StringReader stringReader = new StringReader(szBean);
JsonReader jsonReader = new JsonReader(stringReader);
try {
T beanTemp = clazz.newInstance();
return (T)beanTemp.readBeanFromJsonReader(jsonReader);
} catch (InstantiationException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IllegalAccessException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return null;
}
public static <T extends BaseBean> boolean parseStringToBeanList(String szBeanList, ArrayList<T> beanList, Class<T> clazz) {
try {
beanList.clear();
StringReader stringReader = new StringReader(szBeanList);
JsonReader jsonReader = new JsonReader(stringReader);
jsonReader.beginArray();
while (jsonReader.hasNext()) {
T beanTemp = clazz.newInstance();
T bean = (T)beanTemp.readBeanFromJsonReader(jsonReader);
if (bean != null) {
beanList.add(bean);
//LogUtils.d(TAG, "beanList.add(bean)");
}
}
jsonReader.endArray();
return true;
//LogUtils.d(TAG, "beanList.size() is " + Integer.toString(beanList.size()));
} catch (InstantiationException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IllegalAccessException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return false;
}
@Override
public String toString() {
// 创建 JsonWriter 对象
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setIndent(" ");
try {// 开始 JSON 对象
jsonWriter.beginObject();
// 写入键值对
writeThisToJsonWriter(jsonWriter);
// 结束 JSON 对象
jsonWriter.endObject();
return stringWriter.toString();
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
// 获取 JSON 字符串
return "";
}
public static <T extends BaseBean> String toStringByBeanList(ArrayList<T> beanList) {
try {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setIndent(" ");
jsonWriter.beginArray();
for (int i = 0; i < beanList.size(); i++) {
// 开始 JSON 对象
jsonWriter.beginObject();
// 写入键值对
beanList.get(i).writeThisToJsonWriter(jsonWriter);
// 结束 JSON 对象
jsonWriter.endObject();
}
jsonWriter.endArray();
jsonWriter.close();
return stringWriter.toString();
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return "";
}
public static <T extends BaseBean> T loadBean(Context context, Class<T> clazz) {
try {
T beanTemp = clazz.newInstance();
return loadBeanFromFile(beanTemp.getBeanJsonFilePath(context), clazz);
} catch (InstantiationException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IllegalAccessException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return null;
}
public static <T extends BaseBean> T loadBeanFromFile(String szFilePath, Class<T> clazz) {
try {
try {
File fTemp = new File(szFilePath);
if (fTemp.exists()) {
T beanTemp = clazz.newInstance();String szJson = FileUtils.readStringFromFile(szFilePath);
return beanTemp.parseStringToBean(szJson, clazz);
}
} catch (InstantiationException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IllegalAccessException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return null;
}
public static <T extends BaseBean> boolean saveBean(Context context, T bean) {
return saveBeanToFile(bean.getBeanJsonFilePath(context), bean);
}
public static <T extends BaseBean> boolean saveBeanToFile(String szFilePath, T bean) {
try {
String szJson = bean.toString();
FileUtils.writeStringToFile(szFilePath, szJson);
return true;
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return false;
}
public static <T extends BaseBean> boolean loadBeanList(Context context, ArrayList<T> beanListDst, Class<T> clazz) {
try {
T beanTemp = clazz.newInstance();
return loadBeanListFromFile(beanTemp.getBeanListJsonFilePath(context), beanListDst, clazz);
} catch (InstantiationException e) {} catch (IllegalAccessException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return false;
}
public static <T extends BaseBean> boolean loadBeanListFromFile(String szFilePath, ArrayList<T> beanList, Class<T> clazz) {
try {
File fTemp = new File(szFilePath);
if (fTemp.exists()) {
String szListJson = FileUtils.readStringFromFile(szFilePath);
return parseStringToBeanList(szListJson, beanList, clazz);
}
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return false;
}
public static <T extends BaseBean> boolean saveBeanList(Context context, ArrayList<T> beanList, Class<T> clazz) {
try {
T beanTemp = clazz.newInstance();
return saveBeanListToFile(beanTemp.getBeanListJsonFilePath(context), beanList);
} catch (InstantiationException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
} catch (IllegalAccessException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return false;
}
public static <T extends BaseBean> boolean saveBeanListToFile(String szFilePath, ArrayList<T> beanList) {
try {
String szJson = toStringByBeanList(beanList);
FileUtils.writeStringToFile(szFilePath, szJson);
//LogUtils.d(TAG, "FileUtil.writeFile beanList.size() is " + Integer.toString(beanList.size()));
return true;
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return false;
}
}

View File

@@ -7,6 +7,7 @@ package cc.winboll.studio.libapputils.bean;
*/
import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.libappbase.BaseBean;
import java.io.IOException;
public class DebugBean extends BaseBean {

View File

@@ -2,7 +2,7 @@ package cc.winboll.studio.libapputils.service;
import android.content.Context;
import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.libapputils.bean.BaseBean;
import cc.winboll.studio.libappbase.BaseBean;
import java.io.IOException;
/**

View File

@@ -0,0 +1,180 @@
package cc.winboll.studio.libapputils.util;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/23 16:17:54
* @Describe 哔哔振动响铃工具集
*/
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.os.Vibrator;
import android.os.VibratorManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BBMorseCodeUtils {
public static final String TAG = "BBMorseCodeUtils";
// private static final int DOT_DURATION = 100; // 点时长 (ms)
// private static final int DASH_DURATION = 300; // 划时长 (ms)
// private static final int SYMBOL_GAP = 100; // 符号间隔 (ms)
// private static final int CHARACTER_GAP = 300; // 字符间隔 (ms)
// private static final int WORD_GAP = 700; // 单词间隔 (ms)
//
// private final Context context;
// private final Handler handler = new Handler();
// private boolean isPlaying = false;
//
// public BBMorseCodeUtils(Context context) {
// this.context = context.getApplicationContext();
// }
//
// public void playMorseCode(String morseCode, boolean vibrateEnabled, boolean ringEnabled) {
// if (isPlaying) return;
// isPlaying = true;
//
// List<List<String>> words = parseMorseCode(morseCode);
// startSequence(words, vibrateEnabled, ringEnabled);
// }
//
// private void startSequence(final List<List<String>> words, final boolean vibrateEnabled, final boolean ringEnabled) {
// final int[] wordIndex = {0};
// final int[] charIndex = {0};
// final int[] symbolIndex = {0};
//
// Runnable sequenceRunner = new Runnable() {
// @Override
// public void run() {
// if (wordIndex[0] >= words.size()) {
// stop();
// return;
// }
//
// List<String> characters = words.get(wordIndex[0]);
// if (charIndex[0] >= characters.size()) {
// charIndex[0] = 0;
// symbolIndex[0] = 0;
// wordIndex[0]++;
// handler.postDelayed(this, WORD_GAP);
// return;
// }
//
// String character = characters.get(charIndex[0]);
// if (symbolIndex[0] >= character.length()) {
// symbolIndex[0] = 0;
// charIndex[0]++;
// handler.postDelayed(this, CHARACTER_GAP);
// return;
// }
//
// char symbol = character.charAt(symbolIndex[0]);
// symbolIndex[0]++;
//
// long duration = (symbol == '.') ? DOT_DURATION : DASH_DURATION;
//
// // 执行振动
// if (vibrateEnabled) {
// vibrate(duration);
// }
//
// // 播放声音
// if (ringEnabled) {
// playSound(symbol, duration);
// }
//
// // 安排下一个符号
// handler.postDelayed(this, duration + SYMBOL_GAP);
// }
// };
//
// handler.post(sequenceRunner);
// }
//
// private void vibrate(long duration) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// VibratorManager vibratorManager = context.getSystemService(VibratorManager.class);
// Vibrator vibrator = vibratorManager.getDefaultVibrator();
// vibrator.vibrate(duration);
// } else {
// Vibrator vibrator = context.getSystemService(Vibrator.class);
// if (vibrator != null && vibrator.hasVibrator()) {
// vibrator.vibrate(duration);
// }
// }
// }
//
// private void playSound(char symbol, long duration) {
// int soundRes = (symbol == '.') ? R.raw.morse_dot : R.raw.morse_dash;
// MediaPlayer mediaPlayer = MediaPlayer.create(context, soundRes);
//
// mediaPlayer.setOnPreparedListener(> {
// mp.start();
// handler.postDelayed(mp::stop, duration);
// });
//
// mediaPlayer.setOnCompletionListener(> {
// mp.release();
// });
// }
//
// private List<List<String>> parseMorseCode(String code) {
// List<List<String>> words = new ArrayList<>();
// String[] wordParts = code.split("/");
//
// for (String word : wordParts) {
// String[] chars = word.trim().split("\\s+");
// words.add(new ArrayList<>(Arrays.asList(chars)));
// }
// return words;
// }
//
// public void stop() {
// isPlaying = false;
// handler.removeCallbacksAndMessages(null);
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// VibratorManager vibratorManager = context.getSystemService(VibratorManager.class);
// Vibrator vibrator = vibratorManager.getDefaultVibrator();
// vibrator.cancel();
// } else {
// Vibrator vibrator = context.getSystemService(Vibrator.class);
// if (vibrator != null) {
// vibrator.cancel();
// }
// }
// }
}
// 使用说明:
//
// 1. 在AndroidManifest.xml中添加权限
//
// xml
//
// <uses-permission android:name="android.permission.VIBRATE"/>
//  
//
// 2. 在res/raw目录下添加两个声音文件
//
// - morse_dot.wav短音
//
// - morse_dash.wav长音
//
// 3. 使用示例:
//
// java
//
// MorsePlayer morsePlayer = new MorsePlayer(this);
//morsePlayer.playMorseCode(".... . / .- --", true, true);
//
// 停止播放
// morsePlayer.stop();
// MorsePlayer morsePlayer = new MorsePlayer(this);
//morsePlayer.playMorseCode(".... . / .- --", true, true);
//
//// 停止播放
//// morsePlayer.stop();
//

View File

@@ -21,7 +21,6 @@ import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.utils.ToastUtils;
import cc.winboll.studio.libapputils.app.AppVersionUtils;
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
import cc.winboll.studio.libapputils.bean.APPInfo;
import cc.winboll.studio.libapputils.bean.DebugBean;
import cc.winboll.studio.libapputils.util.PrefUtils;

View File

@@ -9,7 +9,7 @@
<android.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activityaboutToolbar1"/>
android:id="@+id/toolbar"/>
<LinearLayout
android:orientation="vertical"

View File

@@ -9,7 +9,7 @@
<android.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activityassetshtmlToolbar1"/>
android:id="@+id/toolbar"/>
<cc.winboll.studio.libapputils.view.SimpleWebView
android:layout_width="match_parent"

View File

@@ -6,16 +6,10 @@
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/activityqrcodedecodeToolbar1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="扫描结果将显示在此处"
android:id="@+id/activityqrcodedecodeTextView1"/>
android:text="QRCodeDecodeActivity"/>
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:layout_width="wrap_content"

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="UtilsTheme" parent="APPBaseTheme">
<style name="UtilsTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
</style>
</resources>