Compare commits
31 Commits
aes-v15.0.
...
aes-v15.2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89ee16a69f | ||
|
|
4f44034b72 | ||
|
|
9d37de4bfc | ||
|
|
619fd39a92 | ||
|
|
d51ebbd550 | ||
|
|
d474eb6158 | ||
|
|
b1e2a018d8 | ||
|
|
81d538589f | ||
|
|
0735783811 | ||
|
|
156329707d | ||
|
|
3835800d24 | ||
|
|
5d796c4aba | ||
|
|
1891c24d4f | ||
|
|
892f9f0d6c | ||
|
|
a374d1aada | ||
|
|
b9d2778e11 | ||
|
|
43a91575d5 | ||
|
|
f60a57237c | ||
|
|
20b30c1337 | ||
|
|
ed1a1ac179 | ||
|
|
0a4727966a | ||
|
|
7271b2b531 | ||
|
|
e9ed88b930 | ||
|
|
a0cf87fb83 | ||
|
|
dae32ba6cb | ||
|
|
2818c0fd85 | ||
|
|
8fb9ef7992 | ||
|
|
76c9ae469f | ||
|
|
f1dac0c395 | ||
|
|
2750f0faf9 | ||
|
|
e96710e3f1 |
@@ -23,13 +23,13 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "cc.winboll.studio.aes"
|
applicationId "cc.winboll.studio.aes"
|
||||||
minSdkVersion 26
|
minSdkVersion 24
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 1
|
versionCode 1
|
||||||
// versionName 更新后需要手动设置
|
// versionName 更新后需要手动设置
|
||||||
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
||||||
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
versionName "15.0"
|
versionName "15.2"
|
||||||
if(true) {
|
if(true) {
|
||||||
versionName = genVersionName("${versionName}")
|
versionName = genVersionName("${versionName}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Mon Mar 24 19:53:34 HKT 2025
|
#Mon Mar 31 00:47:52 HKT 2025
|
||||||
stageCount=5
|
stageCount=3
|
||||||
libraryProject=libaes
|
libraryProject=libaes
|
||||||
baseVersion=15.0
|
baseVersion=15.2
|
||||||
publishVersion=15.0.4
|
publishVersion=15.2.2
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.0.5
|
baseBetaVersion=15.2.3
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/MyAESTheme"
|
android:theme="@style/MyAESTheme"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:supportsRtl="true">
|
android:supportsRtl="true"
|
||||||
|
android:networkSecurityConfig="@xml/network_security_config">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
@@ -30,6 +31,8 @@
|
|||||||
android:name="android.max_aspect"
|
android:name="android.max_aspect"
|
||||||
android:value="4.0"/>
|
android:value="4.0"/>
|
||||||
|
|
||||||
|
<activity android:name=".AboutActivity"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
91
aes/src/main/java/cc/winboll/studio/aes/AboutActivity.java
Normal file
91
aes/src/main/java/cc/winboll/studio/aes/AboutActivity.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ package cc.winboll.studio.aes;
|
|||||||
* @Describe AES应用类
|
* @Describe AES应用类
|
||||||
*/
|
*/
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
|
||||||
|
|
||||||
public class App extends GlobalApplication {
|
public class App extends GlobalApplication {
|
||||||
|
|
||||||
@@ -14,6 +16,8 @@ public class App extends GlobalApplication {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
ToastUtils.init(this);
|
||||||
|
//ToastUtils.show("App onCreate");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package cc.winboll.studio.aes;
|
|||||||
* @Date 2024/06/13 19:05:52
|
* @Date 2024/06/13 19:05:52
|
||||||
* @Describe 应用主窗口
|
* @Describe 应用主窗口
|
||||||
*/
|
*/
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -12,8 +13,6 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.Toolbar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import cc.winboll.studio.aes.R;
|
import cc.winboll.studio.aes.R;
|
||||||
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
|
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
|
||||||
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
|
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
|
||||||
@@ -25,12 +24,10 @@ import cc.winboll.studio.libaes.unittests.TestASupportToolbarActivity;
|
|||||||
import cc.winboll.studio.libaes.unittests.TestAToolbarActivity;
|
import cc.winboll.studio.libaes.unittests.TestAToolbarActivity;
|
||||||
import cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity;
|
import cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity;
|
||||||
import cc.winboll.studio.libaes.unittests.TestViewPageFragment;
|
import cc.winboll.studio.libaes.unittests.TestViewPageFragment;
|
||||||
import cc.winboll.studio.libaes.winboll.APPInfo;
|
|
||||||
import cc.winboll.studio.libaes.winboll.AboutActivityFactory;
|
|
||||||
import cc.winboll.studio.libaes.winboll.IWinBollActivity;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
|
||||||
import com.a4455jkjh.colorpicker.ColorPickerDialog;
|
import com.a4455jkjh.colorpicker.ColorPickerDialog;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class MainActivity extends DrawerFragmentActivity implements IWinBollActivity {
|
public class MainActivity extends DrawerFragmentActivity implements IWinBollActivity {
|
||||||
@@ -42,7 +39,7 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBollActi
|
|||||||
TestViewPageFragment mTestViewPageFragment;
|
TestViewPageFragment mTestViewPageFragment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppCompatActivity getActivity() {
|
public Activity getActivity() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,21 +48,6 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBollActi
|
|||||||
return TAG;
|
return TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Toolbar initToolBar() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAddWinBollToolBar() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnableDisplayHomeAsUp() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -75,6 +57,7 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBollActi
|
|||||||
}
|
}
|
||||||
showFragment(mTestAButtonFragment);
|
showFragment(mTestAButtonFragment);
|
||||||
//setSubtitle(TAG);
|
//setSubtitle(TAG);
|
||||||
|
//ToastUtils.show("onCreate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -202,28 +185,13 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBollActi
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
else if (nItemId == R.id.item_about) {
|
else if (nItemId == R.id.item_about) {
|
||||||
onAbout();
|
Intent intent = new Intent(this, AboutActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAbout() {
|
|
||||||
String szBranchName = "aes";
|
|
||||||
|
|
||||||
APPInfo appInfo = AboutActivityFactory.buildDefaultAPPInfo();
|
|
||||||
appInfo.setAppName("AES");
|
|
||||||
appInfo.setAppIcon(cc.winboll.studio.libapputils.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");
|
|
||||||
AboutActivityFactory.showAboutActivity(this, appInfo);
|
|
||||||
//ToastUtils.show("onAbout");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
50
aes/src/main/java/cc/winboll/studio/aes/WinBollActivity.java
Normal file
50
aes/src/main/java/cc/winboll/studio/aes/WinBollActivity.java
Normal file
@@ -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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
22
aes/src/main/res/layout/activity_about.xml
Normal file
22
aes/src/main/res/layout/activity_about.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.ASupportToolbar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/toolbar"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
android:id="@+id/aboutviewroot_ll"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
6
aes/src/main/res/xml/network_security_config.xml
Normal file
6
aes/src/main/res/xml/network_security_config.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<network-security-config>
|
||||||
|
<domain-config cleartextTrafficPermitted="true">
|
||||||
|
<domain includeSubdomains="true">winboll.cc</domain>
|
||||||
|
</domain-config>
|
||||||
|
</network-security-config>
|
||||||
@@ -8,7 +8,7 @@ android {
|
|||||||
buildToolsVersion "32.0.0"
|
buildToolsVersion "32.0.0"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 26
|
minSdkVersion 24
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@@ -22,6 +22,9 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
// 吐司类库
|
||||||
|
api 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
|
||||||
// 权限请求框架:https://github.com/getActivity/XXPermissions
|
// 权限请求框架:https://github.com/getActivity/XXPermissions
|
||||||
api 'com.github.getActivity:XXPermissions:18.63'
|
api 'com.github.getActivity:XXPermissions:18.63'
|
||||||
// 下拉控件
|
// 下拉控件
|
||||||
@@ -48,6 +51,6 @@ dependencies {
|
|||||||
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
||||||
//api 'androidx.fragment:fragment:1.1.0'
|
//api 'androidx.fragment:fragment:1.1.0'
|
||||||
|
|
||||||
api 'cc.winboll.studio:libappbase:15.0.9'
|
api 'cc.winboll.studio:libappbase:15.2.0'
|
||||||
api 'cc.winboll.studio:libapputils:15.0.15'
|
api 'cc.winboll.studio:libapputils:15.2.0'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Mon Mar 24 19:53:34 HKT 2025
|
#Mon Mar 31 00:47:52 HKT 2025
|
||||||
stageCount=5
|
stageCount=3
|
||||||
libraryProject=libaes
|
libraryProject=libaes
|
||||||
baseVersion=15.0
|
baseVersion=15.2
|
||||||
publishVersion=15.0.4
|
publishVersion=15.2.2
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.0.5
|
baseBetaVersion=15.2.3
|
||||||
|
|||||||
@@ -13,7 +13,11 @@
|
|||||||
|
|
||||||
<activity android:name="cc.winboll.studio.libaes.unittests.TestASupportToolbarActivity"/>
|
<activity android:name="cc.winboll.studio.libaes.unittests.TestASupportToolbarActivity"/>
|
||||||
|
|
||||||
<activity android:name="cc.winboll.studio.libaes.winboll.AboutActivity"/>
|
<service android:name="cc.winboll.studio.libaes.winboll.WinBollClientService"/>
|
||||||
|
|
||||||
|
<service android:name="cc.winboll.studio.libaes.winboll.AssistantService"/>
|
||||||
|
|
||||||
|
<service android:name="cc.winboll.studio.libaes.winboll.WinBollMail"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import android.view.View;
|
|||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
@@ -26,11 +27,11 @@ import cc.winboll.studio.libaes.beans.AESThemeBean;
|
|||||||
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
|
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
|
||||||
import cc.winboll.studio.libaes.utils.AESThemeUtil;
|
import cc.winboll.studio.libaes.utils.AESThemeUtil;
|
||||||
import cc.winboll.studio.libaes.views.ADrawerMenuListView;
|
import cc.winboll.studio.libaes.views.ADrawerMenuListView;
|
||||||
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
|
||||||
import com.baoyz.widget.PullRefreshLayout;
|
import com.baoyz.widget.PullRefreshLayout;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import cc.winboll.studio.libaes.winboll.IWinBollActivity;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
|
|
||||||
public abstract class DrawerFragmentActivity extends AppCompatActivity implements IWinBollActivity,AdapterView.OnItemClickListener {
|
public abstract class DrawerFragmentActivity extends AppCompatActivity implements IWinBollActivity,AdapterView.OnItemClickListener {
|
||||||
|
|
||||||
@@ -175,6 +176,8 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
|
|||||||
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
|
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
|
||||||
getString(i);
|
getString(i);
|
||||||
}
|
}
|
||||||
|
} else if (R.id.item_log == item.getItemId()) {
|
||||||
|
GlobalApplication.getWinBollActivityManager().startLogActivity(this);
|
||||||
} else if (R.id.item_about == item.getItemId()) {
|
} else if (R.id.item_about == item.getItemId()) {
|
||||||
LogUtils.d(TAG, "onAbout");
|
LogUtils.d(TAG, "onAbout");
|
||||||
} else if (android.R.id.home == item.getItemId()) {
|
} else if (android.R.id.home == item.getItemId()) {
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
package cc.winboll.studio.libaes.beans;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/03/24 15:27:16
|
|
||||||
* @Describe AES数据实例化模型
|
|
||||||
*/
|
|
||||||
import cc.winboll.studio.libappbase.BaseBean;
|
|
||||||
import android.util.JsonWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import android.util.JsonReader;
|
|
||||||
|
|
||||||
public class AESModel extends BaseBean {
|
|
||||||
|
|
||||||
public static final String TAG = "AESModel";
|
|
||||||
|
|
||||||
boolean isInDebugMode;
|
|
||||||
|
|
||||||
public AESModel() {
|
|
||||||
this.isInDebugMode = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AESModel(boolean isInDebugMode) {
|
|
||||||
this.isInDebugMode = isInDebugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsInDebugMode(boolean isInDebugMode) {
|
|
||||||
this.isInDebugMode = isInDebugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInDebugMode() {
|
|
||||||
return isInDebugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return AESModel.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
|
||||||
super.writeThisToJsonWriter(jsonWriter);
|
|
||||||
jsonWriter.name("isInDebugMode").value(isInDebugMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
|
||||||
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
|
||||||
if (name.equals("isInDebugMode")) {
|
|
||||||
setIsInDebugMode(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
package cc.winboll.studio.libaes.unittests;
|
package cc.winboll.studio.libaes.unittests;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.Toolbar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import cc.winboll.studio.libaes.R;
|
import cc.winboll.studio.libaes.R;
|
||||||
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
|
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
|
||||||
import cc.winboll.studio.libaes.winboll.APPInfo;
|
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
|
||||||
import cc.winboll.studio.libaes.winboll.IWinBollActivity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen@QQ.COM
|
* @Author ZhanGSKen@QQ.COM
|
||||||
@@ -23,7 +21,7 @@ public class SecondaryLibraryActivity extends DrawerFragmentActivity implements
|
|||||||
SecondaryLibraryFragment mSecondaryLibraryFragment;
|
SecondaryLibraryFragment mSecondaryLibraryFragment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppCompatActivity getActivity() {
|
public Activity getActivity() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,21 +30,6 @@ public class SecondaryLibraryActivity extends DrawerFragmentActivity implements
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Toolbar initToolBar() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAddWinBollToolBar() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnableDisplayHomeAsUp() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import androidx.fragment.app.Fragment;
|
|||||||
import cc.winboll.studio.libaes.R;
|
import cc.winboll.studio.libaes.R;
|
||||||
import cc.winboll.studio.libaes.views.AButton;
|
import cc.winboll.studio.libaes.views.AButton;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
|
|
||||||
public class TestAButtonFragment extends Fragment {
|
public class TestAButtonFragment extends Fragment {
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,27 @@ package cc.winboll.studio.libaes.unittests;
|
|||||||
* @Date 2024/07/16 01:14:00
|
* @Date 2024/07/16 01:14:00
|
||||||
* @Describe TestASupportToolbarActivity
|
* @Describe TestASupportToolbarActivity
|
||||||
*/
|
*/
|
||||||
import android.content.Context;
|
import android.app.Activity;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import cc.winboll.studio.libaes.R;
|
import cc.winboll.studio.libaes.R;
|
||||||
import cc.winboll.studio.libaes.beans.AESThemeBean;
|
|
||||||
import cc.winboll.studio.libaes.utils.AESThemeUtil;
|
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";
|
public static final String TAG = "TestASupportToolbarActivity";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
|||||||
@@ -10,11 +10,22 @@ import android.os.Bundle;
|
|||||||
import android.widget.Toolbar;
|
import android.widget.Toolbar;
|
||||||
import cc.winboll.studio.libaes.R;
|
import cc.winboll.studio.libaes.R;
|
||||||
import cc.winboll.studio.libaes.utils.AESThemeUtil;
|
import cc.winboll.studio.libaes.utils.AESThemeUtil;
|
||||||
|
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
|
||||||
|
|
||||||
public class TestAToolbarActivity extends Activity {
|
public class TestAToolbarActivity extends Activity implements IWinBollActivity {
|
||||||
|
|
||||||
public static final String TAG = "TestAToolbarActivity";
|
public static final String TAG = "TestAToolbarActivity";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
AESThemeUtil.applyAppTheme(this);
|
AESThemeUtil.applyAppTheme(this);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package cc.winboll.studio.libaes.unittests;
|
|||||||
* @Author ZhanGSKen@QQ.COM
|
* @Author ZhanGSKen@QQ.COM
|
||||||
* @Date 2024/06/30 15:00:51
|
* @Date 2024/06/30 15:00:51
|
||||||
*/
|
*/
|
||||||
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -11,19 +12,18 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.Toolbar;
|
import android.widget.Toolbar;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import cc.winboll.studio.libaes.R;
|
import cc.winboll.studio.libaes.R;
|
||||||
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
|
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
|
||||||
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
|
import cc.winboll.studio.libaes.beans.DrawerMenuBean;
|
||||||
import cc.winboll.studio.libaes.winboll.IWinBollActivity;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.winboll.IWinBollActivity;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class TestDrawerFragmentActivity extends DrawerFragmentActivity implements IWinBollActivity {
|
public class TestDrawerFragmentActivity extends DrawerFragmentActivity implements IWinBollActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppCompatActivity getActivity() {
|
public Activity getActivity() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,22 +32,6 @@ public class TestDrawerFragmentActivity extends DrawerFragmentActivity implement
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Toolbar initToolBar() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAddWinBollToolBar() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnableDisplayHomeAsUp() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static final String TAG = "TestDrawerFragmentActivity";
|
public static final String TAG = "TestDrawerFragmentActivity";
|
||||||
|
|
||||||
TestFragment1 mTestFragment1;
|
TestFragment1 mTestFragment1;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import cc.winboll.studio.libaes.ImagePagerAdapter;
|
|||||||
import cc.winboll.studio.libaes.R;
|
import cc.winboll.studio.libaes.R;
|
||||||
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
|
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
|
||||||
import cc.winboll.studio.libappbase.LogView;
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|||||||
@@ -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 "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,13 +47,14 @@ public class APPInfo implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public APPInfo() {
|
public APPInfo() {
|
||||||
this.appName = "WinBoll-APP";
|
String szBranchName = "app";
|
||||||
|
this.appName = "APP";
|
||||||
this.appIcon = R.drawable.ic_launcher;
|
this.appIcon = R.drawable.ic_launcher;
|
||||||
this.appDescription = "WinBoll APP";
|
this.appDescription = "APP Description";
|
||||||
this.appGitName = "APP";
|
this.appGitName = "APP";
|
||||||
this.appGitOwner = "Studio";
|
this.appGitOwner = "Studio";
|
||||||
this.appGitAPPBranch = "app";
|
this.appGitAPPBranch = szBranchName;
|
||||||
this.appGitAPPSubProjectFolder = "app";
|
this.appGitAPPSubProjectFolder = szBranchName;
|
||||||
this.appHomePage = "https://www.winboll.cc/studio/details.php?app=APP";
|
this.appHomePage = "https://www.winboll.cc/studio/details.php?app=APP";
|
||||||
this.appAPKName = "APP";
|
this.appAPKName = "APP";
|
||||||
this.appAPKFolderName = "APP";
|
this.appAPKFolderName = "APP";
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
package cc.winboll.studio.libaes.winboll;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/03/24 16:39:29
|
|
||||||
* @Describe WinBoll Android 应用介绍窗口
|
|
||||||
*/
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import cc.winboll.studio.libaes.R;
|
|
||||||
|
|
||||||
final public class AboutActivity extends Activity {
|
|
||||||
|
|
||||||
public static final String TAG = "AboutActivity";
|
|
||||||
|
|
||||||
public static final String EXTRA_APPINFO = "EXTRA_APPINFO";
|
|
||||||
|
|
||||||
APPInfo mAPPInfo;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Context getApplicationContext() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_about);
|
|
||||||
Intent intent = getIntent();
|
|
||||||
if (intent != null) {
|
|
||||||
mAPPInfo = (APPInfo)intent.getSerializableExtra(EXTRA_APPINFO);
|
|
||||||
}
|
|
||||||
if (mAPPInfo == null) {
|
|
||||||
mAPPInfo = new APPInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
AboutView aboutView = new AboutView(this, mAPPInfo);
|
|
||||||
LinearLayout llMain = findViewById(R.id.aboutroot_ll);
|
|
||||||
llMain.addView(aboutView);
|
|
||||||
|
|
||||||
//ToastUtils.show(TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.toolbar_winboll_shared_about, menu);
|
|
||||||
return super.onCreateOptionsMenu(menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
// if (item.getItemId() == R.id.item_help) {
|
|
||||||
// WinBollActivityManager.getInstance(this).startWinBollActivity(this, AssetsHtmlActivity.class);
|
|
||||||
// }
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package cc.winboll.studio.libaes.winboll;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/02/06 08:45:23
|
|
||||||
* @Describe 关于活动窗口的介绍窗口工厂
|
|
||||||
*/
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import cc.winboll.studio.libaes.R;
|
|
||||||
import cc.winboll.studio.libaes.winboll.AboutActivityFactory;
|
|
||||||
|
|
||||||
public class AboutActivityFactory {
|
|
||||||
|
|
||||||
public static final String TAG = "AboutActivityFactory";
|
|
||||||
|
|
||||||
public static APPInfo buildDefaultAPPInfo() {
|
|
||||||
String szBranchName = "";
|
|
||||||
|
|
||||||
APPInfo appInfo = new APPInfo();
|
|
||||||
appInfo.setAppName("APP");
|
|
||||||
appInfo.setAppIcon(R.drawable.ic_winboll);
|
|
||||||
appInfo.setAppDescription("APP Description");
|
|
||||||
appInfo.setAppGitName("APP");
|
|
||||||
appInfo.setAppGitOwner("Studio");
|
|
||||||
appInfo.setAppGitAPPBranch(szBranchName);
|
|
||||||
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
|
||||||
appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=APP");
|
|
||||||
appInfo.setAppAPKName("APP");
|
|
||||||
appInfo.setAppAPKFolderName("APP");
|
|
||||||
return appInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showAboutActivity(Context context, APPInfo appInfo) {
|
|
||||||
/*String szPN = ((IWinBollActivity)context).getActivityPackageName();
|
|
||||||
//String szPN = context.getPackageName();
|
|
||||||
String szBranchName = "";
|
|
||||||
if (szPN != null) {
|
|
||||||
//String szPN = "cc.winboll.studio.apputils.beta";
|
|
||||||
String regex = "cc\\.winboll\\.studio\\.([^.]+)\\.*";
|
|
||||||
Pattern pattern = Pattern.compile(regex);
|
|
||||||
Matcher matcher = pattern.matcher(szPN);
|
|
||||||
if (matcher.find()) {
|
|
||||||
szBranchName = matcher.group(1);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
//ToastUtils.show(szPN);
|
|
||||||
|
|
||||||
Intent intent = new Intent(context, AboutActivity.class);
|
|
||||||
intent.putExtra(AboutActivity.EXTRA_APPINFO, (appInfo == null) ? AboutActivityFactory.buildDefaultAPPInfo():appInfo);
|
|
||||||
context.startActivity(intent);
|
|
||||||
//WinBollActivityManager.getInstance(context).startWinBollActivity(context, intent, AboutActivity.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,14 +17,12 @@ import android.view.View;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import cc.winboll.studio.libaes.R;
|
import cc.winboll.studio.libaes.R;
|
||||||
import cc.winboll.studio.libaes.beans.AESModel;
|
import cc.winboll.studio.libaes.utils.AppVersionUtils;
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog;
|
||||||
import cc.winboll.studio.libapputils.app.AppVersionUtils;
|
import cc.winboll.studio.libapputils.utils.PrefUtils;
|
||||||
import cc.winboll.studio.libapputils.util.PrefUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
import cc.winboll.studio.libapputils.view.WinBollServiceStatusView;
|
|
||||||
import cc.winboll.studio.libapputils.view.YesNoAlertDialog;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import mehdi.sakout.aboutpage.AboutPage;
|
import mehdi.sakout.aboutpage.AboutPage;
|
||||||
import mehdi.sakout.aboutpage.Element;
|
import mehdi.sakout.aboutpage.Element;
|
||||||
@@ -120,6 +118,7 @@ public class AboutView extends LinearLayout {
|
|||||||
} else {
|
} else {
|
||||||
mszGitea = "https://gitea.winboll.cc/" + mAPPInfo.getAppGitOwner() + "/" + mszAppGitName + "/src/branch/" + mAPPInfo.getAppGitAPPBranch() + "/" + mAPPInfo.getAppGitAPPSubProjectFolder();
|
mszGitea = "https://gitea.winboll.cc/" + mAPPInfo.getAppGitOwner() + "/" + mszAppGitName + "/src/branch/" + mAPPInfo.getAppGitAPPBranch() + "/" + mAPPInfo.getAppGitAPPSubProjectFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (GlobalApplication.isDebuging()) {
|
if (GlobalApplication.isDebuging()) {
|
||||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||||
@@ -264,6 +263,7 @@ public class AboutView extends LinearLayout {
|
|||||||
View.OnClickListener mAppDebugOnClickListener = new View.OnClickListener(){
|
View.OnClickListener mAppDebugOnClickListener = new View.OnClickListener(){
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
//ToastUtils.show("mAppDebugOnClickListener");
|
||||||
setApp2DebugMode(mContext);
|
setApp2DebugMode(mContext);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -271,6 +271,7 @@ public class AboutView extends LinearLayout {
|
|||||||
View.OnClickListener mAppNormalOnClickListener = new View.OnClickListener(){
|
View.OnClickListener mAppNormalOnClickListener = new View.OnClickListener(){
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
//ToastUtils.show("mAppNormalOnClickListener");
|
||||||
setApp2NormalMode(mContext);
|
setApp2NormalMode(mContext);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -278,12 +279,11 @@ public class AboutView extends LinearLayout {
|
|||||||
public static void setApp2DebugMode(Context context) {
|
public static void setApp2DebugMode(Context context) {
|
||||||
Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
intent.setAction(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW);
|
//intent.setAction(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
GlobalApplication.setIsDebuging(context, true);
|
GlobalApplication.setIsDebuging(true);
|
||||||
AESModel.saveBean(context, new AESModel(true));
|
|
||||||
|
|
||||||
WinBollActivityManager.getInstance(context).finishAll();
|
GlobalApplication.getWinBollActivityManager().finishAll();
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,10 +292,9 @@ public class AboutView extends LinearLayout {
|
|||||||
Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
GlobalApplication.setIsDebuging(context, false);
|
GlobalApplication.setIsDebuging(false);
|
||||||
AESModel.saveBean(context, new AESModel(false));
|
|
||||||
|
|
||||||
WinBollActivityManager.getInstance(context).finishAll();
|
GlobalApplication.getWinBollActivityManager().finishAll();
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package cc.winboll.studio.libaes.winboll;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/03/24 08:23:40
|
|
||||||
* @Describe WinBoll 活动窗口通用接口
|
|
||||||
*/
|
|
||||||
import android.widget.Toolbar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
public interface IWinBollActivity {
|
|
||||||
|
|
||||||
public static final String TAG = "IWinBollActivity";
|
|
||||||
|
|
||||||
// 获取应用资源上下文
|
|
||||||
abstract public AppCompatActivity getActivity();
|
|
||||||
abstract public String getTag();
|
|
||||||
abstract public Toolbar initToolBar();
|
|
||||||
abstract public boolean isEnableDisplayHomeAsUp();
|
|
||||||
abstract public boolean isAddWinBollToolBar();
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package cc.winboll.studio.libaes.winboll;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/03/24 08:24:52
|
|
||||||
*/
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
|
||||||
|
|
||||||
public class MyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
|
|
||||||
|
|
||||||
public static final String TAG = "MyActivityLifecycleCallbacks";
|
|
||||||
|
|
||||||
public String mInfo = "";
|
|
||||||
|
|
||||||
public MyActivityLifecycleCallbacks() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void createActivityeInfo(Activity activity) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
Intent receivedIntent = activity.getIntent();
|
|
||||||
sb.append("\nCallingActivity : \n");
|
|
||||||
if (activity.getCallingActivity() != null) {
|
|
||||||
sb.append(activity.getCallingActivity().getPackageName());
|
|
||||||
}
|
|
||||||
sb.append("\nReceived Intent Package : \n");
|
|
||||||
sb.append(receivedIntent.getPackage());
|
|
||||||
|
|
||||||
Bundle extras = receivedIntent.getExtras();
|
|
||||||
if (extras != null) {
|
|
||||||
for (String key : extras.keySet()) {
|
|
||||||
sb.append("\nIntentInfo");
|
|
||||||
sb.append("\n键: ");
|
|
||||||
sb.append(key);
|
|
||||||
sb.append(", 值: ");
|
|
||||||
sb.append(extras.get(key));
|
|
||||||
//Log.d("IntentInfo", "键: " + key + ", 值: " + extras.get(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mInfo = sb.toString();
|
|
||||||
//Log.d("IntentInfo", "发送Intent的应用包名: " + senderPackage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showActivityeInfo() {
|
|
||||||
ToastUtils.show("ActivityeInfo : " + mInfo);
|
|
||||||
LogUtils.d(TAG, "ActivityeInfo : " + mInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
|
||||||
// 在这里可以做一些初始化相关的操作,例如记录Activity的创建时间等
|
|
||||||
//System.out.println(activity.getLocalClassName() + " was created");
|
|
||||||
LogUtils.d(TAG, activity.getLocalClassName() + " was created");
|
|
||||||
createActivityeInfo(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityStarted(Activity activity) {
|
|
||||||
//System.out.println(activity.getLocalClassName() + " was started");
|
|
||||||
LogUtils.d(TAG, activity.getLocalClassName() + " was started");
|
|
||||||
//createActivityeInfo(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResumed(Activity activity) {
|
|
||||||
//System.out.println(activity.getLocalClassName() + " was resumed");
|
|
||||||
LogUtils.d(TAG, activity.getLocalClassName() + " was resumed");
|
|
||||||
//createActivityeInfo(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityPaused(Activity activity) {
|
|
||||||
//System.out.println(activity.getLocalClassName() + " was paused");
|
|
||||||
LogUtils.d(TAG, activity.getLocalClassName() + " was paused");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityStopped(Activity activity) {
|
|
||||||
//System.out.println(activity.getLocalClassName() + " was stopped");
|
|
||||||
LogUtils.d(TAG, activity.getLocalClassName() + " was stopped");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
|
||||||
// 可以在这里添加保存状态的自定义逻辑
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityDestroyed(Activity activity) {
|
|
||||||
//System.out.println(activity.getLocalClassName() + " was destroyed");
|
|
||||||
LogUtils.d(TAG, activity.getLocalClassName() + " was destroyed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,318 +0,0 @@
|
|||||||
package cc.winboll.studio.libaes.winboll;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/03/24 08:25:43
|
|
||||||
* @Describe 应用活动窗口管理器
|
|
||||||
* 参考 :
|
|
||||||
* android 类似微信小程序多任务窗口 及 设置 TaskDescription 修改 icon 和 label
|
|
||||||
* https://blog.csdn.net/qq_29364417/article/details/109379915?app_version=6.4.2&code=app_1562916241&csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22109379915%22%2C%22source%22%3A%22weixin_38986226%22%7D&uLinkId=usr1mkqgl919blen&utm_source=app
|
|
||||||
*/
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.TaskStackBuilder;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class WinBollActivityManager {
|
|
||||||
|
|
||||||
public static final String TAG = "WinBollActivityManager";
|
|
||||||
public static final String EXTRA_TAG = "EXTRA_TAG";
|
|
||||||
|
|
||||||
public static enum WinBollUI_TYPE {
|
|
||||||
Aplication, // 退出应用后,保持最近任务栏任务记录主窗口
|
|
||||||
Service // 退出应用后,清理所有最近任务栏任务记录窗口
|
|
||||||
};
|
|
||||||
|
|
||||||
// 应用类型标志
|
|
||||||
volatile static WinBollUI_TYPE _mWinBollUI_TYPE = WinBollUI_TYPE.Service;
|
|
||||||
|
|
||||||
Context mContext;
|
|
||||||
MyActivityLifecycleCallbacks mMyActivityLifecycleCallbacks;
|
|
||||||
static WinBollActivityManager _mWinBollActivityManager;
|
|
||||||
static Map<String, IWinBollActivity> _mapIWinBollList;
|
|
||||||
IWinBollActivity firstIWinBollActivity;
|
|
||||||
|
|
||||||
public WinBollActivityManager(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
LogUtils.d(TAG, "WinBollActivityManager()");
|
|
||||||
_mapIWinBollList = new HashMap<String, IWinBollActivity>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized WinBollActivityManager getInstance(Context context) {
|
|
||||||
LogUtils.d(TAG, "getInstance");
|
|
||||||
if (_mWinBollActivityManager == null) {
|
|
||||||
LogUtils.d(TAG, "_mWinBollActivityManager == null");
|
|
||||||
_mWinBollActivityManager = new WinBollActivityManager(context);
|
|
||||||
}
|
|
||||||
return _mWinBollActivityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 设置 WinBoll 应用 UI 类型
|
|
||||||
//
|
|
||||||
public synchronized static void setWinBollUI_TYPE(WinBollUI_TYPE mWinBollUI_TYPE) {
|
|
||||||
_mWinBollUI_TYPE = mWinBollUI_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 获取 WinBoll 应用 UI 类型
|
|
||||||
//
|
|
||||||
public synchronized static WinBollUI_TYPE getWinBollUI_TYPE() {
|
|
||||||
return _mWinBollUI_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 把Activity添加到管理中
|
|
||||||
//
|
|
||||||
public <T extends IWinBollActivity> void add(T iWinBoll) {
|
|
||||||
if (isActive(iWinBoll.getTag())) {
|
|
||||||
LogUtils.d(TAG, String.format("add(...) %s is active.", iWinBoll.getTag()));
|
|
||||||
} else {
|
|
||||||
// 设置起始活动窗口,以便最后退出时提问
|
|
||||||
if (firstIWinBollActivity == null && _mapIWinBollList.size() == 0) {
|
|
||||||
firstIWinBollActivity = iWinBoll;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加到活动窗口列表
|
|
||||||
_mapIWinBollList.put(iWinBoll.getTag(), iWinBoll);
|
|
||||||
LogUtils.d(TAG, String.format("Add activity : %s\n_mapActivityList.size() : %d", iWinBoll.getTag(), _mapIWinBollList.size()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// activity: 为 null 时,
|
|
||||||
// intent.putExtra 函数 EXTRA_TAG 参数为 tag
|
|
||||||
// activity: 不为 null 时,
|
|
||||||
// intent.putExtra 函数 "tag" 参数为 activity.getTag()
|
|
||||||
//
|
|
||||||
public <T extends IWinBollActivity> void startWinBollActivity(Context context, Class<T> clazz) {
|
|
||||||
try {
|
|
||||||
// 如果窗口已存在就重启窗口
|
|
||||||
String tag = clazz.newInstance().getTag();
|
|
||||||
if (isActive(tag)) {
|
|
||||||
resumeActivity(context, tag);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新建一个任务窗口
|
|
||||||
Intent intent = new Intent(context, clazz);
|
|
||||||
//打开多任务窗口 flags
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
intent.putExtra(EXTRA_TAG, tag);
|
|
||||||
mContext.startActivity(intent);
|
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends IWinBollActivity> void startWinBollActivity(Context context, Intent intent, Class<T> clazz) {
|
|
||||||
try {
|
|
||||||
// 如果窗口已存在就重启窗口
|
|
||||||
String tag = clazz.newInstance().getTag();
|
|
||||||
if (isActive(tag)) {
|
|
||||||
resumeActivity(context, tag);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新建一个任务窗口
|
|
||||||
//Intent intent = new Intent(context, clazz);
|
|
||||||
//打开多任务窗口 flags
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
intent.putExtra(EXTRA_TAG, tag);
|
|
||||||
mContext.startActivity(intent);
|
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFirstIWinBollActivity(IWinBollActivity iWinBollActivity) {
|
|
||||||
return firstIWinBollActivity != null && firstIWinBollActivity == iWinBollActivity;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 判断 tag绑定的 MyActivity是否存在
|
|
||||||
//
|
|
||||||
public boolean isActive(String tag) {
|
|
||||||
//printAvtivityListInfo();
|
|
||||||
IWinBollActivity iWinBoll = getIWinBoll(tag);
|
|
||||||
if (iWinBoll != null) {
|
|
||||||
LogUtils.d(TAG, "isActive(...) activity != null tag " + tag);
|
|
||||||
//ToastUtils.show("activity != null tag " + tag);
|
|
||||||
//判断是否为 BaseActivity,如果已经销毁,则移除
|
|
||||||
if (iWinBoll.getActivity().isFinishing() || iWinBoll.getActivity().isDestroyed()) {
|
|
||||||
_mapIWinBollList.remove(iWinBoll.getTag());
|
|
||||||
//_mWinBollActivityList.remove(activity);
|
|
||||||
LogUtils.d(TAG, String.format("isActive(...) remove activity.\ntag : %s", tag));
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
LogUtils.d(TAG, String.format("isActive(...) activity is exist.\ntag : %s", tag));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LogUtils.d(TAG, String.format("isActive(...) activity == null\ntag : %s", tag));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static IWinBollActivity getIWinBoll(String tag) {
|
|
||||||
return _mapIWinBollList.get(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 找到tag 绑定的 BaseActivity ,通过 getTaskId() 移动到前台
|
|
||||||
//
|
|
||||||
public <T extends IWinBollActivity> void resumeActivity(Context context, String tag) {
|
|
||||||
LogUtils.d(TAG, "resumeActivty");
|
|
||||||
T iWinBoll = (T)getIWinBoll(tag);
|
|
||||||
//LogUtils.d(TAG, "activity " + activity.getTag());
|
|
||||||
if (iWinBoll != null && !iWinBoll.getActivity().isFinishing() && !iWinBoll.getActivity().isDestroyed()) {
|
|
||||||
resumeActivity(context, iWinBoll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 找到tag 绑定的 BaseActivity ,通过 getTaskId() 移动到前台
|
|
||||||
//
|
|
||||||
public <T extends IWinBollActivity> void resumeActivity(Context context, T iWinBoll) {
|
|
||||||
ActivityManager am = (ActivityManager) iWinBoll.getActivity().getSystemService(Context.ACTIVITY_SERVICE);
|
|
||||||
//返回启动它的根任务(home 或者 MainActivity)
|
|
||||||
Intent intent = new Intent(context, iWinBoll.getClass());
|
|
||||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
|
|
||||||
stackBuilder.addNextIntentWithParentStack(intent);
|
|
||||||
stackBuilder.startActivities();
|
|
||||||
//moveTaskToFront(YourTaskId, 0);
|
|
||||||
LogUtils.d(TAG, "am.moveTaskToFront");
|
|
||||||
//ToastUtils.show("resumeActivity am.moveTaskToFront");
|
|
||||||
am.moveTaskToFront(iWinBoll.getActivity().getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// 结束所有 Activity
|
|
||||||
//
|
|
||||||
public void finishAll() {
|
|
||||||
try {
|
|
||||||
for (String key : _mapIWinBollList.keySet()) {
|
|
||||||
//System.out.println("Key: " + key + ", Value: " + _mapActivityList.get(key));
|
|
||||||
IWinBollActivity iWinBoll = _mapIWinBollList.get(key);
|
|
||||||
//ToastUtils.show("finishAll() activity");
|
|
||||||
if (iWinBoll != null && !iWinBoll.getActivity().isFinishing() && !iWinBoll.getActivity().isDestroyed()) {
|
|
||||||
//ToastUtils.show("activity != null ...");
|
|
||||||
if (getWinBollUI_TYPE() == WinBollUI_TYPE.Service) {
|
|
||||||
// 结束窗口和最近任务栏, 建议前台服务类应用使用,可以方便用户再次调用 UI 操作。
|
|
||||||
iWinBoll.getActivity().finishAndRemoveTask();
|
|
||||||
//ToastUtils.show("finishAll() activity.finishAndRemoveTask();");
|
|
||||||
} else if (getWinBollUI_TYPE() == WinBollUI_TYPE.Aplication) {
|
|
||||||
// 结束窗口保留最近任务栏,建议前台服务类应用使用,可以保持应用的系统自觉性。
|
|
||||||
iWinBoll.getActivity().finish();
|
|
||||||
//ToastUtils.show("finishAll() activity.finish();");
|
|
||||||
} else {
|
|
||||||
LogUtils.d(TAG, "WinBollApplication.WinBollUI_TYPE error.");
|
|
||||||
//ToastUtils.show("WinBollApplication.WinBollUI_TYPE error.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 结束指定Activity
|
|
||||||
//
|
|
||||||
public <T extends IWinBollActivity> void finish(T iWinBoll) {
|
|
||||||
try {
|
|
||||||
if (iWinBoll != null && !iWinBoll.getActivity().isFinishing() && !iWinBoll.getActivity().isDestroyed()) {
|
|
||||||
//根据tag 移除 MyActivity
|
|
||||||
//String tag= activity.getTag();
|
|
||||||
//_mWinBollActivityList.remove(tag);
|
|
||||||
//ToastUtils.show("remove");
|
|
||||||
//ToastUtils.show("_mWinBollActivityArrayMap.size() " + Integer.toString(_mWinBollActivityArrayMap.size()));
|
|
||||||
|
|
||||||
// 窗口回调规则:
|
|
||||||
// [] 当前窗口位置 >> 调度出的窗口位置
|
|
||||||
// ★:[0] 1 2 3 4 >> 1
|
|
||||||
// ★:0 1 [2] 3 4 >> 1
|
|
||||||
// ★:0 1 2 [3] 4 >> 2
|
|
||||||
// ★:0 1 2 3 [4] >> 3
|
|
||||||
// ★:[0] >> 直接关闭当前窗口
|
|
||||||
LogUtils.d(TAG, "finish no yet.");
|
|
||||||
IWinBollActivity preIWinBoll = getPreIWinBoll(iWinBoll);
|
|
||||||
iWinBoll.getActivity().finish();
|
|
||||||
if (preIWinBoll != null) {
|
|
||||||
resumeActivity(mContext, preIWinBoll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 获取窗口队列中的前一个窗口
|
|
||||||
//
|
|
||||||
IWinBollActivity getPreIWinBoll(IWinBollActivity iWinBoll) {
|
|
||||||
try {
|
|
||||||
boolean bingo = false;
|
|
||||||
IWinBollActivity preIWinBoll = null;
|
|
||||||
for (Map.Entry<String, IWinBollActivity> entity : _mapIWinBollList.entrySet()) {
|
|
||||||
if (entity.getKey().equals(iWinBoll.getTag())) {
|
|
||||||
bingo = true;
|
|
||||||
LogUtils.d(TAG, "bingo");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
preIWinBoll = entity.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bingo) {
|
|
||||||
return preIWinBoll;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 从管理列表中移除管理项
|
|
||||||
//
|
|
||||||
public <T extends IWinBollActivity> boolean registeRemove(T activity) {
|
|
||||||
IWinBollActivity iWinBollTest = _mapIWinBollList.get(activity.getTag());
|
|
||||||
if (iWinBollTest != null) {
|
|
||||||
_mapIWinBollList.remove(activity.getTag());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 打印管理列表项列表里的信息
|
|
||||||
//
|
|
||||||
public static void printIWinBollListInfo() {
|
|
||||||
//LogUtils.d(TAG, "printAvtivityListInfo");
|
|
||||||
if (!_mapIWinBollList.isEmpty()) {
|
|
||||||
StringBuilder sb = new StringBuilder("Map entries : " + Integer.toString(_mapIWinBollList.size()));
|
|
||||||
Iterator<Map.Entry<String, IWinBollActivity>> iterator = _mapIWinBollList.entrySet().iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
Map.Entry<String, IWinBollActivity> entry = iterator.next();
|
|
||||||
sb.append("\nKey: " + entry.getKey() + ", \nValue: " + entry.getValue().getTag());
|
|
||||||
//ToastUtils.show("\nKey: " + entry.getKey() + ", Value: " + entry.getValue().getTag());
|
|
||||||
}
|
|
||||||
sb.append("\nMap entries end.");
|
|
||||||
LogUtils.d(TAG, sb.toString());
|
|
||||||
} else {
|
|
||||||
LogUtils.d(TAG, "The map is empty.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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) {
|
||||||
|
}
|
||||||
|
};*/
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_horizontal">
|
android:gravity="center_horizontal">
|
||||||
|
|
||||||
<cc.winboll.studio.libapputils.view.WinBollServiceStatusView
|
<cc.winboll.studio.libaes.winboll.WinBollServiceStatusView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/viewaboutdevWinBollServiceStatusView1"/>
|
android:id="@+id/viewaboutdevWinBollServiceStatusView1"/>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_horizontal">
|
android:gravity="center_horizontal">
|
||||||
|
|
||||||
<cc.winboll.studio.libapputils.view.WinBollServiceStatusView
|
<cc.winboll.studio.libaes.winboll.WinBollServiceStatusView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/viewaboutwwwWinBollServiceStatusView1"/>
|
android:id="@+id/viewaboutwwwWinBollServiceStatusView1"/>
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
android:title="TestAppCrash"/>
|
android:title="TestAppCrash"/>
|
||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
|
<item
|
||||||
|
android:id="@+id/item_log"
|
||||||
|
android:title="Log"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/item_about"
|
android:id="@+id/item_about"
|
||||||
android:title="About"/>
|
android:title="About"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user