diff --git a/apputils/build.gradle b/apputils/build.gradle index 6e1573e..bb401fa 100644 --- a/apputils/build.gradle +++ b/apputils/build.gradle @@ -18,18 +18,18 @@ def genVersionName(def versionName){ } android { - compileSdkVersion 32 - buildToolsVersion "33.0.3" + compileSdkVersion 30 + buildToolsVersion "30.0.3" defaultConfig { applicationId "cc.winboll.studio.apputils" - minSdkVersion 21 - targetSdkVersion 30 + minSdkVersion 26 + targetSdkVersion 29 versionCode 1 // versionName 更新后需要手动设置 // 项目模块目录的 build.gradle 文件的 stageCount=0 // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" - versionName "9.2" + versionName "9.4" if(true) { versionName = genVersionName("${versionName}") } @@ -50,6 +50,29 @@ android { dependencies { api project(':libapputils') - api 'cc.winboll.studio:libappbase:1.0.3' api fileTree(dir: 'libs', include: ['*.jar']) + + // SSH + implementation 'com.jcraft:jsch:0.1.55' + // Html 解析 + implementation 'org.jsoup:jsoup:1.13.1' + // 二维码类库 + implementation 'com.google.zxing:core:3.4.1' + implementation 'com.journeyapps:zxing-android-embedded:3.6.0' + // 应用介绍页类库 + implementation 'io.github.medyo:android-about-page:2.0.0' + // 吐司类库 + implementation 'com.github.getActivity:ToastUtils:10.5' + // 网络连接类库 + implementation 'com.squareup.okhttp3:okhttp:4.4.1' + + // Android 类库 + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.viewpager:viewpager:1.0.0' + implementation 'androidx.vectordrawable:vectordrawable:1.1.0' + implementation 'androidx.vectordrawable:vectordrawable-animated:1.1.0' + implementation 'androidx.fragment:fragment:1.1.0' + implementation 'com.google.android.material:material:1.4.0' + + implementation 'cc.winboll.studio:libappbase:2.1.3' } diff --git a/apputils/build.properties b/apputils/build.properties index 9d55320..5d866f4 100644 --- a/apputils/build.properties +++ b/apputils/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sat Jan 18 13:03:10 HKT 2025 -stageCount=2 +#Sun Mar 09 09:20:53 HKT 2025 +stageCount=4 libraryProject=libapputils -baseVersion=9.2 -publishVersion=9.2.1 +baseVersion=9.4 +publishVersion=9.4.3 buildCount=0 -baseBetaVersion=9.2.2 +baseBetaVersion=9.4.4 diff --git a/apputils/src/main/AndroidManifest.xml b/apputils/src/main/AndroidManifest.xml index 1a0c9c3..05d695a 100644 --- a/apputils/src/main/AndroidManifest.xml +++ b/apputils/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ android:allowBackup="true" android:icon="@drawable/ic_winboll" android:label="@string/app_name" - android:theme="@style/WinBoll.SupportThemeNoActionBar" + android:theme="@style/MyAppTheme" android:supportsRtl="true"> - - - \ No newline at end of file + diff --git a/apputils/src/main/java/cc/winboll/studio/apputils/App.java b/apputils/src/main/java/cc/winboll/studio/apputils/App.java index ca55cce..165e0e2 100644 --- a/apputils/src/main/java/cc/winboll/studio/apputils/App.java +++ b/apputils/src/main/java/cc/winboll/studio/apputils/App.java @@ -5,27 +5,83 @@ package cc.winboll.studio.apputils; * @Date 2024/12/08 15:10:51 * @Describe 全局应用类 */ -import android.view.Gravity; -import cc.winboll.studio.libapputils.app.WinBollApplication; -import com.hjq.toast.ToastUtils; -import com.hjq.toast.style.WhiteToastStyle; +import android.app.Application; +import android.content.Context; +import android.widget.Toast; +import cc.winboll.studio.libappbase.GlobalApplication; +import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.libapputils.app.MyActivityLifecycleCallbacks; +import cc.winboll.studio.libapputils.app.WinBollActivityManager; +import cc.winboll.studio.libapputils.bean.DebugBean; -public class App extends WinBollApplication { +public class App extends GlobalApplication { public static final String TAG = "App"; - public static final String _ACTION_DEBUGVIEW = WinBollApplication.class.getName() + "_ACTION_DEBUGVIEW"; + public static final String _ACTION_DEBUGVIEW = App.class.getName() + "_ACTION_DEBUGVIEW"; + + //static volatile WinBollApplication _WinBollApplication = null; + MyActivityLifecycleCallbacks mMyActivityLifecycleCallbacks; + + // 标记当前应用是否处于调试状态 + static volatile boolean isDebug = false; + + public synchronized static void setIsDebug(boolean isDebug) { + App.isDebug = isDebug; + } + + public static boolean isDebug() { + return isDebug; + } + + MyActivityLifecycleCallbacks getMyActivityLifecycleCallbacks() { + return mMyActivityLifecycleCallbacks; + } + + @Override + public Context getApplicationContext() { + return super.getApplicationContext(); + } + + @Override + public Application getApplication() { + return this; + } @Override public void onCreate() { super.onCreate(); - // 初始化 Toast 框架 + // 应用环境初始化, 基本调试环境 // - ToastUtils.init(this); - // 设置 Toast 布局样式 - //ToastUtils.setView(R.layout.view_toast); - ToastUtils.setStyle(new WhiteToastStyle()); - ToastUtils.setGravity(Gravity.BOTTOM, 0, 200); - } + // 初始化日志模块 + //LogUtils.init(this); + try { + // 初始化 Toast 框架 +// ToastUtils.init(this); +// // 设置 Toast 布局样式 +// //ToastUtils.setView(R.layout.view_toast); +// ToastUtils.setStyle(new WhiteToastStyle()); +// ToastUtils.setGravity(Gravity.BOTTOM, 0, 200); + // 设置应用调试标志 + DebugBean debugBean = DebugBean.loadBean(this, DebugBean.class); + if (debugBean == null) { + //ToastUtils.show("debugBean == null"); + setIsDebug(false); + } else { + //ToastUtils.show("saveDebugStatus(" + String.valueOf(debugBean.isDebuging()) + ")"); + setIsDebug(debugBean.isDebuging()); + } + // 应用窗口管理模块参数设置 + // + mMyActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks(); + registerActivityLifecycleCallbacks(mMyActivityLifecycleCallbacks); + // 设置默认 WinBoll 应用 UI 类型 + WinBollActivityManager.getInstance(this).setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Service); + //ToastUtils.show("WinBollUI_TYPE " + getWinBollUI_TYPE()); + } catch (Exception e) { + LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); + Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } } diff --git a/apputils/src/main/java/cc/winboll/studio/apputils/MainActivity.java b/apputils/src/main/java/cc/winboll/studio/apputils/MainActivity.java index 49963b5..5e69ad2 100644 --- a/apputils/src/main/java/cc/winboll/studio/apputils/MainActivity.java +++ b/apputils/src/main/java/cc/winboll/studio/apputils/MainActivity.java @@ -1,28 +1,83 @@ package cc.winboll.studio.apputils; +import android.content.ComponentName; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import cc.winboll.studio.apputils.R; +import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.libappbase.LogView; import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity; +import cc.winboll.studio.libapputils.activities.LogActivity; import cc.winboll.studio.libapputils.activities.QRCodeDecodeActivity; -import cc.winboll.studio.libapputils.app.WinBollActivity; +import cc.winboll.studio.libapputils.app.AboutActivityFactory; +import cc.winboll.studio.libapputils.app.IWinBollActivity; import cc.winboll.studio.libapputils.app.WinBollActivityManager; -import cc.winboll.studio.libapputils.log.LogActivity; -import cc.winboll.studio.libapputils.log.LogUtils; +import cc.winboll.studio.libapputils.bean.APPInfo; +import cc.winboll.studio.libapputils.view.AboutView; +import cc.winboll.studio.libapputils.view.YesNoAlertDialog; import com.hjq.toast.ToastUtils; +import java.util.List; +import java.util.Set; -final public class MainActivity extends WinBollActivity { +final public class MainActivity extends AppCompatActivity implements IWinBollActivity { public static final String TAG = "MainActivity"; public static final int REQUEST_QRCODEDECODE_ACTIVITY = 0; + Toolbar mToolbar; + LogView mLogView; + @Override - protected boolean isEnableDisplayHomeAsUp() { + public AppCompatActivity getActivity() { + return this; + } + + @Override + public APPInfo getAppInfo() { + String szBranchName = "apputils"; + + APPInfo appInfo = AboutActivityFactory.buildDefaultAPPInfo(); + appInfo.setAppName("APPUtils"); + appInfo.setAppIcon(cc.winboll.studio.libapputils.R.drawable.ic_winboll); + appInfo.setAppDescription("APPUtils Description"); + appInfo.setAppGitName("APP"); + appInfo.setAppGitOwner("Studio"); + appInfo.setAppGitAPPBranch(szBranchName); + appInfo.setAppGitAPPSubProjectFolder(szBranchName); + appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=APP"); + appInfo.setAppAPKName("APPUtils"); + appInfo.setAppAPKFolderName("APPUtils"); + return appInfo; + //return null; + } + + @Override + public String getTag() { + return TAG; + } + + @Override + public boolean isAddWinBollToolBar() { + return true; + } + + @Override + public Toolbar initToolBar() { + return findViewById(R.id.activitymainToolbar1); + } + + @Override + public boolean isEnableDisplayHomeAsUp() { return false; } @@ -31,8 +86,22 @@ final public class MainActivity extends WinBollActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - //Toolbar toolbar = findViewById(R.id.activitymainToolbar1); - //setActionBar(toolbar); + mLogView = findViewById(R.id.logview); + mLogView.start(); + + // 初始化工具栏 + mToolbar = findViewById(R.id.activitymainToolbar1); + setSupportActionBar(mToolbar); + if (isEnableDisplayHomeAsUp()) { + // 显示后退按钮 + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + getSupportActionBar().setSubtitle(getTag()); + + checkResolveActivity(); + archiveInstance(); + + // 接收并处理 Intent 数据,函数 Intent 处理接收就直接返回 //if (prosessIntents(getIntent())) return; @@ -44,44 +113,94 @@ final public class MainActivity extends WinBollActivity { // LogUtils.d(TAG, "BuildConfig.DEBUG : " + Boolean.toString(BuildConfig.DEBUG)); } + boolean checkResolveActivity() { + PackageManager packageManager = getPackageManager(); + //Intent intent = new Intent("your_action_here"); + Intent intent = getIntent(); + if (intent != null) { + List resolveInfoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); + if (resolveInfoList.size() > 0) { + // 传入的Intent action在Activity清单的intent-filter的action节点里有定义 + if (intent.getAction() != null) { + if (intent.getAction().equals(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW)) { + App.setIsDebug(true); + //ToastUtils.show!("WinBollApplication.setIsDebug(true) by action : " + intent.getAction()); + + } + } + return true; + } else { + // 传入的Intent action在Activity清单的intent-filter的action节点里没有定义 + //ToastUtils.show("false : " + intent.getAction()); + return false; + } + + } + + // action在清单文件中没有声明 + ToastUtils.show("false"); + return false; + } + + void archiveInstance() { + Intent intent = getIntent(); + StringBuilder sb = new StringBuilder("\n### Archive Instance ###\n"); + + if (intent != null) { + ComponentName componentName = intent.getComponent(); + if (componentName != null) { + String packageName = componentName.getPackageName(); + //Log.d("AppStarter", "启动本应用的应用包名: " + packageName); + sb.append("启动本应用的应用包名: \n" + packageName); + } + + sb.append("\nImplicit Intent Tracker :\n接收到的 Intent 动作: \n" + intent.getAction()); + Set categories = intent.getCategories(); + if (categories != null) { + for (String category : categories) { + sb.append("\n接收到的 Intent 类别 :\n" + category); + } + } + Uri data = intent.getData(); + if (data != null) { + sb.append("\n接收到的 Intent 数据 :\n" + data.toString()); + } + } else { + sb.append("Intent is null."); + } + sb.append("\n\n"); + LogUtils.d(TAG, sb.toString()); + } + + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + // 缓存当前 activity + WinBollActivityManager.getInstance(this).add(this); + } + + @Override + public void onDestroy() { + WinBollActivityManager.getInstance(this).registeRemove(this); + super.onDestroy(); + } + public void onTestLogClick(View view) { LogUtils.d(TAG, "onTestLogClick"); Toast.makeText(getApplication(), "onTestLogClick", Toast.LENGTH_SHORT).show(); } public void onLogUtilsClick(View view) { - Intent intent = new Intent(this, LogActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); - intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - startActivity(intent); - } +// Intent intent = new Intent(this, LogActivity.class); +// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); +// intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); +// startActivity(intent); - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); -// setSubTitle(""); + //WinBollActivityManager.getInstance().printAvtivityListInfo(); + WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class); } - @Override - public void onBackPressed() { -// exit(); - } - -// void exit() { -// YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){ -// -// @Override -// public void onYes() { -// WinBollActivityManager.getInstance(getApplicationContext()).finishAll(); -// } -// -// @Override -// public void onNo() { -// } -// }; -// YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener); -// } - // // 处理传入的 Intent 数据 // @@ -125,58 +244,108 @@ final public class MainActivity extends WinBollActivity { return true; } - @Override - public String getTag() { - return TAG; - } - - @Override - protected boolean isAddWinBollToolBar() { - return true; - } - - @Override - protected Toolbar initToolBar() { - return findViewById(R.id.activitymainToolbar1); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { + //ToastUtils.show("onCreateOptionsMenu"); getMenuInflater().inflate(R.menu.toolbar_main, menu); + if (isAddWinBollToolBar()) { + //ToastUtils.show("mIWinBoll.isAddWinBollToolBar()"); + getMenuInflater().inflate(R.menu.toolbar_winboll_shared_main, menu); + } + if (App.isDebug()) { + getMenuInflater().inflate(R.menu.toolbar_studio_debug, menu); + } + return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.item_testwinboll) { - WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestWinBollActivity.class); + if (item.getItemId() == R.id.item_exit) { + exit(); + return true; + } else if (item.getItemId() == R.id.item_about) { + AboutActivityFactory.showAboutActivity(this, getAppInfo()); + return true; } else if (item.getItemId() == R.id.item_teststringtoqrcodeview) { WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestStringToQrCodeViewActivity.class); } else if (item.getItemId() == R.id.item_testqrcodedecodeactivity) { Intent intent = new Intent(this, QRCodeDecodeActivity.class); startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY); + } else if (item.getItemId() == R.id.item_testcrashreport) { + for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) { + getString(i); + } + return true; + } else if (item.getItemId() == R.id.item_log) { + WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class); + return true; + } else if (item.getItemId() == R.id.item_exitdebug) { + AboutView.setApp2NormalMode(this); + return true; + } else if (item.getItemId() == android.R.id.home) { + WinBollActivityManager.getInstance(this).finish(this); + return true; } return super.onOptionsItemSelected(item); } + void about() { +// Intent intent = new Intent(this, AboutActivity.class); +// intent.putExtra(AboutActivity.EXTRA_APPINFO, AboutActivityFactory.buildAPPBranchInfo(this)); +// WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AboutActivity.class); + } + + void exit() { + YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){ + + @Override + public void onYes() { + WinBollActivityManager.getInstance(getApplicationContext()).finishAll(); + } + + @Override + public void onNo() { + } + }; + YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener); + + } + + @Override + public void onBackPressed() { + if (WinBollActivityManager.getInstance(getApplicationContext()).isFirstIWinBollActivity(this)) { + exit(); + } else { + WinBollActivityManager.getInstance(this).finish(this); + super.onBackPressed(); + } + } + + public void onTestAboutActivity(View view) { + about(); + } + public void onTestJavascriptHtmlActivity(View view) { Intent intent = new Intent(this, AssetsHtmlActivity.class); intent.putExtra(AssetsHtmlActivity.EXTRA_HTMLFILENAME, "javascript_test.html"); WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AssetsHtmlActivity.class); } - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case REQUEST_QRCODEDECODE_ACTIVITY : { - String text = data.getStringExtra(QRCodeDecodeActivity.EXTRA_RESULT); - ToastUtils.show(text); - break; - } - default : { - ToastUtils.show(String.format("%d, %d", requestCode, resultCode)); - super.onActivityResult(requestCode, resultCode, data); - } - } - } + /*@Override + protected void onActivithyResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case REQUEST_QRCODEDECODE_ACTIVITY : { + if (data != null) { + String text = data.getStringExtra(QRCodeDecodeActivity.EXTRA_RESULT); + ToastUtils.show(text); + } + break; + } + default : { + //ToastUtils.show(String.format("%d, %d", requestCode, resultCode)); + super.prosessActivityResult(requestCode, resultCode, data); + } + } + }*/ } diff --git a/apputils/src/main/java/cc/winboll/studio/apputils/TestStringToQrCodeViewActivity.java b/apputils/src/main/java/cc/winboll/studio/apputils/TestStringToQrCodeViewActivity.java index 06c80a3..6886697 100644 --- a/apputils/src/main/java/cc/winboll/studio/apputils/TestStringToQrCodeViewActivity.java +++ b/apputils/src/main/java/cc/winboll/studio/apputils/TestStringToQrCodeViewActivity.java @@ -1,37 +1,49 @@ package cc.winboll.studio.apputils; import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import cc.winboll.studio.libapputils.app.WinBollActivity; +import cc.winboll.studio.libapputils.app.IWinBollActivity; +import cc.winboll.studio.libapputils.bean.APPInfo; import cc.winboll.studio.libapputils.view.StringToQrCodeView; /** * @Author ZhanGSKen@QQ.COM * @Date 2025/01/17 19:50:46 */ -public class TestStringToQrCodeViewActivity extends WinBollActivity { - +public class TestStringToQrCodeViewActivity extends AppCompatActivity implements IWinBollActivity { + public static final String TAG = "TestStringToQrCodeViewActivity"; - + StringToQrCodeView mStringToQrCodeView; - + + @Override + public AppCompatActivity getActivity() { + return this; + } + + @Override + public APPInfo getAppInfo() { + return null; + } + @Override public String getTag() { return TAG; } @Override - protected Toolbar initToolBar() { + public Toolbar initToolBar() { return findViewById(R.id.activityteststringtoqrcodeviewToolbar1); } @Override - protected boolean isEnableDisplayHomeAsUp() { + public boolean isEnableDisplayHomeAsUp() { return true; } @Override - protected boolean isAddWinBollToolBar() { + public boolean isAddWinBollToolBar() { return true; } @@ -41,10 +53,4 @@ public class TestStringToQrCodeViewActivity extends WinBollActivity { setContentView(R.layout.activity_teststringtoqrcodeview); mStringToQrCodeView = findViewById(R.id.activityteststringtoqrcodeviewStringToQrCodeView1); } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - setSubTitle(TAG); - } } diff --git a/apputils/src/main/java/cc/winboll/studio/apputils/TestWinBollActivity.java b/apputils/src/main/java/cc/winboll/studio/apputils/TestWinBollActivity.java deleted file mode 100644 index 91bc4b4..0000000 --- a/apputils/src/main/java/cc/winboll/studio/apputils/TestWinBollActivity.java +++ /dev/null @@ -1,52 +0,0 @@ -package cc.winboll.studio.apputils; - -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import androidx.appcompat.widget.Toolbar; -import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity; -import cc.winboll.studio.libapputils.app.WinBollActivity; -import cc.winboll.studio.libapputils.app.WinBollActivityManager; - -/** - * @Author ZhanGSKen@QQ.COM - * @Date 2025/01/13 15:09:46 - */ -public class TestWinBollActivity extends WinBollActivity { - - public static final String TAG = "TestWinBollActivity"; - - @Override - public String getTag() { - return TAG; - } - - @Override - protected Toolbar initToolBar() { - return findViewById(R.id.activitytestwinbollToolbar1); - } - - @Override - protected boolean isEnableDisplayHomeAsUp() { - return true; - } - - @Override - protected boolean isAddWinBollToolBar() { - return true; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_testwinboll); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - setSubTitle(TAG); - } - - -} diff --git a/apputils/src/main/res/layout/activity_main.xml b/apputils/src/main/res/layout/activity_main.xml index ad57465..09c4a6d 100644 --- a/apputils/src/main/res/layout/activity_main.xml +++ b/apputils/src/main/res/layout/activity_main.xml @@ -27,7 +27,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TestLog" - android:textAllCaps="false" + android:textAllCaps="false" android:onClick="onTestLogClick"/>