更新类库,BugFix。
This commit is contained in:
		| @@ -1,60 +0,0 @@ | ||||
| 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; | ||||
| import android.view.MenuItem; | ||||
|  | ||||
| /** | ||||
|  * @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())); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         if(item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
| } | ||||
| @@ -1,81 +0,0 @@ | ||||
| package cc.winboll.studio.appbase; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@AliYun.Com | ||||
|  * @Date 2025/03/28 15:34:16 | ||||
|  * @Describe 应用活动窗口基类 | ||||
|  */ | ||||
| import android.app.Activity; | ||||
| import android.os.Bundle; | ||||
| import android.os.PersistableBundle; | ||||
| import android.view.MenuItem; | ||||
| import cc.winboll.studio.appbase.App; | ||||
| import cc.winboll.studio.appbase.R; | ||||
| import cc.winboll.studio.libappbase.GlobalApplication; | ||||
| import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog; | ||||
| import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; | ||||
| import cc.winboll.studio.libappbase.winboll.WinBoLLActivityManager; | ||||
|  | ||||
| public class WinBoLLActivityBase extends Activity implements IWinBoLLActivity { | ||||
|  | ||||
|     public static final String TAG = "WinBoLLActivityBase"; | ||||
|  | ||||
|     @Override | ||||
|     public Activity getActivity() { | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getTag() { | ||||
|         return TAG; | ||||
|     } | ||||
|  | ||||
|     WinBoLLActivityManager getWinBoLLActivityManager() { | ||||
|         return WinBoLLActivityManager.getInstance(GlobalApplication.getInstance()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         getWinBoLLActivityManager().add(this); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) { | ||||
|         super.onPostCreate(savedInstanceState, persistentState); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_log) { | ||||
|             GlobalApplication.getWinBoLLActivityManager().startLogActivity(this); | ||||
|             return true; | ||||
|         } else if(item.getItemId() == cc.winboll.studio.appbase.R.id.item_minimal) { | ||||
|             //moveTaskToBack(true); | ||||
|             exit(); | ||||
|         } | ||||
|         // 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。 | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
|  | ||||
|     void exit() { | ||||
|         YesNoAlertDialog.show(this, "Exit " + getString(R.string.app_name), "Close all activity and exit?", new YesNoAlertDialog.OnDialogResultListener(){ | ||||
|  | ||||
|                 @Override | ||||
|                 public void onYes() { | ||||
|                     App.getWinBoLLActivityManager().finishAll(); | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void onNo() { | ||||
|                 } | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         getWinBoLLActivityManager().registeRemove(this); | ||||
|     } | ||||
| } | ||||
| @@ -1,72 +0,0 @@ | ||||
| package cc.winboll.studio.appbase.models; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@AliYun.Com | ||||
|  * @Date 2025/02/17 10:05:09 | ||||
|  * @Describe APPSOSReportBean | ||||
|  */ | ||||
| import android.util.JsonReader; | ||||
| import android.util.JsonWriter; | ||||
| import cc.winboll.studio.libappbase.BaseBean; | ||||
| import java.io.IOException; | ||||
|  | ||||
| public class WinBoLLNewsBean extends BaseBean { | ||||
|      | ||||
|     public static final String TAG = "WinBoLLNewsBean"; | ||||
|      | ||||
|     protected String message; | ||||
|      | ||||
|     public WinBoLLNewsBean() { | ||||
|         this.message = ""; | ||||
|     } | ||||
|  | ||||
|     public WinBoLLNewsBean(String message) { | ||||
|         this.message = message; | ||||
|     } | ||||
|  | ||||
|     public void setMessage(String message) { | ||||
|         this.message = message; | ||||
|     } | ||||
|  | ||||
|     public String getMessage() { | ||||
|         return message; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getName() { | ||||
|         return WinBoLLNewsBean.class.getName(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { | ||||
|         super.writeThisToJsonWriter(jsonWriter); | ||||
|         jsonWriter.name("message").value(getMessage()); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException { | ||||
|         if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else { | ||||
|             if (name.equals("message")) { | ||||
|                 setMessage(jsonReader.nextString()); | ||||
|             } 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,51 +0,0 @@ | ||||
| package cc.winboll.studio.apputils; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@AliYun.Com | ||||
|  * @Date 2025/03/28 17:11:37 | ||||
|  * @Describe 应用活动窗口基类 | ||||
|  */ | ||||
| import android.app.Activity; | ||||
| import android.os.Bundle; | ||||
| import android.os.PersistableBundle; | ||||
| import cc.winboll.studio.libappbase.GlobalApplication; | ||||
| import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity; | ||||
| import cc.winboll.studio.libappbase.winboll.WinBoLLActivityManager; | ||||
|  | ||||
| public class WinBoLLActivityBase extends Activity implements IWinBoLLActivity { | ||||
|  | ||||
|     public static final String TAG = "WinBoLLActivityBase"; | ||||
|  | ||||
|     @Override | ||||
|     public Activity getActivity() { | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getTag() { | ||||
|         return TAG; | ||||
|     } | ||||
|  | ||||
|     WinBoLLActivityManager getWinBoLLActivityManager() { | ||||
|         return WinBoLLActivityManager.getInstance(GlobalApplication.getInstance()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         getWinBoLLActivityManager().add(this); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) { | ||||
|         super.onPostCreate(savedInstanceState, persistentState); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     protected void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         getWinBoLLActivityManager().registeRemove(this); | ||||
|     } | ||||
| } | ||||
| @@ -18,13 +18,13 @@ def genVersionName(def versionName){ | ||||
| } | ||||
|  | ||||
| android { | ||||
|     compileSdkVersion 30 | ||||
|     buildToolsVersion "30.0.3" | ||||
|     compileSdkVersion 32 | ||||
|     buildToolsVersion "32.0.0" | ||||
|  | ||||
|     defaultConfig { | ||||
|         applicationId "cc.winboll.studio.autoinstaller" | ||||
|         minSdkVersion 26 | ||||
|         targetSdkVersion 29 | ||||
|         minSdkVersion 24 | ||||
|         targetSdkVersion 30 | ||||
|         versionCode 2 | ||||
|         // versionName 更新后需要手动设置  | ||||
|         // .winboll/winbollBuildProps.properties 文件的 stageCount=0 | ||||
| @@ -45,6 +45,9 @@ android { | ||||
|  | ||||
| dependencies { | ||||
|     api fileTree(dir: 'libs', include: ['*.jar']) | ||||
|     api 'cc.winboll.studio:libaes:15.6.0' | ||||
|     api 'cc.winboll.studio:libapputils:15.3.4' | ||||
|     api 'cc.winboll.studio:libappbase:15.7.6' | ||||
|      | ||||
|     // SSH | ||||
|     api 'com.jcraft:jsch:0.1.55' | ||||
| @@ -67,7 +70,4 @@ dependencies { | ||||
|     //api 'androidx.vectordrawable:vectordrawable-animated:1.1.0' | ||||
|     //api 'androidx.fragment:fragment:1.1.0' | ||||
|      | ||||
|     api 'cc.winboll.studio:libaes:15.2.5' | ||||
|     api 'cc.winboll.studio:libapputils:15.2.1' | ||||
|     api 'cc.winboll.studio:libappbase:15.2.2' | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| #Created by .winboll/winboll_app_build.gradle | ||||
| #Tue Apr 15 10:20:33 GMT 2025 | ||||
| #Sat May 03 03:51:17 GMT 2025 | ||||
| stageCount=1 | ||||
| libraryProject= | ||||
| baseVersion=15.2 | ||||
| publishVersion=15.2.0 | ||||
| buildCount=55 | ||||
| buildCount=59 | ||||
| baseBetaVersion=15.2.1 | ||||
|   | ||||
| @@ -6,9 +6,9 @@ package cc.winboll.studio.autoinstaller; | ||||
|  * @Describe 全局应用类 | ||||
|  */ | ||||
| import android.view.Gravity; | ||||
| import cc.winboll.studio.autoinstaller.R; | ||||
| import cc.winboll.studio.libappbase.GlobalApplication; | ||||
| import com.hjq.toast.ToastUtils; | ||||
| import com.hjq.toast.style.WhiteToastStyle; | ||||
|  | ||||
| public class App extends GlobalApplication { | ||||
|      | ||||
| @@ -21,8 +21,8 @@ public class App extends GlobalApplication { | ||||
|         // 初始化 Toast 框架 | ||||
|         ToastUtils.init(this); | ||||
|         // 设置 Toast 布局样式 | ||||
|         ToastUtils.setView(R.layout.view_toast); | ||||
|         //ToastUtils.setStyle(new WhiteToastStyle()); | ||||
|         //ToastUtils.setView(R.layout.view_toast); | ||||
|         ToastUtils.setStyle(new WhiteToastStyle()); | ||||
|         ToastUtils.setGravity(Gravity.BOTTOM, 0, 200); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -154,10 +154,13 @@ public class AppConfigs implements Serializable { | ||||
|         try { | ||||
|             String szJson = FileUtil.readFile(getDataPath(context.getApplicationContext())); | ||||
|             appConfigs = AppConfigs.getInstance(mContext).parseAppConfigs(szJson); | ||||
|             if(appConfigs != null) { | ||||
|                 _AppConfigs = appConfigs; | ||||
|             } | ||||
|         } catch (IOException e) { | ||||
|             LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return appConfigs; | ||||
|         return _AppConfigs; | ||||
|     } | ||||
|  | ||||
|     public void saveAppConfigs(Context context, AppConfigs appConfigs) { | ||||
|   | ||||
| @@ -1,17 +0,0 @@ | ||||
| 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,192 +0,0 @@ | ||||
| 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; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,78 +0,0 @@ | ||||
| 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); | ||||
|     } | ||||
| } | ||||
| @@ -1,22 +0,0 @@ | ||||
| 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; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,106 +0,0 @@ | ||||
| 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()); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|     } | ||||
| } | ||||
| @@ -1,473 +0,0 @@ | ||||
| package cc.winboll.studio.libaes.winboll; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@AliYun.Com | ||||
|  * @Date 2025/03/28 17:41:55 | ||||
|  * @Describe WinBoLL 服务主机连接状态视图 | ||||
|  */ | ||||
| import cc.winboll.studio.libaes.R; | ||||
| 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.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) { | ||||
|      } | ||||
|      };*/ | ||||
| } | ||||
| @@ -1,39 +0,0 @@ | ||||
| package cc.winboll.studio.libappbase.sos; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@AliYun.Com | ||||
|  * @Date 2025/03/02 09:54:28 | ||||
|  * @Describe WinBoLL 系列应用通用管理类 | ||||
|  */ | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import cc.winboll.studio.libappbase.LogUtils; | ||||
|  | ||||
| public class WinBoLL { | ||||
|  | ||||
|     public static final String TAG = "WinBoLL"; | ||||
|  | ||||
|     public static final String ACTION_BIND = WinBoLL.class.getName() + ".ACTION_BIND"; | ||||
|     public static final String EXTRA_APPMODEL = "EXTRA_APPMODEL"; | ||||
|  | ||||
|     public static void bindToAPPBase(Context context, String appMainService) { | ||||
|         LogUtils.d(TAG, "bindToAPPBase(...)"); | ||||
|         String toPackage = "cc.winboll.studio.appbase"; | ||||
|         startBind(context, toPackage, appMainService); | ||||
|     } | ||||
|  | ||||
|     public static void bindToAPPBaseBeta(Context context, String appMainService) { | ||||
|         LogUtils.d(TAG, "bindToAPPBaseBeta(...)"); | ||||
|         String toPackage = "cc.winboll.studio.appbase.beta"; | ||||
|         startBind(context, toPackage, appMainService); | ||||
|     } | ||||
|  | ||||
|     static void startBind(Context context, String toPackage, String appMainService) { | ||||
|         Intent intent = new Intent(ACTION_BIND); | ||||
|         intent.putExtra(EXTRA_APPMODEL, (new APPModel(toPackage, appMainService)).toString()); | ||||
|         intent.setPackage(toPackage); | ||||
|         LogUtils.d(TAG, String.format("ACTION_BIND :\nTo Package : %s\nAPP Main Service : %s", toPackage, appMainService)); | ||||
|         context.sendBroadcast(intent); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,18 +0,0 @@ | ||||
| package cc.winboll.studio.libappbase.winboll; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@AliYun.Com | ||||
|  * @Date 2025/03/24 08:23:40 | ||||
|  * @Describe WinBoLL 活动窗口通用接口 | ||||
|  */ | ||||
| import android.app.Activity; | ||||
| import android.widget.Toolbar; | ||||
|  | ||||
| public interface IWinBoLLActivity { | ||||
|  | ||||
|     public static final String TAG = "IWinBoLLActivity"; | ||||
|  | ||||
|     // 获取活动窗口 | ||||
|     abstract public Activity getActivity(); | ||||
|     abstract public String getTag(); | ||||
| } | ||||
| @@ -1,356 +0,0 @@ | ||||
| package cc.winboll.studio.libappbase.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.GlobalApplication; | ||||
| import cc.winboll.studio.libappbase.LogUtils; | ||||
| import cc.winboll.studio.libappbase.utils.ToastUtils; | ||||
| 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 // 退出应用后,清理所有最近任务栏任务记录窗口 | ||||
|         }; | ||||
|  | ||||
|     // 应用类型标志 | ||||
|     static volatile WinBoLLUI_TYPE _mWinBoLLUI_TYPE = WinBoLLUI_TYPE.Service; | ||||
|  | ||||
|     GlobalApplication mGlobalApplication; | ||||
|     static volatile WinBoLLActivityManager _Instance; | ||||
|     static volatile Map<String, IWinBoLLActivity> _mapIWinBoLLList; | ||||
|     volatile IWinBoLLActivity mFirstIWinBoLLActivity; | ||||
|  | ||||
|     WinBoLLActivityManager(GlobalApplication application) { | ||||
|         mGlobalApplication = application; | ||||
|         _mapIWinBoLLList = new HashMap<String, IWinBoLLActivity>(); | ||||
|     } | ||||
|  | ||||
|     public static synchronized WinBoLLActivityManager getInstance(GlobalApplication application) { | ||||
|         LogUtils.d(TAG, "getInstance"); | ||||
|         if (_Instance == null) { | ||||
|             LogUtils.d(TAG, "_Instance == null"); | ||||
|             _Instance = new WinBoLLActivityManager(application); | ||||
|         } | ||||
|         return _Instance; | ||||
|     } | ||||
|  | ||||
|     // | ||||
|     // 设置 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) { | ||||
|         String tag = ((IWinBoLLActivity)iWinBoLL).getTag(); | ||||
|         LogUtils.d(TAG, String.format("add(T iWinBoLL) tag is %s", tag)); | ||||
|         if (isActive(tag)) { | ||||
|             LogUtils.d(TAG, String.format("isActive(tag) is true, tag : %s.", tag)); | ||||
|         } else { | ||||
|             // 设置起始活动窗口,以便最后退出时提问 | ||||
|             if (mFirstIWinBoLLActivity == null && _mapIWinBoLLList.size() == 0) { | ||||
|                 LogUtils.d(TAG, "Set firstIWinBoLLActivity, iWinBoLL.getTag() is %s" + iWinBoLL.getTag()); | ||||
|                 mFirstIWinBoLLActivity = 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 = ((IWinBoLLActivity)clazz.newInstance()).getTag(); | ||||
|             LogUtils.d(TAG, String.format("startWinBoLLActivity(Context context, Class<T> clazz) tag is %s", tag)); | ||||
|             if (isActive(tag)) { | ||||
|                 resumeActivity(context, tag); | ||||
|                 return; | ||||
|             } | ||||
|             //ToastUtils.show("startWinBoLLActivity(Context context, Class<T> clazz)"); | ||||
|  | ||||
|             // 新建一个任务窗口 | ||||
|             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); | ||||
|             context.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 = ((IWinBoLLActivity)clazz.newInstance()).getTag(); | ||||
|             LogUtils.d(TAG, String.format("startWinBoLLActivity(Context context, Intent intent, Class<T> clazz) tag is %s", tag)); | ||||
|             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); | ||||
|             context.startActivity(intent); | ||||
|         } catch (InstantiationException | IllegalAccessException e) { | ||||
|             LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public <T extends IWinBoLLActivity> void startLogActivity(Context context) { | ||||
|         // 如果窗口已存在就重启窗口 | ||||
|         String tag = LogActivity.TAG; | ||||
|         if (isActive(tag)) { | ||||
|             resumeActivity(context, tag); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 新建一个任务窗口 | ||||
|         Intent intent = new Intent(context, LogActivity.class); | ||||
|         //打开多任务窗口 flags | ||||
|         // Define the bounds. | ||||
| //        Rect bounds = new Rect(0, 0, 800, 200); | ||||
| //        // Set the bounds as an activity option. | ||||
| //        ActivityOptions options = ActivityOptions.makeBasic(); | ||||
| //        options.setLaunchBounds(bounds); | ||||
|         intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT); | ||||
|         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||||
|         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); | ||||
|         intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); | ||||
|  | ||||
|         intent.putExtra(EXTRA_TAG, tag); | ||||
|  | ||||
|         //context.startActivity(intent, options.toBundle()); | ||||
|         context.startActivity(intent); | ||||
|     } | ||||
|  | ||||
|     public boolean isFirstIWinBoLLActivity(IWinBoLLActivity iWinBoLLActivity) { | ||||
|         return mFirstIWinBoLLActivity != null && mFirstIWinBoLLActivity == iWinBoLLActivity; | ||||
|     } | ||||
|  | ||||
|     // | ||||
|     // 判断 tag绑定的 MyActivity是否存在 | ||||
|     // | ||||
|     public boolean isActive(String tag) { | ||||
|         LogUtils.d(TAG, String.format("isActive(String tag) tag is %s", tag)); | ||||
|         //printIWinBoLLListInfo(); | ||||
|         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(...) iWinBoLL is null tag by %s", tag)); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static IWinBoLLActivity getIWinBoLL(String tag) { | ||||
|         LogUtils.d(TAG, String.format("getIWinBoLL(String tag) %s", tag)); | ||||
|         return _mapIWinBoLLList.get(tag); | ||||
|     } | ||||
|  | ||||
|     // | ||||
|     // 找到tag 绑定的 BaseActivity ,通过 getTaskId() 移动到前台 | ||||
|     // | ||||
|     public <T extends IWinBoLLActivity> void resumeActivity(Context context, String tag) { | ||||
|         LogUtils.d(TAG, "resumeActivity(Context context, String tag)"); | ||||
|         T iWinBoLL = (T)getIWinBoLL(tag); | ||||
|         LogUtils.d(TAG, String.format("iWinBoLL.getTag() %s", iWinBoLL.getTag())); | ||||
|         //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) { | ||||
|         LogUtils.d(TAG, "resumeActivity(Context context, T iWinBoLL)"); | ||||
|         ActivityManager am = (ActivityManager) mGlobalApplication.getSystemService(Context.ACTIVITY_SERVICE); | ||||
|         //返回启动它的根任务(home 或者 MainActivity) | ||||
|         Intent intent = new Intent(mGlobalApplication, iWinBoLL.getClass()); | ||||
|         TaskStackBuilder stackBuilder = TaskStackBuilder.create(mGlobalApplication); | ||||
|         stackBuilder.addNextIntentWithParentStack(intent); | ||||
|         stackBuilder.startActivities(); | ||||
|         //moveTaskToFront(YourTaskId, 0); | ||||
|         //ToastUtils.show("resumeActivity am.moveTaskToFront"); | ||||
|         LogUtils.d(TAG, String.format("iWinBoLL.getActivity().getTaskId() %d", iWinBoLL.getActivity().getTaskId())); | ||||
|         am.moveTaskToFront(iWinBoLL.getActivity().getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION); | ||||
|         LogUtils.d(TAG, "am.moveTaskToFront"); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // | ||||
|     // 结束所有 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(mGlobalApplication, 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."); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 ZhanGSKen
					ZhanGSKen