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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +