diff --git a/aes/build.gradle b/aes/build.gradle
index c6a3a6c..13025d9 100644
--- a/aes/build.gradle
+++ b/aes/build.gradle
@@ -19,17 +19,17 @@ def genVersionName(def versionName){
android {
compileSdkVersion 32
- buildToolsVersion "33.0.3"
+ buildToolsVersion "32.0.0"
defaultConfig {
applicationId "cc.winboll.studio.aes"
minSdkVersion 24
- targetSdkVersion 30
+ targetSdkVersion 29
versionCode 1
// versionName 更新后需要手动设置
// 项目模块目录的 build.gradle 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
- versionName "7.6"
+ versionName "15.2"
if(true) {
versionName = genVersionName("${versionName}")
}
@@ -41,29 +41,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
- }
}
dependencies {
api project(':libaes')
-
- //api 'cc.winboll.studio:winboll-shared:1.6.5'
- 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.1'
- api 'cc.winboll.studio:libappbase:1.0.3'
-
api fileTree(dir: 'libs', include: ['*.jar'])
}
diff --git a/aes/build.properties b/aes/build.properties
index 69caa9a..e14ab66 100644
--- a/aes/build.properties
+++ b/aes/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Sun Jan 19 04:58:59 GMT 2025
-stageCount=3
+#Mon Mar 31 02:04:47 HKT 2025
+stageCount=4
libraryProject=libaes
-baseVersion=7.6
-publishVersion=7.6.2
-buildCount=4
-baseBetaVersion=7.6.3
+baseVersion=15.2
+publishVersion=15.2.3
+buildCount=0
+baseBetaVersion=15.2.4
diff --git a/aes/src/main/AndroidManifest.xml b/aes/src/main/AndroidManifest.xml
index cc00d93..d123b21 100644
--- a/aes/src/main/AndroidManifest.xml
+++ b/aes/src/main/AndroidManifest.xml
@@ -8,9 +8,10 @@
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
- android:theme="@style/WinBoll.SupportThemeNoActionBar"
+ android:theme="@style/MyAESTheme"
android:requestLegacyExternalStorage="true"
- android:supportsRtl="true">
+ android:supportsRtl="true"
+ android:networkSecurityConfig="@xml/network_security_config">
+
+
diff --git a/aes/src/main/java/cc/winboll/studio/aes/AboutActivity.java b/aes/src/main/java/cc/winboll/studio/aes/AboutActivity.java
new file mode 100644
index 0000000..208327c
--- /dev/null
+++ b/aes/src/main/java/cc/winboll/studio/aes/AboutActivity.java
@@ -0,0 +1,91 @@
+package cc.winboll.studio.aes;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/24 23:52:29
+ * @Describe AES应用介绍窗口
+ */
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+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);
+
+ GlobalApplication.getWinBollActivityManager().add(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ GlobalApplication.getWinBollActivityManager().registeRemove(this);
+ }
+
+ public AboutView CreateAboutView() {
+ String szBranchName = "aes";
+ APPInfo appInfo = new APPInfo();
+ appInfo.setAppName("AES");
+ appInfo.setAppIcon(cc.winboll.studio.libaes.R.drawable.ic_winboll);
+ appInfo.setAppDescription("AES Description");
+ appInfo.setAppGitName("APP");
+ appInfo.setAppGitOwner("Studio");
+ appInfo.setAppGitAPPBranch(szBranchName);
+ appInfo.setAppGitAPPSubProjectFolder(szBranchName);
+ appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=AES");
+ appInfo.setAppAPKName("AES");
+ appInfo.setAppAPKFolderName("AES");
+ return new AboutView(mContext, appInfo);
+ }
+}
diff --git a/aes/src/main/java/cc/winboll/studio/aes/App.java b/aes/src/main/java/cc/winboll/studio/aes/App.java
index 578f72d..2eefe56 100644
--- a/aes/src/main/java/cc/winboll/studio/aes/App.java
+++ b/aes/src/main/java/cc/winboll/studio/aes/App.java
@@ -6,6 +6,8 @@ package cc.winboll.studio.aes;
* @Describe AES应用类
*/
import cc.winboll.studio.libappbase.GlobalApplication;
+import com.hjq.toast.ToastUtils;
+
public class App extends GlobalApplication {
@@ -14,7 +16,8 @@ public class App extends GlobalApplication {
@Override
public void onCreate() {
super.onCreate();
- //setIsDebug(BuildConfig.DEBUG);
+ ToastUtils.init(this);
+ //ToastUtils.show("App onCreate");
}
}
diff --git a/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java b/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java
index cafaf1e..7d76e83 100644
--- a/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java
+++ b/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java
@@ -5,12 +5,193 @@ package cc.winboll.studio.aes;
* @Date 2024/06/13 19:05:52
* @Describe 应用主窗口
*/
-import cc.winboll.studio.libaes.unittests.LibraryActivity;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Toast;
+import cc.winboll.studio.aes.R;
+import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
+import cc.winboll.studio.libaes.beans.DrawerMenuBean;
+import cc.winboll.studio.libaes.dialogs.LocalFileSelectDialog;
+import cc.winboll.studio.libaes.dialogs.StoragePathDialog;
+import cc.winboll.studio.libaes.unittests.SecondaryLibraryActivity;
+import cc.winboll.studio.libaes.unittests.TestAButtonFragment;
+import cc.winboll.studio.libaes.unittests.TestASupportToolbarActivity;
+import cc.winboll.studio.libaes.unittests.TestAToolbarActivity;
+import cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity;
+import cc.winboll.studio.libaes.unittests.TestViewPageFragment;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
+import com.a4455jkjh.colorpicker.ColorPickerDialog;
+import com.hjq.toast.ToastUtils;
+import java.util.ArrayList;
+
+public class MainActivity extends DrawerFragmentActivity implements IWinBollActivity {
+
-public class MainActivity extends LibraryActivity {
-
public static final String TAG = "MainActivity";
+
+ TestAButtonFragment mTestAButtonFragment;
+ TestViewPageFragment mTestViewPageFragment;
+ @Override
+ public Activity getActivity() {
+ return this;
+ }
+
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (mTestAButtonFragment == null) {
+ mTestAButtonFragment = new TestAButtonFragment();
+ addFragment(mTestAButtonFragment);
+ }
+ showFragment(mTestAButtonFragment);
+ //setSubtitle(TAG);
+ //ToastUtils.show("onCreate");
+ }
+
+ @Override
+ public void initDrawerMenuItemList(ArrayList listDrawerMenu) {
+ super.initDrawerMenuItemList(listDrawerMenu);
+ LogUtils.d(TAG, "initDrawerMenuItemList");
+ //listDrawerMenu.clear();
+ // 添加抽屉菜单项
+ listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestAButtonFragment.TAG));
+ listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestViewPageFragment.TAG));
+ notifyDrawerMenuDataChanged();
+ }
+
+ @Override
+ public void reinitDrawerMenuItemList(ArrayList listDrawerMenu) {
+ super.reinitDrawerMenuItemList(listDrawerMenu);
+ LogUtils.d(TAG, "reinitDrawerMenuItemList");
+ //listDrawerMenu.clear();
+ // 添加抽屉菜单项
+ listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestAButtonFragment.TAG));
+ listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestViewPageFragment.TAG));
+ notifyDrawerMenuDataChanged();
+ }
+
+ @Override
+ public DrawerFragmentActivity.ActivityType initActivityType() {
+ return DrawerFragmentActivity.ActivityType.Main;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.toolbar_library, menu);
+ if(App.isDebuging()) {
+ getMenuInflater().inflate(cc.winboll.studio.libapputils.R.menu.toolbar_studio_debug, menu);
+ }
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ super.onItemClick(parent, view, position, id);
+ switch (position) {
+ case 0 : {
+ if (mTestAButtonFragment == null) {
+ mTestAButtonFragment = new TestAButtonFragment();
+ addFragment(mTestAButtonFragment);
+ }
+ showFragment(mTestAButtonFragment);
+ break;
+ }
+ case 1 : {
+ if (mTestViewPageFragment == null) {
+ mTestViewPageFragment = new TestViewPageFragment();
+ addFragment(mTestViewPageFragment);
+ }
+ showFragment(mTestViewPageFragment);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int nItemId = item.getItemId();
+// if (item.getItemId() == R.id.item_log) {
+// WinBollActivityManager.getInstance(this).startWinBollActivity(getApplicationContext(), LogActivity.class);
+// } else
+ if (nItemId == R.id.item_atoast) {
+ Toast.makeText(getApplication(), "item_testatoast", Toast.LENGTH_SHORT).show();
+ } else if (nItemId == R.id.item_atoolbar) {
+ Intent intent = new Intent(this, TestAToolbarActivity.class);
+ startActivity(intent);
+
+ } else if (nItemId == R.id.item_asupporttoolbar) {
+ Intent intent = new Intent(this, TestASupportToolbarActivity.class);
+ startActivity(intent);
+
+ } else if (nItemId == R.id.item_colordialog) {
+ ColorPickerDialog dlg = new ColorPickerDialog(this, getResources().getColor(R.color.colorPrimary));
+ dlg.setOnColorChangedListener(new com.a4455jkjh.colorpicker.view.OnColorChangedListener() {
+
+ @Override
+ public void beforeColorChanged() {
+ }
+
+ @Override
+ public void onColorChanged(int color) {
+
+ }
+
+ @Override
+ public void afterColorChanged() {
+ }
+
+
+ });
+ dlg.show();
+
+ } else if (nItemId == R.id.item_dialogstoragepath) {
+ final StoragePathDialog dialog = new StoragePathDialog(this, 0);
+ dialog.setOnOKClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dialog.dismiss();
+ }
+ });
+ dialog.show();
+
+ } else if (nItemId == R.id.item_localfileselectdialog) {
+ final LocalFileSelectDialog dialog = new LocalFileSelectDialog(this);
+ dialog.setOnOKClickListener(new LocalFileSelectDialog.OKClickListener() {
+ @Override
+ public void onOKClick(String sz) {
+ Toast.makeText(getApplication(), sz, Toast.LENGTH_SHORT).show();
+ //dialog.dismiss();
+ }
+ });
+ dialog.open();
+
+ } else if (nItemId == R.id.item_secondarylibraryactivity) {
+ Intent intent = new Intent(this, SecondaryLibraryActivity.class);
+ startActivity(intent);
+ } else if (nItemId == R.id.item_drawerfragmentactivity) {
+ Intent intent = new Intent(this, TestDrawerFragmentActivity.class);
+ startActivity(intent);
+ }
+ else if (nItemId == R.id.item_about) {
+ Intent intent = new Intent(this, AboutActivity.class);
+ startActivity(intent);
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
}
diff --git a/aes/src/main/java/cc/winboll/studio/aes/WinBollActivity.java b/aes/src/main/java/cc/winboll/studio/aes/WinBollActivity.java
new file mode 100644
index 0000000..a57c782
--- /dev/null
+++ b/aes/src/main/java/cc/winboll/studio/aes/WinBollActivity.java
@@ -0,0 +1,50 @@
+package cc.winboll.studio.aes;
+
+import android.app.Activity;
+import android.os.Bundle;
+import androidx.appcompat.app.AppCompatActivity;
+import cc.winboll.studio.libaes.beans.AESThemeBean;
+import cc.winboll.studio.libaes.utils.AESThemeUtil;
+import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/30 00:34:02
+ * @Describe WinBoll 活动窗口通用基类
+ */
+public class WinBollActivity extends AppCompatActivity implements IWinBollActivity {
+
+ public static final String TAG = "WinBollActivity";
+
+ protected volatile AESThemeBean.ThemeType mThemeType;
+
+ @Override
+ public Activity getActivity() {
+ return this;
+ }
+
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ mThemeType = getThemeType();
+ setThemeStyle();
+ super.onCreate(savedInstanceState);
+ }
+
+ AESThemeBean.ThemeType getThemeType() {
+ /*SharedPreferences sharedPreferences = getSharedPreferences(
+ SHAREDPREFERENCES_NAME, MODE_PRIVATE);
+ return AESThemeBean.ThemeType.values()[((sharedPreferences.getInt(DRAWER_THEME_TYPE, AESThemeBean.ThemeType.DEFAULT.ordinal())))];
+ */
+ return AESThemeBean.getThemeStyleType(AESThemeUtil.getThemeTypeID(getApplicationContext()));
+ }
+
+ void setThemeStyle() {
+ //setTheme(AESThemeBean.getThemeStyle(getThemeType()));
+ setTheme(AESThemeUtil.getThemeTypeID(getApplicationContext()));
+ }
+}
diff --git a/aes/src/main/res/layout/activity_about.xml b/aes/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..3de4825
--- /dev/null
+++ b/aes/src/main/res/layout/activity_about.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/libaes/src/main/res/menu/toolbar_library.xml b/aes/src/main/res/menu/toolbar_library.xml
similarity index 99%
rename from libaes/src/main/res/menu/toolbar_library.xml
rename to aes/src/main/res/menu/toolbar_library.xml
index d01cea5..b12aef8 100644
--- a/libaes/src/main/res/menu/toolbar_library.xml
+++ b/aes/src/main/res/menu/toolbar_library.xml
@@ -13,7 +13,7 @@
-
+
diff --git a/aes/src/main/res/values/colors.xml b/aes/src/main/res/values/colors.xml
new file mode 100644
index 0000000..87d3836
--- /dev/null
+++ b/aes/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #FF00B322
+ #FF005C12
+ #FF8DFFA2
+ #FFFFFB8D
+
diff --git a/aes/src/main/res/values/styles.xml b/aes/src/main/res/values/styles.xml
index c5c6ef3..1da88ba 100644
--- a/aes/src/main/res/values/styles.xml
+++ b/aes/src/main/res/values/styles.xml
@@ -1,5 +1,5 @@
-
diff --git a/aes/src/main/res/xml/network_security_config.xml b/aes/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..ee39aa4
--- /dev/null
+++ b/aes/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,6 @@
+
+
+
+ winboll.cc
+
+
diff --git a/libaes/build.gradle b/libaes/build.gradle
index 07ed99e..11d6484 100644
--- a/libaes/build.gradle
+++ b/libaes/build.gradle
@@ -4,14 +4,12 @@ apply from: '../.winboll/winboll_lib_build.gradle'
apply from: '../.winboll/winboll_lint_build.gradle'
android {
- namespace 'cc.winboll.studio.libaes'
-
compileSdkVersion 32
- buildToolsVersion "33.0.3"
+ buildToolsVersion "32.0.0"
defaultConfig {
minSdkVersion 24
- targetSdkVersion 30
+ targetSdkVersion 29
}
buildTypes {
release {
@@ -19,30 +17,40 @@ android {
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.6.5'
-
- 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'
-
- // https://github.com/baoyongzhang/android-PullRefreshLayout
- api 'com.baoyz.pullrefreshlayout:library:1.2.0'
-
- api 'cc.winboll.studio:libapputils:9.2.1'
- api 'cc.winboll.studio:libappbase:1.0.3'
-
api fileTree(dir: 'libs', include: ['*.jar'])
+
+ // 吐司类库
+ api 'com.github.getActivity:ToastUtils:10.5'
+
+ // 权限请求框架:https://github.com/getActivity/XXPermissions
+ api 'com.github.getActivity:XXPermissions:18.63'
+ // 下拉控件
+ api 'com.baoyz.pullrefreshlayout:library:1.2.0'
+ // 拼音搜索
+ // https://mvnrepository.com/artifact/com.github.open-android/pinyin4j
+ api 'com.github.open-android:pinyin4j:2.5.0'
+ // 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.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:libappbase:15.2.0'
+ api 'cc.winboll.studio:libapputils:15.2.0'
}
diff --git a/libaes/build.properties b/libaes/build.properties
index 69caa9a..60a20e9 100644
--- a/libaes/build.properties
+++ b/libaes/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Sun Jan 19 04:58:59 GMT 2025
-stageCount=3
+#Mon Mar 31 02:04:35 HKT 2025
+stageCount=4
libraryProject=libaes
-baseVersion=7.6
-publishVersion=7.6.2
-buildCount=4
-baseBetaVersion=7.6.3
+baseVersion=15.2
+publishVersion=15.2.3
+buildCount=0
+baseBetaVersion=15.2.4
diff --git a/libaes/src/main/AndroidManifest.xml b/libaes/src/main/AndroidManifest.xml
index 74ac142..33e8010 100644
--- a/libaes/src/main/AndroidManifest.xml
+++ b/libaes/src/main/AndroidManifest.xml
@@ -5,16 +5,27 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
-
-
-
-
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/activitys/DrawerFragmentActivity.java b/libaes/src/main/java/cc/winboll/studio/libaes/activitys/DrawerFragmentActivity.java
index ff63941..b353823 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/activitys/DrawerFragmentActivity.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/activitys/DrawerFragmentActivity.java
@@ -27,18 +27,20 @@ import cc.winboll.studio.libaes.beans.AESThemeBean;
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libaes.views.ADrawerMenuListView;
-import cc.winboll.studio.libapputils.log.LogUtils;
+import cc.winboll.studio.libappbase.GlobalApplication;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import com.baoyz.widget.PullRefreshLayout;
import java.util.ArrayList;
-public abstract class DrawerFragmentActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
+public abstract class DrawerFragmentActivity extends AppCompatActivity implements IWinBollActivity,AdapterView.OnItemClickListener {
public static final String TAG = "DrawerFragmentActivity";
static final String SHAREDPREFERENCES_NAME = "SHAREDPREFERENCES_NAME";
static final String DRAWER_THEME_TYPE = "DRAWER_THEME_TYPE";
- protected Context mContext;
+ //protected Context mContext;
ActivityType mActivityType;
ActionBarDrawerToggle mActionBarDrawerToggle;
DrawerLayout mDrawerLayout;
@@ -58,7 +60,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
@Override
protected void onCreate(Bundle savedInstanceState) {
- mContext = this;
+ //mContext = this;
mThemeType = getThemeType();
setThemeStyle();
super.onCreate(savedInstanceState);
@@ -72,7 +74,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
super.onDestroy();
}
- @Override
+ /*@Override
public Intent getIntent() {
// TODO: Implement this method
return super.getIntent();
@@ -80,7 +82,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
public Context getContext() {
return this.mContext;
- }
+ }*/
@Override
public MenuInflater getMenuInflater() {
@@ -88,20 +90,20 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
return super.getMenuInflater();
}
- public void setSubtitle(CharSequence context) {
+ /*public void setSubtitle(CharSequence context) {
// TODO: Implement this method
getSupportActionBar().setSubtitle(context);
- }
+ }*/
@Override
public void recreate() {
super.recreate();
}
- @Override
+ /*@Override
public boolean moveTaskToBack(boolean nonRoot) {
return super.moveTaskToBack(nonRoot);
- }
+ }*/
@Override
public void startActivity(Intent intent) {
@@ -113,7 +115,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
super.startActivityForResult(intent, requestCode, options);
}
- @Override
+ /*@Override
public FragmentManager getSupportFragmentManager() {
return super.getSupportFragmentManager();
}
@@ -131,7 +133,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
public void setTitle(int resId) {
// TODO: Implement this method
getSupportActionBar().setTitle(resId);
- }
+ }*/
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
@@ -151,7 +153,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
void setThemeStyle() {
//setTheme(AESThemeBean.getThemeStyle(getThemeType()));
- setTheme(AESThemeUtil.getThemeTypeID(this));
+ setTheme(AESThemeUtil.getThemeTypeID(getApplicationContext()));
}
boolean checkThemeStyleChange() {
@@ -163,7 +165,7 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
SHAREDPREFERENCES_NAME, MODE_PRIVATE);
return AESThemeBean.ThemeType.values()[((sharedPreferences.getInt(DRAWER_THEME_TYPE, AESThemeBean.ThemeType.DEFAULT.ordinal())))];
*/
- return AESThemeBean.getThemeStyleType(AESThemeUtil.getThemeTypeID(this));
+ return AESThemeBean.getThemeStyleType(AESThemeUtil.getThemeTypeID(getApplicationContext()));
}
@Override
@@ -174,6 +176,8 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
getString(i);
}
+ } else if (R.id.item_log == item.getItemId()) {
+ GlobalApplication.getWinBollActivityManager().startLogActivity(this);
} else if (R.id.item_about == item.getItemId()) {
LogUtils.d(TAG, "onAbout");
} else if (android.R.id.home == item.getItemId()) {
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/beans/AESThemeBean.java b/libaes/src/main/java/cc/winboll/studio/libaes/beans/AESThemeBean.java
index 2d3a474..44fd998 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/beans/AESThemeBean.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/beans/AESThemeBean.java
@@ -8,7 +8,7 @@ package cc.winboll.studio.libaes.beans;
import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.libaes.R;
-import cc.winboll.studio.libapputils.bean.BaseBean;
+import cc.winboll.studio.libappbase.BaseBean;
import java.io.IOException;
public class AESThemeBean extends BaseBean {
@@ -16,7 +16,7 @@ public class AESThemeBean extends BaseBean {
public static final String TAG = "AESThemeBean";
public enum ThemeType {
- DEFAULT("默认主题"),
+ AES("默认主题"),
DEPTH("深奥主题"),
SKY("天空主题"),
GOLDEN("辉煌主题"),
@@ -42,7 +42,7 @@ public class AESThemeBean extends BaseBean {
}
// 保存当前主题
- int currentThemeStyleID = getThemeStyleID(ThemeType.DEFAULT);
+ int currentThemeStyleID = getThemeStyleID(ThemeType.AES);
public AESThemeBean() {
}
@@ -99,7 +99,7 @@ public class AESThemeBean extends BaseBean {
}
public static int getThemeStyleID(ThemeType themeType) {
- int themeStyleID = R.style.DefaultAESTheme;
+ int themeStyleID = R.style.AESTheme;
if (AESThemeBean.ThemeType.DEPTH == themeType) {
themeStyleID = R.style.DepthAESTheme;
} else if (AESThemeBean.ThemeType.SKY == themeType) {
@@ -110,15 +110,15 @@ public class AESThemeBean extends BaseBean {
themeStyleID = R.style.MemorAESTheme;
} else if (AESThemeBean.ThemeType.TAO == themeType) {
themeStyleID = R.style.TaoAESTheme;
- } else if (AESThemeBean.ThemeType.DEFAULT == themeType) {
- themeStyleID = R.style.DefaultAESTheme;
+ } else if (AESThemeBean.ThemeType.AES == themeType) {
+ themeStyleID = R.style.AESTheme;
}
//LogUtils.d(TAG, "themeStyleID " + Integer.toString(themeStyleID));
return themeStyleID;
}
public static AESThemeBean.ThemeType getThemeStyleType(int nThemeStyleID) {
- AESThemeBean.ThemeType themeStyle = AESThemeBean.ThemeType.DEFAULT;
+ AESThemeBean.ThemeType themeStyle = AESThemeBean.ThemeType.AES;
if (R.style.DepthAESTheme == nThemeStyleID) {
themeStyle = AESThemeBean.ThemeType.DEPTH ;
} else if (R.style.SkyAESTheme == nThemeStyleID) {
@@ -129,8 +129,8 @@ public class AESThemeBean extends BaseBean {
themeStyle = AESThemeBean.ThemeType.MEMOR ;
} else if (R.style.TaoAESTheme == nThemeStyleID) {
themeStyle = AESThemeBean.ThemeType.TAO ;
- } else if (R.style.DefaultAESTheme == nThemeStyleID) {
- themeStyle = AESThemeBean.ThemeType.DEFAULT;
+ } else if (R.style.AESTheme == nThemeStyleID) {
+ themeStyle = AESThemeBean.ThemeType.AES;
}
//LogUtils.d(TAG, "themeStyle " + Integer.toString(themeStyle.ordinal()));
return themeStyle;
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/dialogs/LocalFileSelectDialog.java b/libaes/src/main/java/cc/winboll/studio/libaes/dialogs/LocalFileSelectDialog.java
index 2f6b613..c181865 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/dialogs/LocalFileSelectDialog.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/dialogs/LocalFileSelectDialog.java
@@ -5,7 +5,7 @@ import android.content.DialogInterface;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
-import cc.winboll.studio.libapputils.log.LogUtils;
+import cc.winboll.studio.libappbase.LogUtils;
import java.io.File;
import java.lang.reflect.Field;
import java.text.Collator;
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/LibraryActivity.java b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/LibraryActivity.java
deleted file mode 100644
index 6e611bf..0000000
--- a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/LibraryActivity.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package cc.winboll.studio.libaes.unittests;
-
-/**
- * @Author ZhanGSKen@QQ.COM
- * @Date 2024/06/14 03:43:23
- * @Describe AES类库主窗口
- */
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.Toast;
-import cc.winboll.studio.libaes.R;
-import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
-import cc.winboll.studio.libaes.beans.DrawerMenuBean;
-import cc.winboll.studio.libaes.dialogs.LocalFileSelectDialog;
-import cc.winboll.studio.libaes.dialogs.StoragePathDialog;
-import cc.winboll.studio.libapputils.log.LogUtils;
-import com.a4455jkjh.colorpicker.ColorPickerDialog;
-import java.util.ArrayList;
-
-public class LibraryActivity extends DrawerFragmentActivity {
-
- public static final String TAG = "LibraryActivity";
-
- TestAButtonFragment mTestAButtonFragment;
- TestViewPageFragment mTestViewPageFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (mTestAButtonFragment == null) {
- mTestAButtonFragment = new TestAButtonFragment();
- addFragment(mTestAButtonFragment);
- }
- showFragment(mTestAButtonFragment);
- setSubtitle(TAG);
- }
-
- @Override
- public void initDrawerMenuItemList(ArrayList listDrawerMenu) {
- super.initDrawerMenuItemList(listDrawerMenu);
- LogUtils.d(TAG, "initDrawerMenuItemList");
- //listDrawerMenu.clear();
- // 添加抽屉菜单项
- listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestAButtonFragment.TAG));
- listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestViewPageFragment.TAG));
- notifyDrawerMenuDataChanged();
- }
-
- @Override
- public void reinitDrawerMenuItemList(ArrayList listDrawerMenu) {
- super.reinitDrawerMenuItemList(listDrawerMenu);
- LogUtils.d(TAG, "reinitDrawerMenuItemList");
- //listDrawerMenu.clear();
- // 添加抽屉菜单项
- listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestAButtonFragment.TAG));
- listDrawerMenu.add(new DrawerMenuBean(R.drawable.ic_launcher, TestViewPageFragment.TAG));
- notifyDrawerMenuDataChanged();
- }
-
- @Override
- public DrawerFragmentActivity.ActivityType initActivityType() {
- return DrawerFragmentActivity.ActivityType.Main;
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.toolbar_library, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public void onItemClick(AdapterView> parent, View view, int position, long id) {
- super.onItemClick(parent, view, position, id);
- switch (position) {
- case 0 : {
- if (mTestAButtonFragment == null) {
- mTestAButtonFragment = new TestAButtonFragment();
- addFragment(mTestAButtonFragment);
- }
- showFragment(mTestAButtonFragment);
- break;
- }
- case 1 : {
- if (mTestViewPageFragment == null) {
- mTestViewPageFragment = new TestViewPageFragment();
- addFragment(mTestViewPageFragment);
- }
- showFragment(mTestViewPageFragment);
- break;
- }
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int nItemId = item.getItemId();
-// if (item.getItemId() == R.id.item_log) {
-// WinBollActivityManager.getInstance(this).startWinBollActivity(getApplicationContext(), LogActivity.class);
-// } else
- if (nItemId == R.id.item_atoast) {
- Toast.makeText(getApplication(), "item_testatoast", Toast.LENGTH_SHORT).show();
- } else if (nItemId == R.id.item_atoolbar) {
- Intent intent = new Intent(this, TestAToolbarActivity.class);
- startActivity(intent);
-
- } else if (nItemId == R.id.item_asupporttoolbar) {
- Intent intent = new Intent(this, TestASupportToolbarActivity.class);
- startActivity(intent);
-
- } else if (nItemId == R.id.item_colordialog) {
- ColorPickerDialog dlg = new ColorPickerDialog(this, getResources().getColor(R.color.colorPrimary));
- dlg.setOnColorChangedListener(new com.a4455jkjh.colorpicker.view.OnColorChangedListener() {
-
- @Override
- public void beforeColorChanged() {
- }
-
- @Override
- public void onColorChanged(int color) {
-
- }
-
- @Override
- public void afterColorChanged() {
- }
-
-
- });
- dlg.show();
-
- } else if (nItemId == R.id.item_dialogstoragepath) {
- final StoragePathDialog dialog = new StoragePathDialog(this, 0);
- dialog.setOnOKClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dialog.dismiss();
- }
- });
- dialog.show();
-
- } else if (nItemId == R.id.item_localfileselectdialog) {
- final LocalFileSelectDialog dialog = new LocalFileSelectDialog(this);
- dialog.setOnOKClickListener(new LocalFileSelectDialog.OKClickListener() {
- @Override
- public void onOKClick(String sz) {
- Toast.makeText(getApplication(), sz, Toast.LENGTH_SHORT).show();
- //dialog.dismiss();
- }
- });
- dialog.open();
-
- } else if (nItemId == R.id.item_secondarylibraryactivity) {
- Intent intent = new Intent(this, SecondaryLibraryActivity.class);
- startActivity(intent);
- } else if (nItemId == R.id.item_drawerfragmentactivity) {
- Intent intent = new Intent(this, TestDrawerFragmentActivity.class);
- startActivity(intent);
- }
-// else if (nItemId == R.id.item_about) {
-// Intent intent = new Intent(this, AboutActivity.class);
-// startActivity(intent);
-// }
-
- return super.onOptionsItemSelected(item);
- }
-}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/SecondaryLibraryActivity.java b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/SecondaryLibraryActivity.java
index 64db217..42cdef8 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/SecondaryLibraryActivity.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/SecondaryLibraryActivity.java
@@ -1,23 +1,35 @@
package cc.winboll.studio.libaes.unittests;
+import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
+import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
/**
* @Author ZhanGSKen@QQ.COM
* @Date 2024/06/15 00:58:10
* @Describe 第二级窗口
*/
-public class SecondaryLibraryActivity extends DrawerFragmentActivity {
+public class SecondaryLibraryActivity extends DrawerFragmentActivity implements IWinBollActivity {
public static final String TAG = "SecondaryLibraryActivity";
SecondaryLibraryFragment mSecondaryLibraryFragment;
+ @Override
+ public Activity getActivity() {
+ return this;
+ }
+
+ @Override
+ public String getTag() {
+ return null;
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -43,7 +55,7 @@ public class SecondaryLibraryActivity extends DrawerFragmentActivity {
public boolean onOptionsItemSelected(MenuItem item) {
int nItemId = item.getItemId();
if (nItemId == R.id.item_test) {
- Toast.makeText(getApplication(), "item_test", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getApplicationContext(), "item_test", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAButtonFragment.java b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAButtonFragment.java
index 64e125c..6dcf11d 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAButtonFragment.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAButtonFragment.java
@@ -9,11 +9,11 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Toast;
import androidx.fragment.app.Fragment;
import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.views.AButton;
-import cc.winboll.studio.libapputils.log.LogUtils;
+import cc.winboll.studio.libappbase.LogUtils;
+import com.hjq.toast.ToastUtils;
public class TestAButtonFragment extends Fragment {
@@ -28,7 +28,7 @@ public class TestAButtonFragment extends Fragment {
@Override
public void onClick(View view) {
LogUtils.d(TAG, "onClick");
- Toast.makeText(getActivity(), "AButton", Toast.LENGTH_SHORT).show();
+ ToastUtils.show("AButton");
}
});
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestASupportToolbarActivity.java b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestASupportToolbarActivity.java
index c570bf6..1ba071d 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestASupportToolbarActivity.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestASupportToolbarActivity.java
@@ -5,19 +5,27 @@ package cc.winboll.studio.libaes.unittests;
* @Date 2024/07/16 01:14:00
* @Describe TestASupportToolbarActivity
*/
-import android.content.Context;
-import android.content.SharedPreferences;
+import android.app.Activity;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libaes.R;
-import cc.winboll.studio.libaes.beans.AESThemeBean;
import cc.winboll.studio.libaes.utils.AESThemeUtil;
+import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
-public class TestASupportToolbarActivity extends AppCompatActivity {
+public class TestASupportToolbarActivity extends AppCompatActivity implements IWinBollActivity {
public static final String TAG = "TestASupportToolbarActivity";
+ @Override
+ public Activity getActivity() {
+ return this;
+ }
+
+ @Override
+ public String getTag() {
+ return TAG;
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAToolbarActivity.java b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAToolbarActivity.java
index bdd401c..2aa4f4d 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAToolbarActivity.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestAToolbarActivity.java
@@ -10,11 +10,22 @@ import android.os.Bundle;
import android.widget.Toolbar;
import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.utils.AESThemeUtil;
+import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
-public class TestAToolbarActivity extends Activity {
+public class TestAToolbarActivity extends Activity implements IWinBollActivity {
public static final String TAG = "TestAToolbarActivity";
+ @Override
+ public Activity getActivity() {
+ return this;
+ }
+
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
AESThemeUtil.applyAppTheme(this);
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestDrawerFragmentActivity.java b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestDrawerFragmentActivity.java
index b49c28d..2646e1c 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestDrawerFragmentActivity.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestDrawerFragmentActivity.java
@@ -4,26 +4,40 @@ package cc.winboll.studio.libaes.unittests;
* @Author ZhanGSKen@QQ.COM
* @Date 2024/06/30 15:00:51
*/
+import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Toast;
+import android.widget.Toolbar;
import androidx.fragment.app.Fragment;
import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
-import cc.winboll.studio.libapputils.log.LogUtils;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
import java.util.ArrayList;
-public class TestDrawerFragmentActivity extends DrawerFragmentActivity {
+public class TestDrawerFragmentActivity extends DrawerFragmentActivity implements IWinBollActivity {
+
+ @Override
+ public Activity getActivity() {
+ return this;
+ }
+
+ @Override
+ public String getTag() {
+ return null;
+ }
public static final String TAG = "TestDrawerFragmentActivity";
TestFragment1 mTestFragment1;
TestFragment2 mTestFragment2;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -66,7 +80,7 @@ public class TestDrawerFragmentActivity extends DrawerFragmentActivity {
super.onItemClick(parent, view, position, id);
switch (position) {
case 0 : {
- Toast.makeText(getContext(), "0", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getApplicationContext(), "0", Toast.LENGTH_SHORT).show();
//LogUtils.d(TAG, "MenuItem 1");
showFragment(mTestFragment1);
break;
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestViewPageFragment.java b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestViewPageFragment.java
index 290ee9d..a7253c8 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestViewPageFragment.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/unittests/TestViewPageFragment.java
@@ -5,6 +5,7 @@ package cc.winboll.studio.libaes.unittests;
* @Date 2024/07/16 01:35:56
* @Describe TestViewPageFragment
*/
+import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -17,12 +18,17 @@ import androidx.viewpager.widget.ViewPager;
import cc.winboll.studio.libaes.ImagePagerAdapter;
import cc.winboll.studio.libaes.R;
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
+import cc.winboll.studio.libappbase.LogView;
+import com.hjq.toast.ToastUtils;
import java.util.ArrayList;
import java.util.List;
public class TestViewPageFragment extends Fragment implements ViewPager.OnPageChangeListener, View.OnClickListener {
public static final String TAG = "TestViewPageFragment";
+
+ Context mContext;
+ LogView mLogView;
private ViewPager viewPager;
private List views; //用来存放放进ViewPager里面的布局
@@ -36,6 +42,10 @@ public class TestViewPageFragment extends Fragment implements ViewPager.OnPageCh
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_viewpage, container, false);
+ mContext = getActivity();
+
+ mLogView = mView.findViewById(R.id.logview);
+ mLogView.start();
//viewPager = findViewById(R.id.activitymainViewPager1);
initData();
@@ -60,12 +70,13 @@ public class TestViewPageFragment extends Fragment implements ViewPager.OnPageCh
initPoint();//初始化页面下方的点
viewPager.setOnPageChangeListener(this);
initAOHPCTCSeekBar();
+ initAOHPCTCSeekBar2();
}
//初始化所要显示的布局
void initData() {
ViewPager viewPager = mView.findViewById(R.id.fragmentviewpageViewPager1);
- LayoutInflater inflater = LayoutInflater.from(getActivity());
+ LayoutInflater inflater = LayoutInflater.from(mContext);
View view1 = inflater.inflate(R.layout.viewpage_atickprogressbar, viewPager, false);
View view2 = inflater.inflate(R.layout.viewpage_acard, viewPager, false);
View view3 = inflater.inflate(R.layout.viewpage_aohpctccard, viewPager, false);
@@ -185,14 +196,31 @@ public class TestViewPageFragment extends Fragment implements ViewPager.OnPageCh
}
void initAOHPCTCSeekBar() {
- AOHPCTCSeekBar seekbar = mView.findViewById(R.id.fragmentviewpageAOHPCTCSeekBar1);
- seekbar.setThumb(getActivity().getDrawable(R.drawable.ic_launcher));
- seekbar.setThumbOffset(10);
+ AOHPCTCSeekBar seekbar = views.get(3).findViewById(R.id.fragmentviewpageAOHPCTCSeekBar1);
+ seekbar.setThumb(mContext.getDrawable(R.drawable.ic_launcher));
+ //seekbar.setThumbOffset(200);
+ //seekbar.setThumbOffset(1);
+ seekbar.setBlurRightDP(50);
seekbar.setOnOHPCListener(new AOHPCTCSeekBar.OnOHPCListener() {
@Override
public void onOHPCommit() {
- Toast.makeText(getActivity(), "onOHPCommit ", Toast.LENGTH_SHORT).show();
+ ToastUtils.show("onOHPCommit");
+ }
+ });
+ }
+
+ void initAOHPCTCSeekBar2() {
+ AOHPCTCSeekBar seekbar = views.get(3).findViewById(R.id.fragmentviewpageAOHPCTCSeekBar2);
+ seekbar.setThumb(mContext.getDrawable(R.drawable.ic_call));
+ //seekbar.setThumbOffset(200);
+ //seekbar.setThumbOffset(1);
+ seekbar.setBlurRightDP(50);
+ seekbar.setOnOHPCListener(new AOHPCTCSeekBar.OnOHPCListener() {
+
+ @Override
+ public void onOHPCommit() {
+ ToastUtils.show("onOHPCommit 2");
}
});
}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/utils/AESThemeUtil.java b/libaes/src/main/java/cc/winboll/studio/libaes/utils/AESThemeUtil.java
index 68f3dd1..1ed8022 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/utils/AESThemeUtil.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/utils/AESThemeUtil.java
@@ -11,8 +11,8 @@ import android.view.Menu;
import android.view.MenuItem;
import androidx.appcompat.app.AppCompatActivity;
import cc.winboll.studio.libaes.R;
+import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
import cc.winboll.studio.libaes.beans.AESThemeBean;
-import cc.winboll.studio.libapputils.app.WinBollActivity;
public class AESThemeUtil {
@@ -25,7 +25,7 @@ public class AESThemeUtil {
public static int getThemeTypeID(T context) {
AESThemeBean bean = AESThemeBean.loadBean(context, AESThemeBean.class);
- return bean == null ? AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEFAULT): bean.getCurrentThemeTypeID();
+ return bean == null ? AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.AES): bean.getCurrentThemeTypeID();
}
public static void saveThemeStyleID(T context, int nThemeTypeID) {
@@ -41,9 +41,9 @@ public class AESThemeUtil {
activity.setTheme(getThemeTypeID(activity));
}
- public static void applyWinBollTheme(T activity) {
+ /*public static void applyWinBollTheme(T activity) {
activity.setTheme(getThemeTypeID(activity.getApplicationContext()));
- }
+ }*/
public static void applyAppTheme(Activity activity, AESThemeBean.ThemeType themeType) {
activity.setTheme(AESThemeBean.getThemeStyleID(themeType));
@@ -53,9 +53,9 @@ public class AESThemeUtil {
activity.setTheme(AESThemeBean.getThemeStyleID(themeType));
}
- public static void applyWinBollTheme(Activity activity, AESThemeBean.ThemeType themeType) {
+ /*public static void applyWinBollTheme(Activity activity, AESThemeBean.ThemeType themeType) {
activity.setTheme(AESThemeBean.getThemeStyleID(themeType));
- }
+ }*/
public static void inflateMenu(T activity, Menu menu) {
activity.getMenuInflater().inflate(R.menu.toolbar_apptheme, menu);
@@ -65,9 +65,9 @@ public class AESThemeUtil {
activity.getMenuInflater().inflate(R.menu.toolbar_apptheme, menu);
}
- public static void inflateWinBollMenu(T activity, Menu menu) {
+ /*public static void inflateWinBollMenu(T activity, Menu menu) {
activity.getMenuInflater().inflate(R.menu.toolbar_apptheme, menu);
- }
+ }*/
public static boolean onAppThemeItemSelected(T activity, MenuItem item) {
int nThemeStyleID;
@@ -92,7 +92,7 @@ public class AESThemeUtil {
saveThemeStyleID(activity, nThemeStyleID);
return true;
} else if (R.id.item_defaulttheme == item.getItemId()) {
- nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEFAULT);
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.AES);
saveThemeStyleID(activity, nThemeStyleID);
return true;
}
@@ -123,7 +123,7 @@ public class AESThemeUtil {
saveThemeStyleID(activity, nThemeStyleID);
return true;
} else if (R.id.item_defaulttheme == item.getItemId()) {
- nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEFAULT);
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.AES);
saveThemeStyleID(activity, nThemeStyleID);
return true;
}
@@ -131,7 +131,7 @@ public class AESThemeUtil {
return false;
}
- public static boolean onWinBollThemeItemSelected(T activity, MenuItem item) {
+ public static boolean onWinBollThemeItemSelected(T activity, MenuItem item) {
int nThemeStyleID;
if (R.id.item_depththeme == item.getItemId()) {
nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEPTH);
@@ -154,7 +154,38 @@ public class AESThemeUtil {
saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
return true;
} else if (R.id.item_defaulttheme == item.getItemId()) {
- nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEFAULT);
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.AES);
+ saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean onWinBollThemeItemSelected(T activity, MenuItem item) {
+ int nThemeStyleID;
+ if (R.id.item_depththeme == item.getItemId()) {
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.DEPTH);
+ saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
+ return true;
+ } else if (R.id.item_skytheme == item.getItemId()) {
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.SKY);
+ saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
+ return true;
+ } else if (R.id.item_goldentheme == item.getItemId()) {
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.GOLDEN);
+ saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
+ return true;
+ } else if (R.id.item_memortheme == item.getItemId()) {
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.MEMOR);
+ saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
+ return true;
+ } else if (R.id.item_taotheme == item.getItemId()) {
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.TAO);
+ saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
+ return true;
+ } else if (R.id.item_defaulttheme == item.getItemId()) {
+ nThemeStyleID = AESThemeBean.getThemeStyleID(AESThemeBean.ThemeType.AES);
saveThemeStyleID(activity.getApplicationContext(), nThemeStyleID);
return true;
}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/utils/AppVersionUtils.java b/libaes/src/main/java/cc/winboll/studio/libaes/utils/AppVersionUtils.java
new file mode 100644
index 0000000..f684626
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/utils/AppVersionUtils.java
@@ -0,0 +1,162 @@
+package cc.winboll.studio.libaes.utils;
+
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2024/08/12 14:45:35
+ * @Describe 应用版本工具集
+ */
+import cc.winboll.studio.libappbase.LogUtils;
+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) {
+ LogUtils.d(TAG, String.format("isHasNewVersion2\nszCurrentName : %s\nszNextName : %s", szCurrentName, 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) {
+ LogUtils.d(TAG, String.format("isHasNewStageReleaseVersion\nszCurrentName : %s\nszNextName : %s", szCurrentName, 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) {
+ if (szCurrentCode == null || szCurrentCode.equals("") || szNextCode == null || szNextCode.equals("")) {
+ LogUtils.d(TAG, String.format("checkNewVersion unexpected parameters:\nszCurrentCode : %s\nszNextCode : %s", szCurrentCode, szNextCode));
+ return false;
+ }
+ 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) {
+ LogUtils.d(TAG, String.format("getCodeInPackageName apkName : %s", 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();
+ LogUtils.d(TAG, String.format("version is %s", version));
+ return version;
+ //System.out.println("Version number: " + version); // 输出:7.0.0
+ }
+ LogUtils.d(TAG, String.format("No result."));
+ 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 "";
+ }
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/views/AOHPCTCSeekBar.java b/libaes/src/main/java/cc/winboll/studio/libaes/views/AOHPCTCSeekBar.java
index fc17539..22344b8 100644
--- a/libaes/src/main/java/cc/winboll/studio/libaes/views/AOHPCTCSeekBar.java
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/views/AOHPCTCSeekBar.java
@@ -6,24 +6,30 @@ package cc.winboll.studio.libaes.views;
* @Describe AOneHundredPercantClickToCommitSeekBar
*/
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.SeekBar;
+import cc.winboll.studio.libappbase.LogUtils;
public class AOHPCTCSeekBar extends SeekBar {
public static final String TAG = "AOHPCTCSeekBar";
- // 可开始拉动的起始位置(百分比值)
- static final int ENABLE_POST_PERCENT_X = 20;
- // 最小拉动值,滑块拉动值要超过这个值,确定事件才会提交。
- static final int TO_MIN_VALUE = 15;
+ volatile int thumbWidth = 1;
+ volatile int progressBarWidth = 1;
+ // 设置按钮模糊右边边缘像素
+ volatile int blurRightDP = 1;
+ // 是否从起点拉动的标志
+ volatile boolean isStartSeek = false;
+
// 外部接口对象,确定事件提交会调用该对象的方法
OnOHPCListener mOnOHPCListener;
- // 是否从起点拉动的标志
- boolean mIsStartTo = false;
- // 拉动的滑动值
- int mnTo = 0;
+
+
+ public void setBlurRightDP(int blurRight) {
+ this.blurRightDP = blurRight;
+ }
public void setOnOHPCListener(OnOHPCListener listener) {
mOnOHPCListener = listener;
@@ -35,83 +41,68 @@ public class AOHPCTCSeekBar extends SeekBar {
public AOHPCTCSeekBar(Context context) {
super(context);
+ initView(context);
}
public AOHPCTCSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
-
- //LogUtils.d(TAG, "AOHPCTCSeekBar(...)");
-
- // 获得TypedArray
- //TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AToolbar);
- // 获得attrs.xml里面的属性值,格式为:名称_属性名,后面是默认值
- //int colorBackgroud = a.getColor(R.styleable.ACard_backgroudColor, context.getColor(R.color.colorACardBackgroung));
- //int centerColor = a.getColor(R.styleable.AToolbar_centerColor, context.getColor(R.color.colorAToolbarCenterColor));
- //int endColor = a.getColor(R.styleable.AToolbar_endColor, context.getColor(R.color.colorAToolbarEndColor));
- //float tSize = a.getDimension(R.styleable.CustomView_tSize, 35);
- //p.setColor(tColor);
- //p.setTextSize(tSize);
- //Drawable drawable = context.getDrawable(R.drawable.frame_atoolbar);
-
- //setBackground(context.getDrawable(R.drawable.acard_frame_main));
-
- // 返回一个绑定资源结束的信号给资源
- //a.recycle();
+ initView(context);
}
public AOHPCTCSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ initView(context);
}
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
+ void initView(Context context) {
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
- //LogUtils.d(TAG, "ACTION_DOWN");
- // 有效的拖动起始位置(ENABLE_POST_PERCENT_X)%
- int nEnablePostX = ((getRight() - getLeft()) * ENABLE_POST_PERCENT_X / 100) + getLeft();
-
- if ((getLeft() < event.getX())
- && (event.getX() < nEnablePostX)) {
- //LogUtils.d(TAG, "event.getX() is " + Float.toString(event.getX()));
- mIsStartTo = true;
- return super.dispatchTouchEvent(event);
- }
- if (!mIsStartTo) {
- resetView();
- return false;
+ if (thumbWidth + blurRightDP > event.getX() && event.getX() > 0) {
+ getParent().requestDisallowInterceptTouchEvent(true);
+ isStartSeek = true;
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
- //LogUtils.d(TAG, "ACTION_MOVE");
- if (mIsStartTo) {
- mnTo++;
+ if (isStartSeek) {
+ super.dispatchTouchEvent(event);
}
- } else if (event.getAction() == MotionEvent.ACTION_UP) {
- //LogUtils.d(TAG, Integer.toString(getProgress()));
- // 提交100%确定事件
- if ((getProgress() == 100) && (mnTo > TO_MIN_VALUE)) {
- //LogUtils.d(TAG, "Commit mnTo is " + Integer.toString(mnTo));
+ } else if (event.getAction() == MotionEvent.ACTION_UP
+ || event.getAction() == MotionEvent.ACTION_CANCEL) {
+ getParent().requestDisallowInterceptTouchEvent(false);
+ if (getProgress() == progressBarWidth) {
mOnOHPCListener.onOHPCommit();
- //resetView();
- //return true;
}
- resetView();
- return false;
+ // 重置控件状态
+ setProgress(0);
+ isStartSeek = false;
}
- //LogUtils.d(TAG, "dispatchTouchEvent End");
- return super.dispatchTouchEvent(event);
+ return true;
}
- // 重置控件状态
- //
- void resetView() {
- setProgress(0);
- mnTo = 0;
- mIsStartTo = false;
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ //int height = MeasureSpec.getSize(heightMeasureSpec);
+ //LogUtils.d(TAG, String.format("width %d height %d", width, height));
+
+ // 获取SeekBar的图标宽度
+ Drawable thumbDrawable = getThumb();
+ if (thumbDrawable != null) {
+ // 获取图标宽度
+ thumbWidth = thumbDrawable.getIntrinsicWidth();
+ }
+
+ // 获取进度条宽度
+ progressBarWidth = width;
+
+ //LogUtils.d(TAG, String.format("thumbWidth %d progressBarWidth %d", thumbWidth, progressBarWidth));
+
+ // 设置图标位置
+ setThumbOffset(0);
+ // 设置进度条刻度
+ setMax(progressBarWidth);
}
}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/APPInfo.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/APPInfo.java
new file mode 100644
index 0000000..66a53e6
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/APPInfo.java
@@ -0,0 +1,143 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/01/20 14:19:02
+ * @Describe 应用信息类
+ */
+import cc.winboll.studio.libaes.R;
+import java.io.Serializable;
+
+public class APPInfo implements Serializable {
+
+ public static final String TAG = "APPInfo";
+
+ // 应用名称
+ String appName;
+ // 应用图标
+ int appIcon;
+ // 应用描述
+ String appDescription;
+ // 应用Git仓库地址
+ String appGitName;
+ // 应用Git仓库拥有者
+ String appGitOwner;
+ // 应用Git仓库分支
+ String appGitAPPBranch;
+ // 应用Git仓库子项目文件夹
+ String appGitAPPSubProjectFolder;
+ // 应用主页
+ String appHomePage;
+ // 应用包名称
+ String appAPKName;
+ // 应用包存储文件夹名称
+ String appAPKFolderName;
+
+ public APPInfo(String appName, int appIcon, String appDescription, String appGitName, String appGitOwner, String appGitAPPBranch, String appGitAPPSubProjectFolder, String appHomePage, String appAPKName, String appAPKFolderName) {
+ this.appName = appName;
+ this.appIcon = appIcon;
+ this.appDescription = appDescription;
+ this.appGitName = appGitName;
+ this.appGitOwner = appGitOwner;
+ this.appGitAPPBranch = appGitAPPBranch;
+ this.appGitAPPSubProjectFolder = appGitAPPSubProjectFolder;
+ this.appHomePage = appHomePage;
+ this.appAPKName = appAPKName;
+ this.appAPKFolderName = appAPKFolderName;
+ }
+
+ public APPInfo() {
+ String szBranchName = "app";
+ this.appName = "APP";
+ this.appIcon = R.drawable.ic_launcher;
+ this.appDescription = "APP Description";
+ this.appGitName = "APP";
+ this.appGitOwner = "Studio";
+ this.appGitAPPBranch = szBranchName;
+ this.appGitAPPSubProjectFolder = szBranchName;
+ this.appHomePage = "https://www.winboll.cc/studio/details.php?app=APP";
+ this.appAPKName = "APP";
+ this.appAPKFolderName = "APP";
+ }
+
+ public void setAppGitOwner(String appGitOwner) {
+ this.appGitOwner = appGitOwner;
+ }
+
+ public String getAppGitOwner() {
+ return appGitOwner;
+ }
+
+ public void setAppGitAPPBranch(String appGitAPPBranch) {
+ this.appGitAPPBranch = appGitAPPBranch;
+ }
+
+ public String getAppGitAPPBranch() {
+ return appGitAPPBranch;
+ }
+
+ public void setAppGitAPPSubProjectFolder(String appGitAPPSubProjectFolder) {
+ this.appGitAPPSubProjectFolder = appGitAPPSubProjectFolder;
+ }
+
+ public String getAppGitAPPSubProjectFolder() {
+ return appGitAPPSubProjectFolder;
+ }
+
+ public void setAppIcon(int appIcon) {
+ this.appIcon = appIcon;
+ }
+
+ public int getAppIcon() {
+ return appIcon;
+ }
+
+ public void setAppDescription(String appDescription) {
+ this.appDescription = appDescription;
+ }
+
+ public String getAppDescription() {
+ return appDescription;
+ }
+
+ public void setAppAPKFolderName(String appAPKFolderName) {
+ this.appAPKFolderName = appAPKFolderName;
+ }
+
+ public String getAppAPKFolderName() {
+ return appAPKFolderName;
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public String getAppName() {
+ return appName;
+ }
+
+ public void setAppGitName(String appGitName) {
+ this.appGitName = appGitName;
+ }
+
+ public String getAppGitName() {
+ return appGitName;
+ }
+
+ public void setAppHomePage(String appHomePage) {
+ this.appHomePage = appHomePage;
+ }
+
+ public String getAppHomePage() {
+ return appHomePage;
+ }
+
+ public void setAppAPKName(String appAPKName) {
+ this.appAPKName = appAPKName;
+ }
+
+ public String getAppAPKName() {
+ return appAPKName;
+ }
+}
+
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/AboutView.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/AboutView.java
new file mode 100644
index 0000000..3628113
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/AboutView.java
@@ -0,0 +1,392 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/24 15:08:52
+ * @Describe WinBoll应用介绍视图
+ */
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.net.Uri;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import cc.winboll.studio.libaes.R;
+import cc.winboll.studio.libaes.utils.AppVersionUtils;
+import cc.winboll.studio.libappbase.GlobalApplication;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog;
+import cc.winboll.studio.libapputils.utils.PrefUtils;
+import com.hjq.toast.ToastUtils;
+import java.io.IOException;
+import mehdi.sakout.aboutpage.AboutPage;
+import mehdi.sakout.aboutpage.Element;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Credentials;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+public class AboutView extends LinearLayout {
+
+ public static final String TAG = "AboutView";
+
+ public static final int MSG_APPUPDATE_CHECKED = 0;
+
+ Context mContext;
+ APPInfo mAPPInfo;
+
+ WinBollServiceStatusView mWinBollServiceStatusView;
+ OnRequestDevUserInfoAutofillListener mOnRequestDevUserInfoAutofillListener;
+ String mszAppName = "";
+ String mszAppAPKFolderName = "";
+ String mszAppAPKName = "";
+ String mszAppGitName = "";
+ String mszAppVersionName = "";
+ String mszCurrentAppPackageName = "";
+ volatile String mszNewestAppPackageName = "";
+ String mszAppDescription = "";
+ String mszHomePage = "";
+ String mszGitea = "";
+ int mnAppIcon = 0;
+ String mszWinBollServerHost;
+ String mszReleaseAPKName;
+ EditText metDevUserName;
+ EditText metDevUserPassword;
+
+ public AboutView(Context context, APPInfo appInfo) {
+ super(context);
+ mContext = context;
+
+ setAPPInfo(appInfo);
+ initView(context);
+ }
+
+ public AboutView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+
+ initView(context, attrs);
+ }
+
+ public void setAPPInfo(APPInfo appInfo) {
+ mAPPInfo = appInfo;
+ }
+
+ APPInfo createAppInfo(Context context, AttributeSet attrs) {
+ APPInfo appInfo = new APPInfo();
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AboutView);
+ appInfo.setAppName(typedArray.getString(R.styleable.AboutView_app_name));
+ appInfo.setAppAPKFolderName(typedArray.getString(R.styleable.AboutView_app_apkfoldername));
+ appInfo.setAppAPKName(typedArray.getString(R.styleable.AboutView_app_apkname));
+ appInfo.setAppGitName(typedArray.getString(R.styleable.AboutView_app_gitname));
+ appInfo.setAppGitOwner(typedArray.getString(R.styleable.AboutView_app_gitowner));
+ appInfo.setAppGitAPPBranch(typedArray.getString(R.styleable.AboutView_app_gitappbranch));
+ appInfo.setAppGitAPPSubProjectFolder(typedArray.getString(R.styleable.AboutView_app_gitappsubprojectfolder));
+ appInfo.setAppDescription(typedArray.getString(R.styleable.AboutView_appdescription));
+ appInfo.setAppIcon(typedArray.getResourceId(R.styleable.AboutView_appicon, R.drawable.ic_winboll));
+ // 返回一个绑定资源结束的信号给资源
+ typedArray.recycle();
+ return appInfo;
+ }
+
+ void initView(Context context) {
+ mszAppName = mAPPInfo.getAppName();
+ mszAppAPKFolderName = mAPPInfo.getAppAPKFolderName();
+ mszAppAPKName = mAPPInfo.getAppAPKName();
+ mszAppGitName = mAPPInfo.getAppGitName();
+ mszAppDescription = mAPPInfo.getAppDescription();
+ mnAppIcon = mAPPInfo.getAppIcon();
+
+ mszWinBollServerHost = GlobalApplication.isDebuging() ? "https://dev.winboll.cc": "https://www.winboll.cc";
+
+ try {
+ mszAppVersionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ mszCurrentAppPackageName = mszAppAPKName + "_" + mszAppVersionName + ".apk";
+ mszHomePage = mszWinBollServerHost + "/studio/details.php?app=" + mszAppAPKFolderName;
+ if (mAPPInfo.getAppGitAPPBranch().equals("")) {
+ mszGitea = "https://gitea.winboll.cc/" + mAPPInfo.getAppGitOwner() + "/" + mszAppGitName;
+ } else {
+ mszGitea = "https://gitea.winboll.cc/" + mAPPInfo.getAppGitOwner() + "/" + mszAppGitName + "/src/branch/" + mAPPInfo.getAppGitAPPBranch() + "/" + mAPPInfo.getAppGitAPPSubProjectFolder();
+ }
+
+
+ if (GlobalApplication.isDebuging()) {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ View addedView = inflater.inflate(R.layout.view_about_dev, this, false);
+ LinearLayout llMain = addedView.findViewById(R.id.viewaboutdevLinearLayout1);
+ metDevUserName = addedView.findViewById(R.id.viewaboutdevEditText1);
+ metDevUserPassword = addedView.findViewById(R.id.viewaboutdevEditText2);
+ metDevUserName.setText(PrefUtils.getString(mContext, "metDevUserName", ""));
+ metDevUserPassword.setText(PrefUtils.getString(mContext, "metDevUserPassword", ""));
+ //mDevelopHostConnectionStatusView = new DevelopHostConnectionStatusView(context);
+ mWinBollServiceStatusView = addedView.findViewById(R.id.viewaboutdevWinBollServiceStatusView1);
+ mWinBollServiceStatusView.setServerHost(mszWinBollServerHost);
+ mWinBollServiceStatusView.setAuthInfo(metDevUserName.getText().toString(), metDevUserPassword.getText().toString());
+ //llMain.addView(mDevelopHostConnectionStatusView);
+ llMain.addView(createAboutPage());
+ addView(addedView);
+ } else {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ View addedView = inflater.inflate(R.layout.view_about_www, this, false);
+ LinearLayout llMain = addedView.findViewById(R.id.viewaboutwwwLinearLayout1);
+ //mDevelopHostConnectionStatusView = new DevelopHostConnectionStatusView(context);
+ mWinBollServiceStatusView = addedView.findViewById(R.id.viewaboutwwwWinBollServiceStatusView1);
+ mWinBollServiceStatusView.setServerHost(mszWinBollServerHost);
+ mWinBollServiceStatusView.setAuthInfo("", "");
+ //llMain.addView(mDevelopHostConnectionStatusView);
+ llMain.addView(createAboutPage());
+ addView(addedView);
+ }
+
+ // 初始化标题栏
+ //setSubtitle(getContext().getString(R.string.text_about));
+
+// LinearLayout llMain = findViewById(R.id.viewaboutLinearLayout1);
+// llMain.addView(createAboutPage());
+
+ // 就读取正式版应用包版本号,设置 Release 应用包文件名
+ String szReleaseAppVersionName = "";
+ try {
+ //LogUtils.d(TAG, String.format("mContext.getPackageName() %s", mContext.getPackageName()));
+ String szSubBetaSuffix = subBetaSuffix(mContext.getPackageName());
+ //LogUtils.d(TAG, String.format("szSubBetaSuffix : %s", szSubBetaSuffix));
+ szReleaseAppVersionName = mContext.getPackageManager().getPackageInfo(szSubBetaSuffix, 0).versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ mszReleaseAPKName = mszAppAPKName + "_" + szReleaseAppVersionName + ".apk";
+
+ }
+
+ void initView(Context context, AttributeSet attrs) {
+ mAPPInfo = createAppInfo(context, attrs);
+ initView(context);
+ }
+
+ public static String subBetaSuffix(String input) {
+ if (input.endsWith(".beta")) {
+ return input.substring(0, input.length() - ".beta".length());
+ }
+ return input;
+ }
+
+ android.os.Handler mHandler = new android.os.Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what) {
+ case MSG_APPUPDATE_CHECKED : {
+ /*//检查当前应用包文件名是否是测试版,如果是就忽略检查
+ if(mszCurrentAppPackageName.matches(".*_\\d+\\.\\d+\\.\\d+-beta.*\\.apk")) {
+ ToastUtils.show("APP is the beta Version. Version check ignore.");
+ return;
+ }*/
+
+// if (!AppVersionUtils.isHasNewStageReleaseVersion(mszReleaseAPKName, mszNewestAppPackageName)) {
+// ToastUtils.delayedShow("Current app is the newest.", 5000);
+// }
+ if (!AppVersionUtils.isHasNewVersion2(mszCurrentAppPackageName, mszNewestAppPackageName)) {
+ ToastUtils.show("Current app is the newest.");
+ } else {
+ String szMsg = "Current app is :\n[ " + mszCurrentAppPackageName
+ + " ]\nThe last app is :\n[ " + mszNewestAppPackageName
+ + " ]\nIs download the last app?";
+ YesNoAlertDialog.show(mContext, "Application Update Prompt", szMsg, mIsDownlaodUpdateListener);
+ }
+ break;
+ }
+ }
+ }
+ };
+
+ protected View createAboutPage() {
+ // 定义应用调试按钮
+ //
+ Element elementAppMode;
+ if (GlobalApplication.isDebuging()) {
+ elementAppMode = new Element(mContext.getString(R.string.app_normal), R.drawable.ic_winboll);
+ elementAppMode.setOnClickListener(mAppNormalOnClickListener);
+ } else {
+ elementAppMode = new Element(mContext.getString(R.string.app_debug), R.drawable.ic_winboll);
+ elementAppMode.setOnClickListener(mAppDebugOnClickListener);
+ }
+ // 定义 GitWeb 按钮
+ //
+ Element elementGitWeb = new Element(mContext.getString(R.string.gitea_home), R.drawable.ic_winboll);
+ elementGitWeb.setOnClickListener(mGitWebOnClickListener);
+ // 定义检查更新按钮
+ //
+ Element elementAppUpdate = new Element(mContext.getString(R.string.app_update), R.drawable.ic_winboll);
+ elementAppUpdate.setOnClickListener(mAppUpdateOnClickListener);
+
+ String szAppInfo = "";
+ try {
+ szAppInfo = mszAppName + " "
+ + mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName
+ + "\n" + mszAppDescription;
+ } catch (PackageManager.NameNotFoundException e) {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ View aboutPage = new AboutPage(mContext)
+ .setDescription(szAppInfo)
+ //.isRTL(false)
+ //.setCustomFont(String) // or Typeface
+ .setImage(mnAppIcon)
+ //.addItem(versionElement)
+ //.addItem(adsElement)
+ //.addGroup("Connect with us")
+ .addEmail("ZhanGSKen@AliYun.Com")
+ .addWebsite(mszHomePage)
+ .addItem(elementAppMode)
+ .addItem(elementGitWeb)
+ .addItem(elementAppUpdate)
+ //.addFacebook("the.medy")
+ //.addTwitter("medyo80")
+ //.addYoutube("UCdPQtdWIsg7_pi4mrRu46vA")
+ //.addPlayStore("com.ideashower.readitlater.pro")
+ //.addGitHub("medyo")
+ //.addInstagram("medyo80")
+ .create();
+ return aboutPage;
+ }
+
+ View.OnClickListener mAppDebugOnClickListener = new View.OnClickListener(){
+ @Override
+ public void onClick(View view) {
+ //ToastUtils.show("mAppDebugOnClickListener");
+ setApp2DebugMode(mContext);
+ }
+ };
+
+ View.OnClickListener mAppNormalOnClickListener = new View.OnClickListener(){
+ @Override
+ public void onClick(View view) {
+ //ToastUtils.show("mAppNormalOnClickListener");
+ setApp2NormalMode(mContext);
+ }
+ };
+
+ public static void setApp2DebugMode(Context context) {
+ Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
+ if (intent != null) {
+ //intent.setAction(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ GlobalApplication.setIsDebuging(true);
+
+ GlobalApplication.getWinBollActivityManager().finishAll();
+ context.startActivity(intent);
+ }
+ }
+
+ public static void setApp2NormalMode(Context context) {
+ Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
+ if (intent != null) {
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ GlobalApplication.setIsDebuging(false);
+
+ GlobalApplication.getWinBollActivityManager().finishAll();
+ context.startActivity(intent);
+ }
+ }
+
+ View.OnClickListener mGitWebOnClickListener = new View.OnClickListener(){
+ @Override
+ public void onClick(View view) {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(mszGitea));
+ mContext.startActivity(browserIntent);
+ }
+ };
+
+ View.OnClickListener mAppUpdateOnClickListener = new View.OnClickListener(){
+ @Override
+ public void onClick(View view) {
+ ToastUtils.show("Start app update checking.");
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ String szUrl = mszWinBollServerHost + "/studio/details.php?app=" + mszAppAPKFolderName;
+ // 构建包含认证信息的请求
+ String credential = "";
+ if (GlobalApplication.isDebuging()) {
+ credential = Credentials.basic(metDevUserName.getText().toString(), metDevUserPassword.getText().toString());
+ PrefUtils.saveString(mContext, "metDevUserName", metDevUserName.getText().toString());
+ PrefUtils.saveString(mContext, "metDevUserPassword", metDevUserPassword.getText().toString());
+ } else {
+ 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();
+ Call call = client.newCall(request);
+ call.enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ // 处理网络请求失败
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (!response.isSuccessful()) {
+ LogUtils.d(TAG, "Unexpected code " + response, Thread.currentThread().getStackTrace());
+ return;
+ }
+
+ try {
+ // 读取响应体作为字符串,注意这里可能需要解码
+ String text = response.body().string();
+ org.jsoup.nodes.Document doc = org.jsoup.Jsoup.parse(text);
+ LogUtils.v(TAG, doc.text());
+
+ // 使用id选择器找到具有特定id的元素
+ org.jsoup.nodes.Element elementWithId = doc.select("#LastRelease").first(); // 获取第一个匹配的元素
+
+ // 提取并打印元素的文本内容
+ mszNewestAppPackageName = elementWithId.text();
+ //ToastUtils.delayedShow(text + "\n" + mszNewestAppPackageName, 5000);
+
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_APPUPDATE_CHECKED));
+ } catch (Exception e) {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ }
+ });
+ }
+ }).start();
+ }
+ };
+
+ YesNoAlertDialog.OnDialogResultListener mIsDownlaodUpdateListener = new YesNoAlertDialog.OnDialogResultListener() {
+ @Override
+ public void onYes() {
+ String szUrl = mszWinBollServerHost + "/studio/download.php?appname=" + mszAppAPKFolderName + "&apkname=" + mszNewestAppPackageName;
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(szUrl));
+ mContext.startActivity(browserIntent);
+ }
+
+ @Override
+ public void onNo() {
+ }
+ };
+
+ public interface OnRequestDevUserInfoAutofillListener {
+ void requestAutofill(EditText etDevUserName, EditText etDevUserPassword);
+ }
+
+ public void setOnRequestDevUserInfoAutofillListener(OnRequestDevUserInfoAutofillListener l) {
+ mOnRequestDevUserInfoAutofillListener = l;
+ }
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/AssistantService.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/AssistantService.java
new file mode 100644
index 0000000..9f1e48a
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/AssistantService.java
@@ -0,0 +1,96 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/28 19:12:12
+ * @Describe 应用主要服务组件类守护进程服务组件类
+ */
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import cc.winboll.studio.libaes.winboll.WinBollClientService;
+import cc.winboll.studio.libappbase.utils.ServiceUtils;
+
+public class AssistantService extends Service {
+
+ public final static String TAG = "AssistantService";
+
+ WinBollClientServiceBean mWinBollServiceBean;
+ MyServiceConnection mMyServiceConnection;
+ volatile boolean mIsServiceRunning;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mWinBollServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
+ if (mMyServiceConnection == null) {
+ mMyServiceConnection = new MyServiceConnection();
+ }
+ // 设置运行参数
+ mIsServiceRunning = false;
+ run();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ run();
+ return START_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ mIsServiceRunning = false;
+ super.onDestroy();
+ }
+
+ //
+ // 运行服务内容
+ //
+ void run() {
+ mWinBollServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
+ if (mWinBollServiceBean.isEnable()) {
+ if (mIsServiceRunning == false) {
+ // 设置运行状态
+ mIsServiceRunning = true;
+ // 唤醒和绑定主进程
+ wakeupAndBindMain();
+ }
+ }
+ }
+
+ //
+ // 唤醒和绑定主进程
+ //
+ void wakeupAndBindMain() {
+ if (ServiceUtils.isServiceRunning(getApplicationContext(), WinBollClientService.class.getName()) == false) {
+ startForegroundService(new Intent(AssistantService.this, WinBollClientService.class));
+ }
+
+ bindService(new Intent(AssistantService.this, WinBollClientService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
+ }
+
+ //
+ // 主进程与守护进程连接时需要用到此类
+ //
+ class MyServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mWinBollServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(AssistantService.this);
+ if (mWinBollServiceBean.isEnable()) {
+ wakeupAndBindMain();
+ }
+ }
+ }
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/EWUIStatusIconDrawable.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/EWUIStatusIconDrawable.java
new file mode 100644
index 0000000..3d66468
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/EWUIStatusIconDrawable.java
@@ -0,0 +1,35 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/28 19:11:27
+ * @Describe WinBoll UI 状态图标枚举
+ */
+import cc.winboll.studio.libaes.R;
+
+public enum EWUIStatusIconDrawable {
+ NORMAL(0),
+ NEWS(1)
+ ;
+
+ static final String TAG = "WUIStatusIconDrawable";
+
+ static String[] _mlistCNName = { "正常", "新的消息" };
+
+ private int value = 0;
+ private EWUIStatusIconDrawable(int value) { //必须是private的,否则编译错误
+ this.value = value;
+ }
+
+ public static int getIconDrawableId(EWUIStatusIconDrawable drawableId) {
+ int res;
+ switch(drawableId){
+ case NEWS :
+ res = R.drawable.ic_winbollbeta;
+ break;
+ default :
+ res = R.drawable.ic_winboll;
+ }
+ return res;
+ }
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/IWinBollClientServiceBinder.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/IWinBollClientServiceBinder.java
new file mode 100644
index 0000000..eaf40d5
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/IWinBollClientServiceBinder.java
@@ -0,0 +1,17 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/28 19:08:45
+ * @Describe WinBollService 服务 Binder。
+ */
+import android.graphics.drawable.Drawable;
+
+public interface IWinBollClientServiceBinder {
+
+ public static final String TAG = "IWinBollClientServiceBinder";
+
+ public WinBollClientService getService();
+
+ public Drawable getCurrentStatusIconDrawable();
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollClientService.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollClientService.java
new file mode 100644
index 0000000..756e885
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollClientService.java
@@ -0,0 +1,192 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/28 19:06:54
+ * @Describe WinBoll 客户端服务
+ */
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.graphics.drawable.Drawable;
+import android.os.IBinder;
+import cc.winboll.studio.libaes.winboll.AssistantService;
+import cc.winboll.studio.libappbase.GlobalApplication;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libappbase.utils.ServiceUtils;
+import cc.winboll.studio.libapputils.utils.PrefUtils;
+import com.hjq.toast.ToastUtils;
+
+public class WinBollClientService extends Service implements IWinBollClientServiceBinder {
+
+ public static final String TAG = "WinBollClientService";
+
+ WinBollClientServiceBean mWinBollClientServiceBean;
+ MyServiceConnection mMyServiceConnection;
+ volatile boolean mIsWinBollClientThreadRunning;
+ volatile boolean mIsEnableService;
+ volatile WinBollClientThread mWinBollClientThread;
+
+ public boolean isWinBollClientThreadRunning() {
+ return mIsWinBollClientThreadRunning;
+ }
+
+ @Override
+ public WinBollClientService getService() {
+ return WinBollClientService.this;
+ }
+
+ @Override
+ public Drawable getCurrentStatusIconDrawable() {
+ return mIsWinBollClientThreadRunning ?
+ getDrawable(EWUIStatusIconDrawable.getIconDrawableId(EWUIStatusIconDrawable.NORMAL))
+ : getDrawable(EWUIStatusIconDrawable.getIconDrawableId(EWUIStatusIconDrawable.NEWS));
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ //ToastUtils.show("onCreate");
+ super.onCreate();
+ mWinBollClientThread = null;
+ mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
+ mIsEnableService = mWinBollClientServiceBean.isEnable();
+
+ if (mMyServiceConnection == null) {
+ mMyServiceConnection = new MyServiceConnection();
+ }
+
+ // 由系统启动时,应用可以通过下面函数实例化实际服务进程。
+ runMainThread();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ //ToastUtils.show("onStartCommand");
+ // 由应用 Intent 启动时,应用可以通过下面函数实例化实际服务进程。
+ runMainThread();
+
+ // 返回运行参数持久化存储后,服务状态控制参数
+ // 无论 Intent 传入如何,服务状态一直以持久化存储后的参数控制,
+ // PS: 另外当然可以通过 Intent 传入的指标来修改 mWinBollServiceBean,
+ // 不过本服务的应用方向会变得繁琐,
+ // 现阶段只要满足手机端启动与停止本服务,WinBoll 客户端实例运行在手机端就可以了。
+ return mIsEnableService ? Service.START_STICKY: super.onStartCommand(intent, flags, startId);
+ }
+
+ synchronized void runMainThread() {
+ if (mWinBollClientThread == null) {
+ //ToastUtils.show("runMainThread()");
+ mWinBollClientThread = new WinBollClientThread();
+ mWinBollClientThread.start();
+ }
+ }
+
+ void syncWinBollClientThreadStatus() {
+ mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
+ mIsEnableService = mWinBollClientServiceBean.isEnable();
+ LogUtils.d(TAG, String.format("mIsEnableService %s", mIsEnableService));
+ }
+
+
+ // 唤醒和绑定守护进程
+ //
+ void wakeupAndBindAssistant() {
+ if (ServiceUtils.isServiceRunning(getApplicationContext(), AssistantService.class.getName()) == false) {
+ startService(new Intent(WinBollClientService.this, AssistantService.class));
+ //LogUtils.d(TAG, "call wakeupAndBindAssistant() : Binding... AssistantService");
+ bindService(new Intent(WinBollClientService.this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
+ }
+ }
+
+ // 主进程与守护进程连接时需要用到此类
+ //
+ private class MyServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(WinBollClientService.this);
+ if (mWinBollClientServiceBean.isEnable()) {
+ // 唤醒守护进程
+ wakeupAndBindAssistant();
+ }
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ //ToastUtils.show("onDestroy");
+ }
+
+ @Override
+ public void onStart(Intent intent, int startId) {
+ super.onStart(intent, startId);
+ }
+
+ void setWinBollServiceEnableStatus(boolean isEnable) {
+ WinBollClientServiceBean bean = WinBollClientServiceBean.loadWinBollClientServiceBean(this);
+ bean.setIsEnable(isEnable);
+ WinBollClientServiceBean.saveWinBollServiceBean(this, bean);
+ }
+
+ boolean getWinBollServiceEnableStatus(Context context) {
+ mWinBollClientServiceBean = WinBollClientServiceBean.loadWinBollClientServiceBean(context);
+ return mWinBollClientServiceBean.isEnable();
+ }
+
+ /*public interface OnServiceStatusChangeListener {
+ void onServerStatusChange(boolean isServiceAlive);
+ }
+
+ public void setOnServerStatusChangeListener(OnServiceStatusChangeListener l) {
+ mOnServerStatusChangeListener = l;
+ }*/
+
+ class WinBollClientThread extends Thread {
+ @Override
+ public void run() {
+ super.run();
+ LogUtils.d(TAG, "run syncWinBollClientThreadStatus");
+ syncWinBollClientThreadStatus();
+ if (mIsEnableService) {
+ if (mIsWinBollClientThreadRunning == false) {
+ // 设置运行状态
+ mIsWinBollClientThreadRunning = true;
+ LogUtils.d(TAG, "WinBollClientThread run()");
+
+ // 唤醒守护进程
+ //wakeupAndBindAssistant();
+
+ while (mIsEnableService) {
+ // 显示运行状态
+ WinBollServiceStatusView.startConnection();
+ LogUtils.d(TAG, String.format("while mIsEnableService is %s", mIsEnableService));
+
+ try {
+ Thread.sleep(10 * 1000);
+ } catch (InterruptedException e) {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ syncWinBollClientThreadStatus();
+ }
+
+ // 服务进程退出, 重置进程运行状态
+ WinBollServiceStatusView.stopConnection();
+ mIsWinBollClientThreadRunning = false;
+ mWinBollClientThread = null;
+ }
+ }
+ }
+ }
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollClientServiceBean.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollClientServiceBean.java
new file mode 100644
index 0000000..271f1e0
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollClientServiceBean.java
@@ -0,0 +1,78 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/28 19:05:15
+ * @Describe WinBollService 运行参数配置
+ */
+import android.content.Context;
+import android.util.JsonReader;
+import android.util.JsonWriter;
+import cc.winboll.studio.libappbase.BaseBean;
+import java.io.IOException;
+
+public class WinBollClientServiceBean extends BaseBean {
+
+ public static final String TAG = "WinBollClientServiceBean";
+
+ volatile boolean isEnable;
+
+ public WinBollClientServiceBean() {
+ isEnable = false;
+ }
+
+ public void setIsEnable(boolean isEnable) {
+ this.isEnable = isEnable;
+ }
+
+ public boolean isEnable() {
+ return isEnable;
+ }
+
+ @Override
+ public String getName() {
+ return WinBollClientServiceBean.class.getName();
+ }
+
+ @Override
+ public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
+ super.writeThisToJsonWriter(jsonWriter);
+ WinBollClientServiceBean bean = this;
+ jsonWriter.name("isEnable").value(bean.isEnable());
+ }
+
+ @Override
+ public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
+ if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
+ if (name.equals("isEnable")) {
+ setIsEnable(jsonReader.nextBoolean());
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
+ jsonReader.beginObject();
+ while (jsonReader.hasNext()) {
+ String name = jsonReader.nextName();
+ if (!initObjectsFromJsonReader(jsonReader, name)) {
+ jsonReader.skipValue();
+ }
+ }
+ // 结束 JSON 对象
+ jsonReader.endObject();
+ return this;
+ }
+
+ public static WinBollClientServiceBean loadWinBollClientServiceBean(Context context) {
+ WinBollClientServiceBean bean = WinBollClientServiceBean.loadBean(context, WinBollClientServiceBean.class);
+ return bean == null ? new WinBollClientServiceBean() : bean;
+ }
+
+ public static boolean saveWinBollServiceBean(WinBollClientService service, WinBollClientServiceBean bean) {
+ return WinBollClientServiceBean.saveBean(service, bean);
+ }
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollMail.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollMail.java
new file mode 100644
index 0000000..3806106
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollMail.java
@@ -0,0 +1,22 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/28 19:13:20
+ * @Describe WinBoll 邮件服务
+ */
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class WinBollMail extends Service {
+
+ public static final String TAG = "WinBollMail";
+
+ @Override
+ public IBinder onBind(Intent intent) {
+
+ return null;
+ }
+
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollServerConnectionThread.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollServerConnectionThread.java
new file mode 100644
index 0000000..25ecd21
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollServerConnectionThread.java
@@ -0,0 +1,106 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/29 15:57:28
+ * @Describe WinBoll 服务器服务情况测试访问进程。
+ */
+import cc.winboll.studio.libappbase.LogUtils;
+import java.io.IOException;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Credentials;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+// 新增自定义回调接口
+interface TextCallback {
+ void onSuccess(String text);
+ void onFailure(Exception e);
+}
+
+public class WinBollServerConnectionThread extends Thread {
+
+ public static final String TAG = "WinBollClientService";
+
+ private final String url;
+ private final String username;
+ private final String password;
+ private final int connectTimeout;
+ private final int readTimeout;
+ private final int maxRetries;
+ private final TextCallback callback; // 新增回调成员变量
+
+ // 新增带回调的构造函数
+ public WinBollServerConnectionThread(String url, String username, String password, TextCallback callback) {
+ this(url, username, password, 10000, 10000, 5, callback);
+ }
+
+ // 修改原有构造函数,添加回调参数
+ public WinBollServerConnectionThread(String url, String username, String password,
+ int connectTimeout, int readTimeout, int maxRetries, TextCallback callback) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ this.connectTimeout = connectTimeout;
+ this.readTimeout = readTimeout;
+ this.maxRetries = maxRetries;
+ this.callback = callback;
+ }
+
+ @Override
+ public void run() {
+ LogUtils.d(TAG, String.format("run() url %s\nusername %s\npassword %s", url, username, password));
+ String credential = Credentials.basic(username, password);
+ LogUtils.d(TAG, String.format("credential %s", credential));
+
+ OkHttpClient client = new OkHttpClient();
+ Request request = new Request.Builder()
+ .url(url)
+ .header("Accept", "text/plain")
+ .header("Authorization", credential)
+ .build();
+
+ Call call = client.newCall(request);
+ call.enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ // 优先调用自定义回调
+ if (callback != null) {
+ callback.onFailure(e);
+ } else {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (!response.isSuccessful()) {
+ if (callback != null) {
+ callback.onFailure(new Exception("Unexpected code " + response));
+ } else {
+ LogUtils.d(TAG, "Unexpected code " + response, Thread.currentThread().getStackTrace());
+ }
+ return;
+ }
+
+ try {
+ String text = response.body().string();
+ // 优先调用自定义回调
+ if (callback != null) {
+ callback.onSuccess(text);
+ } else {
+ LogUtils.d(TAG, text);
+ }
+ } catch (Exception e) {
+ if (callback != null) {
+ callback.onFailure(e);
+ } else {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollServiceStatusView.java b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollServiceStatusView.java
new file mode 100644
index 0000000..4954177
--- /dev/null
+++ b/libaes/src/main/java/cc/winboll/studio/libaes/winboll/WinBollServiceStatusView.java
@@ -0,0 +1,472 @@
+package cc.winboll.studio.libaes.winboll;
+
+/**
+ * @Author ZhanGSKen@AliYun.Com
+ * @Date 2025/03/28 17:41:55
+ * @Describe WinBoll 服务主机连接状态视图
+ */
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import cc.winboll.studio.libaes.winboll.WinBollClientService;
+import cc.winboll.studio.libappbase.GlobalApplication;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libapputils.R;
+import cc.winboll.studio.libapputils.utils.PrefUtils;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+//import okhttp3.Authenticator;
+//import okhttp3.Credentials;
+//import okhttp3.OkHttpClient;
+//import okhttp3.Request;
+//import okhttp3.Response;
+//import okhttp3.Route;
+
+public class WinBollServiceStatusView extends LinearLayout {
+
+ public static final String TAG = "WinBollServiceStatusView";
+
+ public static final int MSG_CONNECTION_INFO = 0;
+ public static final int MSG_UPDATE_CONNECTION_STATUS = 1;
+
+ static WinBollServiceStatusView _WinBollServiceStatusView;
+ Context mContext;
+ //boolean mIsConnected;
+ volatile ConnectionThread mConnectionThread;
+
+ String mszServerHost;
+ WinBollClientService mWinBollService;
+ ImageView mImageView;
+ TextView mTextView;
+ WinBollServiceViewHandler mWinBollServiceViewHandler;
+ //WebView mWebView;
+ static volatile ConnectionStatus mConnectionStatus;
+ View.OnClickListener mViewOnClickListener;
+ static String _mUserName;
+ static String _mPassword;
+
+ static enum ConnectionStatus {
+ DISCONNECTED,
+ START_CONNECT,
+ CONNECTING,
+ CONNECTED;
+ };
+
+ boolean isBound = false;
+ ServiceConnection connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ IWinBollClientServiceBinder binder = (IWinBollClientServiceBinder) service;
+ mWinBollService = binder.getService();
+ isBound = true;
+ // 可以在这里调用Service的方法进行通信,比如获取数据
+ mImageView.setBackgroundDrawable(mWinBollService.getCurrentStatusIconDrawable());
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ isBound = false;
+ }
+ };
+
+ public WinBollServiceStatusView(Context context) {
+ super(context);
+ mContext = context;
+ initView();
+ }
+
+ public WinBollServiceStatusView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ initView();
+ }
+
+ public WinBollServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mContext = context;
+ initView();
+ }
+
+ public WinBollServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mContext = context;
+ initView();
+ }
+
+ ConnectionStatus getConnectionStatus() {
+ return false ?
+ ConnectionStatus.CONNECTED
+ : ConnectionStatus.DISCONNECTED;
+ }
+
+ void initView() {
+ _WinBollServiceStatusView = this;
+
+ mImageView = new ImageView(mContext);
+ setImageViewByConnection(mImageView, false);
+ mConnectionStatus = getConnectionStatus();
+ //mIsConnected = false;
+ //mWinBollServerHostConnectionStatus = WinBollServerHostConnectionStatus.DISCONNECTED;
+ //ToastUtils.show("initView()");
+
+ mViewOnClickListener = new View.OnClickListener(){
+ @Override
+ public void onClick(View v) {
+ LogUtils.d(TAG, "onClick()");
+ if (mConnectionStatus == ConnectionStatus.CONNECTED) {
+ LogUtils.d(TAG, "Click to stop service.");
+ WinBollClientServiceBean bean = WinBollClientServiceBean.loadWinBollClientServiceBean(mContext);
+ bean.setIsEnable(false);
+ WinBollClientServiceBean.saveBean(mContext, bean);
+ Intent intent = new Intent(mContext, WinBollClientService.class);
+ mContext.stopService(intent);
+ //stopConnectionThread();
+ mTextView.setText("");
+ setImageViewByConnection(mImageView, false);
+ mConnectionStatus = ConnectionStatus.DISCONNECTED;
+ } else if (mConnectionStatus == ConnectionStatus.DISCONNECTED) {
+ LogUtils.d(TAG, "Click to start service.");
+ WinBollClientServiceBean bean = WinBollClientServiceBean.loadWinBollClientServiceBean(mContext);
+ bean.setIsEnable(true);
+ WinBollClientServiceBean.saveBean(mContext, bean);
+ Intent intent = new Intent(mContext, WinBollClientService.class);
+ mContext.startService(intent);
+ //startConnectionThread();
+ }
+ }
+ };
+ setOnClickListener(mViewOnClickListener);
+ addView(mImageView);
+ mTextView = new TextView(mContext);
+ mWinBollServiceViewHandler = new WinBollServiceViewHandler(this);
+ addView(mTextView);
+ /*mWebView = new WebView(mContext);
+ mWebView.setWebViewClient(new WebViewClient() {
+ @Override
+ public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
+ // 弹出系统基本HTTP验证窗口
+ handler.proceed("username", "password");
+ }
+ });
+ addView(mWebView);*/
+ }
+
+ void checkWinBollServerStatusAndUpdateCurrentView() {
+ LogUtils.d(TAG, "checkWinBollServerStatusAndUpdateCurrentView()");
+ /*if (getConnectionStatus() == ConnectionStatus.CONNECTED) {
+ mConnectionStatus = ConnectionStatus.CONNECTED;
+ } else {
+ mConnectionStatus = ConnectionStatus.DISCONNECTED;
+ }*/
+ }
+
+ public void setServerHost(String szWinBollServerHost) {
+ mszServerHost = szWinBollServerHost;
+ }
+
+ public void setAuthInfo(String username, String password) {
+ _mUserName = username;
+ _mPassword = password;
+ }
+
+ void setImageViewByConnection(ImageView imageView, boolean isConnected) {
+ //mIsConnected = isConnected;
+ // 获取vector drawable
+ Drawable drawable = mContext.getDrawable(isConnected ? R.drawable.ic_dev_connected : R.drawable.ic_dev_disconnected);
+ if (drawable != null) {
+ imageView.setImageDrawable(drawable);
+ }
+ }
+
+ TextCallback apiTextCallback = new TextCallback() {
+ @Override
+ public void onSuccess(String text) {
+ // 处理成功响应
+ LogUtils.d(TAG, text);
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ // 处理失败情况
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ };
+
+ TextCallback cipTextCallback = new TextCallback() {
+ @Override
+ public void onSuccess(String text) {
+ // 处理成功响应
+ LogUtils.d(TAG, text);
+ LogUtils.d(TAG, "Develop Host Connection IP is : " + text);
+ mConnectionStatus = ConnectionStatus.CONNECTED;
+ // 获取当前时间
+ LocalDateTime now = LocalDateTime.now();
+ // 定义时间格式
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
+ // 按照指定格式格式化时间并输出
+ String formattedDateTime = now.format(formatter);
+ String msg = "ClientIP<" + formattedDateTime + ">: " + text;
+ mWinBollServiceViewHandler.postMessageText(msg);
+ mWinBollServiceViewHandler.postMessageConnectionStatus(true);
+
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ // 处理失败情况
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ // 处理网络请求失败
+ setImageViewByConnection(mImageView, false);
+ mWinBollServiceViewHandler.postMessageText(e.getMessage());
+ mWinBollServiceViewHandler.postMessageConnectionStatus(false);
+ }
+ };
+
+ public void requestAPIWithBasicAuth() {
+ String targetUrl = "https://" + (GlobalApplication.isDebuging() ?"dev.winboll": "winboll") + ".cc/api/"; // 替换为实际测试的URL
+ requestWithBasicAuth(targetUrl, apiTextCallback);
+ }
+
+ public void requestCIPWithBasicAuth() {
+ String targetUrl = mszServerHost + "/cip/?simple=true";
+ requestWithBasicAuth(targetUrl, cipTextCallback);
+ }
+
+ public void requestWithBasicAuth(String targetUrl, TextCallback callback) {
+ String username = "";
+ String password = "";
+ if (GlobalApplication.isDebuging()) {
+ username = PrefUtils.getString(mContext, "metDevUserName", "");
+ password = PrefUtils.getString(mContext, "metDevUserPassword", "");
+ } else {
+ username = "WinBoll";
+ password = "WinBollPowerByZhanGSKen";
+ }
+ LogUtils.d(TAG, String.format("Connection Start. targetUrl %s", targetUrl));
+ WinBollServerConnectionThread thread = new WinBollServerConnectionThread(
+ targetUrl,
+ username,
+ password,
+ cipTextCallback
+ );
+ thread.start();
+ }
+
+ /*void requestWithBasicAuth(final WinBollServiceViewHandler textViewHandler, String targetUrl, final String username, final String password) {
+ // 用户名和密码,替换为实际的认证信息
+ //String username = "your_username";
+ //String password = "your_password";
+ LogUtils.d(TAG, "requestWithBasicAuth(...)");
+ LogUtils.d(TAG, String.format("targetUrl %s", targetUrl));
+
+ // 构建包含认证信息的请求
+ String credential = Credentials.basic(username, password);
+ LogUtils.d(TAG, String.format("credential %s", credential));
+
+ OkHttpClient client = new OkHttpClient();
+ Request request = new Request.Builder()
+ .url(targetUrl)
+ .header("Accept", "text/plain") // 设置正确的Content-Type头
+ .header("Authorization", credential)
+ .build();
+
+ Call call = client.newCall(request);
+ call.enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ // 处理网络请求失败
+ setImageViewByConnection(mImageView, false);
+ textViewHandler.postMessageText(e.getMessage());
+ textViewHandler.postMessageConnectionStatus(false);
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ //String sz = "请求失败,状态码: " + response.code();
+ //setImageViewByConnection(mImageView, false);
+ //LogUtils.d(TAG, sz);
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (!response.isSuccessful()) {
+ setImageViewByConnection(mImageView, false);
+ textViewHandler.postMessageText("Unexpected code " + response);
+ textViewHandler.postMessageConnectionStatus(false);
+ LogUtils.d(TAG, "Unexpected code " + response, Thread.currentThread().getStackTrace());
+ return;
+ }
+
+ try {
+ // 读取响应体作为字符串,注意这里可能需要解码
+ String text = response.body().string();
+ LogUtils.d(TAG, "Develop Host Connection IP is : " + text);
+ mConnectionStatus = ConnectionStatus.CONNECTED;
+ // 获取当前时间
+ LocalDateTime now = LocalDateTime.now();
+ // 定义时间格式
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
+ // 按照指定格式格式化时间并输出
+ String formattedDateTime = now.format(formatter);
+ textViewHandler.postMessageText("ClientIP<" + formattedDateTime + ">: " + text);
+ textViewHandler.postMessageConnectionStatus(true);
+
+ //org.jsoup.nodes.Document doc = org.jsoup.Jsoup.parse(text);
+ //LogUtils.d(TAG, doc.text());
+
+ // 使用id选择器找到具有特定id的元素
+ //org.jsoup.nodes.Element elementWithId = doc.select("#LastRelease").first(); // 获取第一个匹配的元素
+
+ // 提取并打印元素的文本内容
+ //mszNewestAppPackageName = elementWithId.text();
+ //ToastUtils.delayedShow(text + "\n" + mszNewestAppPackageName, 5000);
+
+ //mHandler.sendMessage(mHandler.obtainMessage(MSG_APPUPDATE_CHECKED));
+ //System.out.println(response.body().string());
+ // mConnectionStatus = ConnectionStatus.CONNECTED;
+ // // 获取当前时间
+ // LocalDateTime now = LocalDateTime.now();
+ //
+ // // 定义时间格式
+ // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
+ // // 按照指定格式格式化时间并输出
+ // String formattedDateTime = now.format(formatter);
+ // //System.out.println(formattedDateTime);
+ // textViewHandler.postMessageText("ClientIP<" + formattedDateTime + ">: " + response.body().string());
+ // textViewHandler.postMessageConnectionStatus(true);
+ } catch (Exception e) {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ }
+ });
+
+ }*/
+
+ class WinBollServiceViewHandler extends Handler {
+ WinBollServiceStatusView mDevelopHostConnectionStatusView;
+
+ public WinBollServiceViewHandler(WinBollServiceStatusView view) {
+ mDevelopHostConnectionStatusView = view;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_CONNECTION_INFO) {
+ mDevelopHostConnectionStatusView.mTextView.setText((String)msg.obj);
+ } else if (msg.what == MSG_UPDATE_CONNECTION_STATUS) {
+ mDevelopHostConnectionStatusView.setImageViewByConnection(mImageView, (boolean)msg.obj);
+ mDevelopHostConnectionStatusView.mConnectionStatus = ((boolean)msg.obj) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED;
+ }
+ super.handleMessage(msg);
+ }
+
+ void postMessageText(String szMSG) {
+ Message msg = new Message();
+ msg.what = MSG_CONNECTION_INFO;
+ msg.obj = szMSG;
+ sendMessage(msg);
+ }
+
+ void postMessageConnectionStatus(boolean isConnected) {
+ Message msg = new Message();
+ msg.what = MSG_UPDATE_CONNECTION_STATUS;
+ msg.obj = isConnected;
+ sendMessage(msg);
+ }
+ }
+
+ public static void startConnection() {
+ if (_WinBollServiceStatusView != null) {
+ _WinBollServiceStatusView.startConnectionThread();
+ }
+ }
+
+ public static void stopConnection() {
+ if (_WinBollServiceStatusView != null) {
+ _WinBollServiceStatusView.stopConnectionThread();
+ }
+ }
+
+ void startConnectionThread() {
+ if (mConnectionStatus == ConnectionStatus.DISCONNECTED) {
+ mConnectionStatus = ConnectionStatus.START_CONNECT;
+ LogUtils.d(TAG, "startConnectionThread");
+ if (mConnectionThread != null) {
+ LogUtils.d(TAG, "mConnectionThread != null");
+ mConnectionThread.mIsExist = true;
+ }
+ mConnectionThread = new ConnectionThread();
+ mConnectionThread.start();
+ } else if (mConnectionStatus == ConnectionStatus.CONNECTING) {
+ //LogUtils.d(TAG, "mConnectionStatus == ConnectionStatus.CONNECTING");
+ } else if (mConnectionStatus == ConnectionStatus.CONNECTED) {
+ //LogUtils.d(TAG, "mConnectionStatus == ConnectionStatus.CONNECTED");
+ } else {
+ LogUtils.d(TAG, String.format("Unknow mConnectionStatus %s, can not start ConnectionThread.", mConnectionStatus));
+ }
+ }
+
+ void stopConnectionThread() {
+ LogUtils.d(TAG, "stopConnectionThread");
+ if (mConnectionThread != null) {
+ LogUtils.d(TAG, "mConnectionThread != null");
+ mConnectionThread.mIsExist = true;
+ mConnectionThread = null;
+ }
+ }
+
+
+
+ class ConnectionThread extends Thread {
+
+ public volatile boolean mIsExist;
+
+ //DevelopHostConnectionStatusViewHandler mDevelopHostConnectionStatusViewHandler;
+
+ //public ConnectionThread(DevelopHostConnectionStatusViewHandler developHostConnectionStatusViewHandler) {
+ //mDevelopHostConnectionStatusViewHandler = developHostConnectionStatusViewHandler;
+ //}
+ public ConnectionThread() {
+ mIsExist = false;
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ while (mIsExist == false) {
+ if (mConnectionStatus == ConnectionStatus.START_CONNECT) {
+ mConnectionStatus = ConnectionStatus.CONNECTING;
+ //requestAPIWithBasicAuth();
+ requestCIPWithBasicAuth();
+ } else if (mConnectionStatus == ConnectionStatus.CONNECTED
+ || mConnectionStatus == ConnectionStatus.DISCONNECTED) {
+ //ToastUtils.show("mWinBollServerHostConnectionStatus " + mConnectionStatus);
+ LogUtils.d(TAG, String.format("mConnectionStatus done %s", mConnectionStatus));
+ } else {
+ LogUtils.d(TAG, String.format("mConnectionStatus unknow %s", mConnectionStatus));
+ }
+
+ try {
+ Thread.sleep(5 * 1000);
+ } catch (InterruptedException e) {
+ LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
+ }
+ }
+ //ToastUtils.show("ConnectionThread exit.");
+ LogUtils.d(TAG, "ConnectionThread exit.");
+ }
+ }
+
+ /*WinBollService.OnServiceStatusChangeListener mOnServerStatusChangeListener = new WinBollService.OnServiceStatusChangeListener(){
+ @Override
+ public void onServerStatusChange(boolean isServiceAlive) {
+ }
+ };*/
+}
diff --git a/libaes/src/main/res/drawable/bg_shadow.xml b/libaes/src/main/res/drawable/bg_shadow.xml
new file mode 100644
index 0000000..6d3d898
--- /dev/null
+++ b/libaes/src/main/res/drawable/bg_shadow.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/ic_call.xml b/libaes/src/main/res/drawable/ic_call.xml
new file mode 100644
index 0000000..c5802bb
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_call.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libaes/src/main/res/drawable/ic_dev_connected.xml b/libaes/src/main/res/drawable/ic_dev_connected.xml
new file mode 100644
index 0000000..1fb2f26
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_dev_connected.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libaes/src/main/res/drawable/ic_dev_disconnected.xml b/libaes/src/main/res/drawable/ic_dev_disconnected.xml
new file mode 100644
index 0000000..4267975
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_dev_disconnected.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libaes/src/main/res/drawable/ic_email.xml b/libaes/src/main/res/drawable/ic_email.xml
new file mode 100644
index 0000000..d526b26
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_email.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/ic_email_alert.xml b/libaes/src/main/res/drawable/ic_email_alert.xml
new file mode 100644
index 0000000..f3ed613
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_email_alert.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/ic_launcher.xml b/libaes/src/main/res/drawable/ic_launcher.xml
new file mode 100644
index 0000000..f269b7e
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_launcher.xml
@@ -0,0 +1,13 @@
+
+
+ -
+
+
diff --git a/libaes/src/main/res/drawable/ic_launcher_background.xml b/libaes/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..9486190
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/ic_launcher_foreground.xml b/libaes/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..872b04e
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/libaes/src/main/res/drawable/ic_winboll.xml b/libaes/src/main/res/drawable/ic_winboll.xml
new file mode 100644
index 0000000..f269b7e
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_winboll.xml
@@ -0,0 +1,13 @@
+
+
+ -
+
+
diff --git a/libaes/src/main/res/drawable/ic_winbollbeta.xml b/libaes/src/main/res/drawable/ic_winbollbeta.xml
new file mode 100644
index 0000000..f4876a0
--- /dev/null
+++ b/libaes/src/main/res/drawable/ic_winbollbeta.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/shape_gradient.xml b/libaes/src/main/res/drawable/shape_gradient.xml
new file mode 100644
index 0000000..c164fe9
--- /dev/null
+++ b/libaes/src/main/res/drawable/shape_gradient.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/view_border.xml b/libaes/src/main/res/drawable/view_border.xml
new file mode 100644
index 0000000..58b374a
--- /dev/null
+++ b/libaes/src/main/res/drawable/view_border.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/winboll_help.xml b/libaes/src/main/res/drawable/winboll_help.xml
new file mode 100644
index 0000000..564175f
--- /dev/null
+++ b/libaes/src/main/res/drawable/winboll_help.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/winboll_logo.xml b/libaes/src/main/res/drawable/winboll_logo.xml
new file mode 100644
index 0000000..ea28987
--- /dev/null
+++ b/libaes/src/main/res/drawable/winboll_logo.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
diff --git a/libaes/src/main/res/drawable/winboll_point.xml b/libaes/src/main/res/drawable/winboll_point.xml
new file mode 100644
index 0000000..48028cc
--- /dev/null
+++ b/libaes/src/main/res/drawable/winboll_point.xml
@@ -0,0 +1,20 @@
+
+
+
+
diff --git a/libaes/src/main/res/layout/activity_library.xml b/libaes/src/main/res/layout/activity_about.xml
similarity index 52%
rename from libaes/src/main/res/layout/activity_library.xml
rename to libaes/src/main/res/layout/activity_about.xml
index 856c0cc..540c689 100644
--- a/libaes/src/main/res/layout/activity_library.xml
+++ b/libaes/src/main/res/layout/activity_about.xml
@@ -1,14 +1,11 @@
-
-
+ android:layout_height="match_parent"
+ android:id="@+id/aboutroot_ll">
diff --git a/libaes/src/main/res/layout/fragment_viewpage.xml b/libaes/src/main/res/layout/fragment_viewpage.xml
index 3e25494..33b577a 100644
--- a/libaes/src/main/res/layout/fragment_viewpage.xml
+++ b/libaes/src/main/res/layout/fragment_viewpage.xml
@@ -2,7 +2,7 @@
@@ -12,49 +12,49 @@
android:layout_height="wrap_content"
android:text="AOHPCTCSeekBar"/>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/libaes/src/main/res/layout/view_about_dev.xml b/libaes/src/main/res/layout/view_about_dev.xml
new file mode 100644
index 0000000..629585f
--- /dev/null
+++ b/libaes/src/main/res/layout/view_about_dev.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libaes/src/main/res/layout/view_about_www.xml b/libaes/src/main/res/layout/view_about_www.xml
new file mode 100644
index 0000000..6cd4e5c
--- /dev/null
+++ b/libaes/src/main/res/layout/view_about_www.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/libaes/src/main/res/layout/viewpage_aohpctcsb.xml b/libaes/src/main/res/layout/viewpage_aohpctcsb.xml
index f86f372..94430b3 100644
--- a/libaes/src/main/res/layout/viewpage_aohpctcsb.xml
+++ b/libaes/src/main/res/layout/viewpage_aohpctcsb.xml
@@ -11,6 +11,25 @@
android:layout_height="wrap_content"
android:text="AOHPCTCSeekBar"/>
+
+
+
+
+
+
+
diff --git a/libaes/src/main/res/menu/toolbar_drawerbase.xml b/libaes/src/main/res/menu/toolbar_drawerbase.xml
index a4eb375..fb7c064 100644
--- a/libaes/src/main/res/menu/toolbar_drawerbase.xml
+++ b/libaes/src/main/res/menu/toolbar_drawerbase.xml
@@ -9,6 +9,9 @@
android:title="TestAppCrash"/>
+
diff --git a/libaes/src/main/res/values/attrs.xml b/libaes/src/main/res/values/attrs.xml
index 4dfb542..c3a273d 100644
--- a/libaes/src/main/res/values/attrs.xml
+++ b/libaes/src/main/res/values/attrs.xml
@@ -32,6 +32,13 @@
+
+
+
+
+
+
+
#FF03AB4E
#FF027C39
#FF3DDC84
- #FFA9A9A9
+ #FFFFFB8D
+ #FFA9A9A9
#FF000000
#FFFFFFFF
#FF7D3F12
@@ -14,16 +16,16 @@
@color/colorPrimaryDark
@color/colorPrimary
@color/colorAccent
-
+
@color/colorAccent
@color/colorPrimary
-
+
@color/colorAccent
@color/colorPrimary
@color/colorPrimaryDark
-
+
-
+
+ -->
diff --git a/libaes/src/main/res/values/styles.xml b/libaes/src/main/res/values/styles.xml
index 5f4ccb5..5a8e85f 100644
--- a/libaes/src/main/res/values/styles.xml
+++ b/libaes/src/main/res/values/styles.xml
@@ -1,11 +1,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+