调试代码,加入AES转移模块。
This commit is contained in:
@@ -45,6 +45,8 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
api 'com.google.code.gson:gson:2.10.1'
|
||||||
|
|
||||||
// SSH
|
// SSH
|
||||||
api 'com.jcraft:jsch:0.1.55'
|
api 'com.jcraft:jsch:0.1.55'
|
||||||
@@ -67,7 +69,7 @@ dependencies {
|
|||||||
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
||||||
//api 'androidx.fragment:fragment:1.1.0'
|
//api 'androidx.fragment:fragment:1.1.0'
|
||||||
|
|
||||||
api 'cc.winboll.studio:libaes:15.8.0'
|
api 'cc.winboll.studio:libaes:15.10.0'
|
||||||
api 'cc.winboll.studio:libapputils:15.8.2'
|
api 'cc.winboll.studio:libapputils:15.10.0'
|
||||||
api 'cc.winboll.studio:libappbase:15.8.2'
|
api 'cc.winboll.studio:libappbase:15.10.9'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package cc.winboll.studio.libaes.winboll;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/03/28 19:12:12
|
||||||
|
* @Describe 应用主要服务组件类守护进程服务组件类
|
||||||
|
*/
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import cc.winboll.studio.libaes.models.WinBoLLClientServiceBean;
|
||||||
|
import cc.winboll.studio.libaes.winboll.AssistantService;
|
||||||
|
import cc.winboll.studio.libapputils.utils.ServiceUtils;
|
||||||
|
|
||||||
|
public class AssistantService extends Service {
|
||||||
|
|
||||||
|
public final static String TAG = "AssistantService";
|
||||||
|
|
||||||
|
WinBoLLClientServiceBean mWinBoLLServiceBean;
|
||||||
|
MyServiceConnection mMyServiceConnection;
|
||||||
|
volatile boolean mIsServiceRunning;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
mWinBoLLServiceBean = WinBoLLClientServiceBean.loadWinBoLLClientServiceBean(this);
|
||||||
|
if (mMyServiceConnection == null) {
|
||||||
|
mMyServiceConnection = new MyServiceConnection();
|
||||||
|
}
|
||||||
|
// 设置运行参数
|
||||||
|
mIsServiceRunning = false;
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
run();
|
||||||
|
return START_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
mIsServiceRunning = false;
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 运行服务内容
|
||||||
|
//
|
||||||
|
void run() {
|
||||||
|
mWinBoLLServiceBean = WinBoLLClientServiceBean.loadWinBoLLClientServiceBean(this);
|
||||||
|
if (mWinBoLLServiceBean.isEnable()) {
|
||||||
|
if (mIsServiceRunning == false) {
|
||||||
|
// 设置运行状态
|
||||||
|
mIsServiceRunning = true;
|
||||||
|
// 唤醒和绑定主进程
|
||||||
|
wakeupAndBindMain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 唤醒和绑定主进程
|
||||||
|
//
|
||||||
|
void wakeupAndBindMain() {
|
||||||
|
if (ServiceUtils.isServiceAlive(getApplicationContext(), WinBoLLClientService.class.getName()) == false) {
|
||||||
|
startForegroundService(new Intent(AssistantService.this, WinBoLLClientService.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
bindService(new Intent(AssistantService.this, WinBoLLClientService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 主进程与守护进程连接时需要用到此类
|
||||||
|
//
|
||||||
|
class MyServiceConnection implements ServiceConnection {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
mWinBoLLServiceBean = WinBoLLClientServiceBean.loadWinBoLLClientServiceBean(AssistantService.this);
|
||||||
|
if (mWinBoLLServiceBean.isEnable()) {
|
||||||
|
wakeupAndBindMain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cc.winboll.studio.libaes.winboll;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/03/28 19:11:27
|
||||||
|
* @Describe WinBoLL UI 状态图标枚举
|
||||||
|
*/
|
||||||
|
import cc.winboll.studio.libaes.R;
|
||||||
|
|
||||||
|
public enum EWUIStatusIconDrawable {
|
||||||
|
NORMAL(0),
|
||||||
|
NEWS(1)
|
||||||
|
;
|
||||||
|
|
||||||
|
static final String TAG = "WUIStatusIconDrawable";
|
||||||
|
|
||||||
|
static String[] _mlistCNName = { "正常", "新的消息" };
|
||||||
|
|
||||||
|
private int value = 0;
|
||||||
|
private EWUIStatusIconDrawable(int value) { //必须是private的,否则编译错误
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getIconDrawableId(EWUIStatusIconDrawable drawableId) {
|
||||||
|
int res;
|
||||||
|
switch(drawableId){
|
||||||
|
case NEWS :
|
||||||
|
res = R.drawable.ic_winbollbeta;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
res = R.drawable.ic_winboll;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
public static final String TAG = "MainActivity";
|
public static final String TAG = "MainActivity";
|
||||||
|
|
||||||
LogView mLogView;
|
LogView mLogView;
|
||||||
private TerminalView mTerminalView;
|
//private TerminalView mTerminalView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -37,10 +37,10 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
mLogView = findViewById(R.id.logview);
|
mLogView = findViewById(R.id.logview);
|
||||||
|
|
||||||
mTerminalView = findViewById(R.id.terminalView);
|
/*mTerminalView = findViewById(R.id.terminalView);
|
||||||
|
|
||||||
// 示例:模拟用户输入 "ls" 命令
|
// 示例:模拟用户输入 "ls" 命令
|
||||||
mTerminalView.sendInput("ls");
|
mTerminalView.sendInput("ls");*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package cc.winboll.studio.appbase;
|
package cc.winboll.studio.winboll;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
* @Date 2025/02/13 19:30:10
|
* @Date 2025/02/13 19:30:10
|
||||||
*/
|
*/
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import cc.winboll.studio.winboll.R;
|
||||||
import android.service.quicksettings.Tile;
|
import android.service.quicksettings.Tile;
|
||||||
import android.service.quicksettings.TileService;
|
import android.service.quicksettings.TileService;
|
||||||
import cc.winboll.studio.appbase.models.MainServiceBean;
|
import cc.winboll.studio.winboll.models.MainServiceBean;
|
||||||
import cc.winboll.studio.appbase.services.MainService;
|
import cc.winboll.studio.winboll.services.MainService;
|
||||||
|
|
||||||
public class MyTileService extends TileService {
|
public class MyTileService extends TileService {
|
||||||
public static final String TAG = "MyTileService";
|
public static final String TAG = "MyTileService";
|
||||||
|
|||||||
40
winboll/src/main/java/cc/winboll/studio/winboll/WinBoLL.java
Normal file
40
winboll/src/main/java/cc/winboll/studio/winboll/WinBoLL.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package cc.winboll.studio.libaes.winboll;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/05/10 10:13
|
||||||
|
* @Describe WinBoLL 系列应用通用管理类
|
||||||
|
*/
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libaes.models.WinBoLLModel;
|
||||||
|
|
||||||
|
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_WINBOLLMODEL = "EXTRA_WINBOLLMODEL";
|
||||||
|
|
||||||
|
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_WINBOLLMODEL, (new WinBoLLModel(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package cc.winboll.studio.libaes.winboll;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen
|
||||||
|
* @Date 2025/05/03 19:28
|
||||||
|
*/
|
||||||
|
public class WinBoLLClientService extends Service {
|
||||||
|
|
||||||
|
public static final String TAG = "WinBoLLClientService";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package cc.winboll.studio.libaes.winboll;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen
|
||||||
|
* @Date 2025/05/03 19:14
|
||||||
|
*/
|
||||||
|
public class WinBoLLServiceStatusView extends LinearLayout {
|
||||||
|
|
||||||
|
public static final String TAG = "WinBoLLServiceStatusView";
|
||||||
|
|
||||||
|
public WinBoLLServiceStatusView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WinBoLLServiceStatusView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WinBoLLServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WinBoLLServiceStatusView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setServerHost(String szWinBoLLServerHost) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAuthInfo(String szDevUserName, String szDevUserPassword) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.activities;
|
package cc.winboll.studio.winboll.activities;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -7,14 +7,14 @@ import android.widget.RadioButton;
|
|||||||
import cc.winboll.studio.libappbase.BuildConfig;
|
import cc.winboll.studio.libappbase.BuildConfig;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.LogView;
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
import cc.winboll.studio.libappbase.R;
|
import cc.winboll.studio.winboll.R;
|
||||||
import cc.winboll.studio.libappbase.models.UserInfoModel;
|
|
||||||
import cc.winboll.studio.libappbase.utils.RSAUtils;
|
|
||||||
import cc.winboll.studio.libappbase.utils.YunUtils;
|
|
||||||
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
import cc.winboll.studio.winboll.utils.YunUtils;
|
||||||
|
import cc.winboll.studio.winboll.models.UserInfoModel;
|
||||||
|
import cc.winboll.studio.winboll.utils.RSAUtils;
|
||||||
|
import cc.winboll.studio.libaes.winboll.IWinBoLLActivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.activities;
|
package cc.winboll.studio.winboll.activities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -11,9 +11,10 @@ import android.view.Menu;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toolbar;
|
import android.widget.Toolbar;
|
||||||
import cc.winboll.studio.appbase.R;
|
import cc.winboll.studio.winboll.R;
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
|
import cc.winboll.studio.libaes.winboll.IWinBoLLActivity;
|
||||||
|
import cc.winboll.studio.libaes.winboll.WinBoLLActivityManager;
|
||||||
|
|
||||||
public class New2Activity extends WinBoLLActivity implements IWinBoLLActivity {
|
public class New2Activity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||||
|
|
||||||
@@ -51,15 +52,15 @@ public class New2Activity extends WinBoLLActivity implements IWinBoLLActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onCloseThisActivity(View view) {
|
public void onCloseThisActivity(View view) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().finish(this);
|
WinBoLLActivityManager.getInstance().finish(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCloseAllActivity(View view) {
|
public void onCloseAllActivity(View view) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().finishAll();
|
WinBoLLActivityManager.getInstance().finishAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNewActivity(View view) {
|
public void onNewActivity(View view) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, NewActivity.class);
|
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, NewActivity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.activities;
|
package cc.winboll.studio.winboll.activities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||||
@@ -11,9 +11,10 @@ import android.view.Menu;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toolbar;
|
import android.widget.Toolbar;
|
||||||
import cc.winboll.studio.appbase.R;
|
import cc.winboll.studio.winboll.R;
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
|
import cc.winboll.studio.libaes.winboll.WinBoLLActivityManager;
|
||||||
|
import cc.winboll.studio.libaes.winboll.IWinBoLLActivity;
|
||||||
|
|
||||||
public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||||
|
|
||||||
@@ -50,15 +51,15 @@ public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onCloseThisActivity(View view) {
|
public void onCloseThisActivity(View view) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().finish(this);
|
WinBoLLActivityManager.getInstance().finish(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCloseAllActivity(View view) {
|
public void onCloseAllActivity(View view) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().finishAll();
|
WinBoLLActivityManager.getInstance().finishAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNew2Activity(View view) {
|
public void onNew2Activity(View view) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, New2Activity.class);
|
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, New2Activity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.activities;
|
package cc.winboll.studio.winboll.activities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -6,13 +6,15 @@ package cc.winboll.studio.appbase.activities;
|
|||||||
* @Describe WinBoLL 窗口基础类
|
* @Describe WinBoLL 窗口基础类
|
||||||
*/
|
*/
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import cc.winboll.studio.appbase.MainActivity;
|
import cc.winboll.studio.libaes.winboll.IWinBoLLActivity;
|
||||||
import cc.winboll.studio.appbase.R;
|
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
|
import cc.winboll.studio.winboll.MainActivity;
|
||||||
|
import cc.winboll.studio.winboll.R;
|
||||||
|
import cc.winboll.studio.libaes.winboll.WinBoLLActivityManager;
|
||||||
|
|
||||||
public class WinBoLLActivity extends Activity implements IWinBoLLActivity {
|
public class WinBoLLActivity extends Activity implements IWinBoLLActivity {
|
||||||
|
|
||||||
@@ -37,10 +39,10 @@ public class WinBoLLActivity extends Activity implements IWinBoLLActivity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (item.getItemId() == R.id.item_log) {
|
if (item.getItemId() == R.id.item_log) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().startLogActivity(this);
|
WinBoLLActivityManager.getInstance().startLogActivity(this);
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.item_home) {
|
} else if (item.getItemId() == R.id.item_home) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(getApplicationContext(), MainActivity.class);
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
|
// 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
|
||||||
@@ -50,12 +52,12 @@ public class WinBoLLActivity extends Activity implements IWinBoLLActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
super.onPostCreate(savedInstanceState);
|
super.onPostCreate(savedInstanceState);
|
||||||
GlobalApplication.getWinBoLLActivityManager().add(this);
|
WinBoLLActivityManager.getInstance().add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
GlobalApplication.getWinBoLLActivityManager().registeRemove(this);
|
WinBoLLActivityManager.getInstance().registeRemove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase;
|
package cc.winboll.studio.winboll.activities;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -9,12 +9,19 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.Toolbar;
|
import android.widget.Toolbar;
|
||||||
import cc.winboll.studio.appbase.R;
|
|
||||||
import cc.winboll.studio.libappbase.CrashHandler;
|
import cc.winboll.studio.libappbase.CrashHandler;
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.GlobalCrashActivity;
|
import cc.winboll.studio.libappbase.GlobalCrashActivity;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||||
|
import cc.winboll.studio.winboll.App;
|
||||||
|
import cc.winboll.studio.winboll.R;
|
||||||
|
import cc.winboll.studio.winboll.services.MainService;
|
||||||
|
import cc.winboll.studio.winboll.services.TestDemoBindService;
|
||||||
|
import cc.winboll.studio.winboll.services.TestDemoService;
|
||||||
|
import cc.winboll.studio.winboll.sos.SOS;
|
||||||
|
import cc.winboll.studio.winboll.widgets.StatusWidget;
|
||||||
|
import cc.winboll.studio.libaes.winboll.WinBoLLActivityManager;
|
||||||
|
|
||||||
public class WinBoLLUnitTestActivity extends Activity {
|
public class WinBoLLUnitTestActivity extends Activity {
|
||||||
|
|
||||||
@@ -44,9 +51,9 @@ public class WinBoLLUnitTestActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if(item.getItemId() == R.id.item_yun) {
|
if(item.getItemId() == R.id.item_yun) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, cc.winboll.studio.libappbase.activities.YunActivity.class);
|
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, cc.winboll.studio.libappbase.activities.YunActivity.class);
|
||||||
} else if(item.getItemId() == R.id.item_logon) {
|
} else if(item.getItemId() == R.id.item_logon) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, cc.winboll.studio.libappbase.activities.LogonActivity.class);
|
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, cc.winboll.studio.libappbase.activities.LogonActivity.class);
|
||||||
}
|
}
|
||||||
// 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
|
// 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
@@ -63,7 +70,7 @@ public class WinBoLLUnitTestActivity extends Activity {
|
|||||||
public void onSwitchDebugMode(View view) {
|
public void onSwitchDebugMode(View view) {
|
||||||
boolean isDebuging = ((CheckBox)view).isChecked();
|
boolean isDebuging = ((CheckBox)view).isChecked();
|
||||||
GlobalApplication.setIsDebuging(isDebuging);
|
GlobalApplication.setIsDebuging(isDebuging);
|
||||||
GlobalApplication.saveDebugStatus();
|
GlobalApplication.saveDebugStatus(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPreviewGlobalCrashActivity(View view) {
|
public void onPreviewGlobalCrashActivity(View view) {
|
||||||
@@ -152,7 +159,7 @@ public class WinBoLLUnitTestActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onTestOpenNewActivity(View view) {
|
public void onTestOpenNewActivity(View view) {
|
||||||
GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(this, NewActivity.class);
|
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, NewActivity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.activities;
|
package cc.winboll.studio.winboll.activities;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.handlers;
|
package cc.winboll.studio.winboll.handlers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -6,8 +6,8 @@ package cc.winboll.studio.appbase.handlers;
|
|||||||
*/
|
*/
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import cc.winboll.studio.appbase.services.MainService;
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import cc.winboll.studio.winboll.services.MainService;
|
||||||
|
|
||||||
public class MainServiceHandler extends Handler {
|
public class MainServiceHandler extends Handler {
|
||||||
public static final String TAG = "MainServiceHandler";
|
public static final String TAG = "MainServiceHandler";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.models;
|
package cc.winboll.studio.winboll.models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package cc.winboll.studio.winboll.models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/06/05 11:26
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ResponseData {
|
||||||
|
|
||||||
|
public static final String STATUS_SUCCESS = "success";
|
||||||
|
public static final String STATUS_ERROR = "error";
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
private String message;
|
||||||
|
private UserInfoModel data;
|
||||||
|
|
||||||
|
public ResponseData() {
|
||||||
|
this.status = "";
|
||||||
|
this.message = "";
|
||||||
|
this.data = new UserInfoModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseData(String status, String message, UserInfoModel data) {
|
||||||
|
this.status = status;
|
||||||
|
this.message = message;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(UserInfoModel data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserInfoModel getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.models;
|
package cc.winboll.studio.winboll.models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.models;
|
package cc.winboll.studio.winboll.models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package cc.winboll.studio.winboll.models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/06/04 19:14
|
||||||
|
*/
|
||||||
|
import android.util.JsonReader;
|
||||||
|
import android.util.JsonWriter;
|
||||||
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class UserInfoModel extends BaseBean {
|
||||||
|
|
||||||
|
public static final String TAG = "UserInfoModel";
|
||||||
|
|
||||||
|
String username;
|
||||||
|
String password;
|
||||||
|
String token;
|
||||||
|
|
||||||
|
public UserInfoModel() {
|
||||||
|
this.username = "";
|
||||||
|
this.password = "";
|
||||||
|
this.token = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return UserInfoModel.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||||
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
|
jsonWriter.name("username").value(getUsername());
|
||||||
|
jsonWriter.name("password").value(getPassword());
|
||||||
|
jsonWriter.name("token").value(getToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||||
|
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||||
|
if (name.equals("username")) {
|
||||||
|
setUsername(jsonReader.nextString());
|
||||||
|
} else if (name.equals("password")) {
|
||||||
|
setPassword(jsonReader.nextString());
|
||||||
|
} else if (name.equals("token")) {
|
||||||
|
setToken(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package cc.winboll.studio.winboll.models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/05/10 10:16
|
||||||
|
* @Describe WinBoLLModel
|
||||||
|
*/
|
||||||
|
import android.util.JsonReader;
|
||||||
|
import android.util.JsonWriter;
|
||||||
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
|
import java.io.IOException;
|
||||||
|
import cc.winboll.studio.libappbase.APPModel;
|
||||||
|
|
||||||
|
public class WinBoLLModel extends BaseBean {
|
||||||
|
|
||||||
|
public static final String TAG = "WinBoLLModel";
|
||||||
|
|
||||||
|
String appPackageName;
|
||||||
|
String appMainServiveName;
|
||||||
|
|
||||||
|
public WinBoLLModel() {
|
||||||
|
this.appPackageName = "";
|
||||||
|
this.appMainServiveName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public WinBoLLModel(boolean isDebuging, String appPackageName, String appMainServiveName) {
|
||||||
|
this.appPackageName = appPackageName;
|
||||||
|
this.appMainServiveName = appMainServiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WinBoLLModel(String appPackageName, String appMainServiveName) {
|
||||||
|
this.appPackageName = appPackageName;
|
||||||
|
this.appMainServiveName = appMainServiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppPackageName(String appPackageName) {
|
||||||
|
this.appPackageName = appPackageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppPackageName() {
|
||||||
|
return appPackageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppMainServiveName(String appMainServiveName) {
|
||||||
|
this.appMainServiveName = appMainServiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppMainServiveName() {
|
||||||
|
return appMainServiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return APPModel.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||||
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
|
jsonWriter.name("appPackageName").value(getAppPackageName());
|
||||||
|
jsonWriter.name("appMainServiveName").value(getAppMainServiveName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||||
|
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||||
|
if (name.equals("appPackageName")) {
|
||||||
|
setAppPackageName(jsonReader.nextString());
|
||||||
|
} else if (name.equals("appMainServiveName")) {
|
||||||
|
setAppMainServiveName(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,14 +1,15 @@
|
|||||||
package cc.winboll.studio.libappbase.models;
|
package cc.winboll.studio.winboll.models;
|
||||||
import android.util.JsonReader;
|
|
||||||
import android.util.JsonWriter;
|
|
||||||
import cc.winboll.studio.libappbase.BaseBean;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
* @Date 2025/05/10 09:36
|
* @Date 2025/05/10 09:36
|
||||||
* @Describe WinBoLL 应用消息数据模型
|
* @Describe WinBoLL 应用消息数据模型
|
||||||
*/
|
*/
|
||||||
|
import android.util.JsonReader;
|
||||||
|
import android.util.JsonWriter;
|
||||||
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class WinBoLLNewsBean extends BaseBean {
|
public class WinBoLLNewsBean extends BaseBean {
|
||||||
|
|
||||||
public static final String TAG = "WinBoLLNewsBean";
|
public static final String TAG = "WinBoLLNewsBean";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.receivers;
|
package cc.winboll.studio.winboll.receivers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -7,8 +7,8 @@ package cc.winboll.studio.appbase.receivers;
|
|||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import cc.winboll.studio.appbase.widgets.APPNewsWidget;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.winboll.widgets.APPNewsWidget;
|
||||||
|
|
||||||
public class APPNewsWidgetClickListener extends BroadcastReceiver {
|
public class APPNewsWidgetClickListener extends BroadcastReceiver {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.receivers;
|
package cc.winboll.studio.winboll.receivers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -10,14 +10,17 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import cc.winboll.studio.appbase.services.MainService;
|
import cc.winboll.studio.libaes.winboll.IWinBoLLActivity;
|
||||||
import cc.winboll.studio.appbase.widgets.APPNewsWidget;
|
import cc.winboll.studio.libaes.winboll.WinBoLL;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.models.WinBoLLModel;
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
import cc.winboll.studio.libappbase.models.WinBoLLNewsBean;
|
import cc.winboll.studio.libapputils.utils.AppUtils;
|
||||||
import cc.winboll.studio.libappbase.sos.SOS;
|
import cc.winboll.studio.winboll.models.WinBoLLModel;
|
||||||
import cc.winboll.studio.libappbase.sos.SOSObject;
|
import cc.winboll.studio.winboll.models.WinBoLLNewsBean;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import cc.winboll.studio.winboll.services.MainService;
|
||||||
|
import cc.winboll.studio.winboll.sos.SOS;
|
||||||
|
import cc.winboll.studio.winboll.sos.SOSObject;
|
||||||
|
import cc.winboll.studio.winboll.widgets.APPNewsWidget;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.services;
|
package cc.winboll.studio.winboll.services;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -11,11 +11,9 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import cc.winboll.studio.appbase.models.MainServiceBean;
|
|
||||||
import cc.winboll.studio.appbase.services.AssistantService;
|
|
||||||
import cc.winboll.studio.appbase.services.MainService;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import cc.winboll.studio.winboll.models.MainServiceBean;
|
||||||
|
|
||||||
public class AssistantService extends Service {
|
public class AssistantService extends Service {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.services;
|
package cc.winboll.studio.winboll.services;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -17,16 +17,15 @@ import android.content.Intent;
|
|||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import cc.winboll.studio.appbase.MyTileService;
|
import cc.winboll.studio.libaes.models.WinBoLLModel;
|
||||||
import cc.winboll.studio.appbase.handlers.MainServiceHandler;
|
|
||||||
import cc.winboll.studio.appbase.models.MainServiceBean;
|
|
||||||
import cc.winboll.studio.appbase.receivers.MainReceiver;
|
|
||||||
import cc.winboll.studio.appbase.services.AssistantService;
|
|
||||||
import cc.winboll.studio.appbase.threads.MainServiceThread;
|
|
||||||
import cc.winboll.studio.appbase.widgets.APPNewsWidget;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.models.APPModel;
|
import cc.winboll.studio.winboll.MyTileService;
|
||||||
import cc.winboll.studio.libappbase.models.WinBoLLModel;
|
import cc.winboll.studio.winboll.handlers.MainServiceHandler;
|
||||||
|
import cc.winboll.studio.winboll.models.MainServiceBean;
|
||||||
|
import cc.winboll.studio.winboll.receivers.MainReceiver;
|
||||||
|
import cc.winboll.studio.winboll.services.AssistantService;
|
||||||
|
import cc.winboll.studio.winboll.threads.MainServiceThread;
|
||||||
|
import cc.winboll.studio.winboll.widgets.APPNewsWidget;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class MainService extends Service {
|
public class MainService extends Service {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.services;
|
package cc.winboll.studio.winboll.services;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -10,12 +10,12 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import cc.winboll.studio.appbase.App;
|
import cc.winboll.studio.libaes.winboll.WinBoLL;
|
||||||
import cc.winboll.studio.appbase.models.TestDemoBindServiceBean;
|
|
||||||
import cc.winboll.studio.appbase.services.TestDemoBindService;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.sos.SOS;
|
import cc.winboll.studio.winboll.App;
|
||||||
import cc.winboll.studio.libappbase.winboll.WinBoLL;
|
import cc.winboll.studio.winboll.models.TestDemoBindServiceBean;
|
||||||
|
import cc.winboll.studio.winboll.services.TestDemoBindService;
|
||||||
|
import cc.winboll.studio.winboll.sos.SOS;
|
||||||
|
|
||||||
public class TestDemoBindService extends Service {
|
public class TestDemoBindService extends Service {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.services;
|
package cc.winboll.studio.winboll.services;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -10,8 +10,9 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import cc.winboll.studio.appbase.models.TestDemoServiceBean;
|
import cc.winboll.studio.winboll.models.TestDemoServiceBean;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.winboll.models.TestDemoServiceBean;
|
||||||
|
|
||||||
public class TestDemoService extends Service {
|
public class TestDemoService extends Service {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.sos;
|
package cc.winboll.studio.winboll.sos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.sos;
|
package cc.winboll.studio.winboll.sos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.sos;
|
package cc.winboll.studio.winboll.sos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.sos;
|
package cc.winboll.studio.winboll.sos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.sos;
|
package cc.winboll.studio.winboll.sos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package cc.winboll.studio.appbase.threads;
|
package cc.winboll.studio.winboll.threads;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
* @Date 2025/02/14 03:46:44
|
* @Date 2025/02/14 03:46:44
|
||||||
*/
|
*/
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import cc.winboll.studio.appbase.handlers.MainServiceHandler;
|
import cc.winboll.studio.winboll.handlers.MainServiceHandler;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,222 @@
|
|||||||
|
package cc.winboll.studio.winboll.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/06/04 13:36
|
||||||
|
* @Describe RSA加密工具
|
||||||
|
*/
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Base64;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.Objects;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
|
||||||
|
public class RSAUtils {
|
||||||
|
private static final String TAG = "RSAUtils";
|
||||||
|
private static final int KEY_SIZE = 2048;
|
||||||
|
private static final String KEY_ALGORITHM = "RSA";
|
||||||
|
private static final String PUBLIC_KEY_FILE = "public.key";
|
||||||
|
private static final String PRIVATE_KEY_FILE = "private.key";
|
||||||
|
private static final String CIPHER_ALGORITHM = KEY_ALGORITHM + "/ECB/PKCS1Padding"; // 保留原加密方式
|
||||||
|
|
||||||
|
private final String keyPath;
|
||||||
|
private static volatile RSAUtils INSTANCE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造方法:初始化密钥存储路径(内部存储)
|
||||||
|
*/
|
||||||
|
private RSAUtils(Context context) {
|
||||||
|
keyPath = context.getFilesDir() + File.separator + "keys" + File.separator; // 修正路径格式
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单例实例
|
||||||
|
*/
|
||||||
|
public static synchronized RSAUtils getInstance(Context context) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = new RSAUtils(context);
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查密钥文件是否存在
|
||||||
|
*/
|
||||||
|
public boolean keysExist() {
|
||||||
|
File publicKeyFile = new File(keyPath + PUBLIC_KEY_FILE);
|
||||||
|
File privateKeyFile = new File(keyPath + PRIVATE_KEY_FILE);
|
||||||
|
return publicKeyFile.exists() && privateKeyFile.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成密钥对并保存到文件
|
||||||
|
*/
|
||||||
|
public void generateAndSaveKeys() throws Exception {
|
||||||
|
LogUtils.d(TAG, "开始生成 RSA 密钥对(2048位)");
|
||||||
|
KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
||||||
|
generator.initialize(KEY_SIZE);
|
||||||
|
KeyPair keyPair = generator.generateKeyPair();
|
||||||
|
|
||||||
|
saveKey(PUBLIC_KEY_FILE, keyPair.getPublic().getEncoded());
|
||||||
|
saveKey(PRIVATE_KEY_FILE, keyPair.getPrivate().getEncoded());
|
||||||
|
LogUtils.d(TAG, "密钥对生成并保存成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取或生成密钥对(线程安全)
|
||||||
|
*/
|
||||||
|
public KeyPair getOrGenerateKeys() throws Exception {
|
||||||
|
if (!keysExist()) {
|
||||||
|
synchronized (RSAUtils.class) { // 双重检查锁,避免多线程重复生成
|
||||||
|
if (!keysExist()) {
|
||||||
|
generateAndSaveKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readKeysFromFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从文件读取密钥对
|
||||||
|
*/
|
||||||
|
private KeyPair readKeysFromFile() throws Exception {
|
||||||
|
LogUtils.d(TAG, "读取密钥对文件");
|
||||||
|
try {
|
||||||
|
byte[] publicKeyBytes = readFileToBytes(keyPath + PUBLIC_KEY_FILE);
|
||||||
|
byte[] privateKeyBytes = readFileToBytes(keyPath + PRIVATE_KEY_FILE);
|
||||||
|
|
||||||
|
X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(publicKeyBytes);
|
||||||
|
PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(privateKeyBytes);
|
||||||
|
|
||||||
|
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
PublicKey publicKey = factory.generatePublic(publicSpec);
|
||||||
|
PrivateKey privateKey = factory.generatePrivate(privateSpec);
|
||||||
|
|
||||||
|
return new KeyPair(publicKey, privateKey);
|
||||||
|
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||||
|
LogUtils.e(TAG, "密钥文件读取失败:" + e.getMessage());
|
||||||
|
throw new Exception("密钥文件损坏或格式错误", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存密钥到文件(通用方法)
|
||||||
|
*/
|
||||||
|
private void saveKey(String fileName, byte[] keyBytes) throws IOException {
|
||||||
|
Objects.requireNonNull(keyBytes, "密钥字节数据不可为空");
|
||||||
|
File dir = new File(keyPath);
|
||||||
|
if (!dir.exists() && !dir.mkdirs()) {
|
||||||
|
throw new IOException("创建密钥目录失败:" + keyPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileOutputStream fos = null;
|
||||||
|
try {
|
||||||
|
fos = new FileOutputStream(keyPath + fileName);
|
||||||
|
fos.write(keyBytes);
|
||||||
|
} finally {
|
||||||
|
if (fos != null) {
|
||||||
|
try {
|
||||||
|
fos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.e(TAG, "关闭文件流失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件为字节数组(Java 7 兼容)
|
||||||
|
*/
|
||||||
|
private byte[] readFileToBytes(String filePath) throws IOException {
|
||||||
|
File file = new File(filePath);
|
||||||
|
if (!file.exists() || file.isDirectory()) {
|
||||||
|
throw new IOException("文件不存在或为目录:" + filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInputStream fis = null;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(file);
|
||||||
|
byte[] data = new byte[(int) file.length()];
|
||||||
|
int bytesRead = fis.read(data);
|
||||||
|
if (bytesRead != data.length) {
|
||||||
|
throw new IOException("文件读取不完整");
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
} finally {
|
||||||
|
if (fis != null) {
|
||||||
|
try {
|
||||||
|
fis.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.e(TAG, "关闭文件流失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公钥加密(带参数校验)
|
||||||
|
*/
|
||||||
|
public byte[] encryptWithPublicKey(String plainText, PublicKey publicKey) throws Exception {
|
||||||
|
Objects.requireNonNull(plainText, "明文不可为空");
|
||||||
|
Objects.requireNonNull(publicKey, "公钥不可为空");
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
|
||||||
|
// 检查数据长度是否超过 RSA 限制(2048位密钥最大明文为 214字节,PKCS1Padding)
|
||||||
|
int maxPlainTextSize = cipher.getBlockSize() - 11; // PKCS1Padding 固定填充长度
|
||||||
|
if (plainText.getBytes("UTF-8").length > maxPlainTextSize) {
|
||||||
|
throw new IllegalArgumentException("明文过长,最大支持 " + maxPlainTextSize + " 字节");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cipher.doFinal(plainText.getBytes("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私钥解密(带参数校验)
|
||||||
|
*/
|
||||||
|
public String decryptWithPrivateKey(byte[] encryptedData, PrivateKey privateKey) throws Exception {
|
||||||
|
Objects.requireNonNull(encryptedData, "密文不可为空");
|
||||||
|
Objects.requireNonNull(privateKey, "私钥不可为空");
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
|
byte[] decryptedBytes = cipher.doFinal(encryptedData);
|
||||||
|
return new String(decryptedBytes, "UTF-8");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 将 HTTP 传输的 Base64 字符串还原为加密字节数组(Java 7 兼容)
|
||||||
|
* @param httpString Base64 字符串(非 null)
|
||||||
|
* @return 加密字节数组
|
||||||
|
* @throws IllegalArgumentException 解码失败时抛出
|
||||||
|
*/
|
||||||
|
public byte[] httpStringToEncryptBytes(String httpString) {
|
||||||
|
Objects.requireNonNull(httpString, "HTTP 字符串不可为空");
|
||||||
|
|
||||||
|
// 计算缺失的填充符数量(Java 7 不支持 repeat(),手动拼接)
|
||||||
|
int pad = httpString.length() % 4;
|
||||||
|
StringBuilder paddedString = new StringBuilder(httpString);
|
||||||
|
if (pad != 0) {
|
||||||
|
for (int i = 0; i < pad; i++) {
|
||||||
|
paddedString.append('='); // 补全 '='
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 Base64 解码(Android 原生 Base64 类兼容 Java 7)
|
||||||
|
return Base64.decode(paddedString.toString(), Base64.URL_SAFE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -5,13 +5,15 @@ package cc.winboll.studio.winboll.utils;
|
|||||||
* @Date 2025/06/08 09:05
|
* @Date 2025/06/08 09:05
|
||||||
* @Describe Termux 应用操作工具集
|
* @Describe Termux 应用操作工具集
|
||||||
*/
|
*/
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
public abstract class TermuxUtils {
|
public abstract class TermuxUtils {
|
||||||
|
|
||||||
public static final String TAG = "TermuxUtils";
|
public static final String TAG = "TermuxUtils";
|
||||||
|
|
||||||
private void runTermuxCommand(String command) {
|
private void runTermuxCommand(String command) {
|
||||||
// 1. 创建 Intent,指定 Termux 的 RunCommandService
|
// 1. 创建 Intent,指定 Termux 的 RunCommandService
|
||||||
Intent intent = new Intent("com.termux.RUN_COMMAND");
|
/*Intent intent = new Intent("com.termux.RUN_COMMAND");
|
||||||
intent.setPackage("com.termux"); // Termux 应用的包名
|
intent.setPackage("com.termux"); // Termux 应用的包名
|
||||||
|
|
||||||
// 2. 传递命令参数(必填)
|
// 2. 传递命令参数(必填)
|
||||||
@@ -26,6 +28,6 @@ public abstract class TermuxUtils {
|
|||||||
getApplicationContext().startService(intent);
|
getApplicationContext().startService(intent);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,282 @@
|
|||||||
|
package cc.winboll.studio.winboll.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2025/06/04 17:21
|
||||||
|
* @Describe 应用登录与接口工具
|
||||||
|
*/
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.Callback;
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import cc.winboll.studio.winboll.models.UserInfoModel;
|
||||||
|
import cc.winboll.studio.winboll.models.ResponseData;
|
||||||
|
import cc.winboll.studio.libapputils.utils.FileUtils;
|
||||||
|
|
||||||
|
public class YunUtils {
|
||||||
|
public static final String TAG = "YunUtils";
|
||||||
|
// 私有静态实例,类加载时创建
|
||||||
|
private static volatile YunUtils INSTANCE;
|
||||||
|
Context mContext;
|
||||||
|
UserInfoModel mUserInfoModel;
|
||||||
|
String token = "";
|
||||||
|
String mDataFolderPath = "";
|
||||||
|
String mUserInfoModelPath = "";
|
||||||
|
|
||||||
|
private static final int CONNECT_TIMEOUT = 15; // 连接超时时间(秒)
|
||||||
|
private static final int READ_TIMEOUT = 20; // 读取超时时间(秒)
|
||||||
|
private static volatile YunUtils instance;
|
||||||
|
private OkHttpClient okHttpClient;
|
||||||
|
private Handler mainHandler; // 主线程 Handler
|
||||||
|
|
||||||
|
// 私有构造方法,防止外部实例化
|
||||||
|
private YunUtils(Context context) {
|
||||||
|
LogUtils.d(TAG, "YunUtils");
|
||||||
|
mContext = context;
|
||||||
|
mDataFolderPath = mContext.getExternalFilesDir(TAG).toString();
|
||||||
|
File fTest = new File(mDataFolderPath);
|
||||||
|
if (!fTest.exists()) {
|
||||||
|
fTest.mkdirs();
|
||||||
|
}
|
||||||
|
mUserInfoModelPath = mDataFolderPath + File.separator + "UserInfoModel.rsajson";
|
||||||
|
|
||||||
|
okHttpClient = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
mainHandler = new Handler(Looper.getMainLooper()); // 获取主线程 Looper
|
||||||
|
}
|
||||||
|
|
||||||
|
// 公共静态方法,返回唯一实例
|
||||||
|
public static synchronized YunUtils getInstance(Context context) {
|
||||||
|
LogUtils.d(TAG, "getInstance");
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = new YunUtils(context);
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkLoginStatus() {
|
||||||
|
String token = getLocalToken();
|
||||||
|
LogUtils.d(TAG, String.format("checkLoginStatus token is %s", token));
|
||||||
|
}
|
||||||
|
|
||||||
|
String getLocalToken() {
|
||||||
|
UserInfoModel userInfoModel = loadUserInfoModel();
|
||||||
|
return (userInfoModel == null) ?"": userInfoModel.getToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void login(String host, UserInfoModel userInfoModel) {
|
||||||
|
LogUtils.d(TAG, "login");
|
||||||
|
|
||||||
|
// 发送 POST 请求
|
||||||
|
String apiUrl = host + "/login/index.php";
|
||||||
|
// 序列化对象为JSON
|
||||||
|
Gson gson = new Gson();
|
||||||
|
String jsonData = gson.toJson(userInfoModel); // 自动生成标准JSON
|
||||||
|
//String jsonData = userInfoModel.toString();
|
||||||
|
LogUtils.d(TAG, "要发送的数据 : " + jsonData);
|
||||||
|
|
||||||
|
sendPostRequest(apiUrl, jsonData, new OnResponseListener() {
|
||||||
|
// 成功回调(主线程)
|
||||||
|
@Override
|
||||||
|
public void onSuccess(String responseBody) {
|
||||||
|
LogUtils.d(TAG, "onSuccess");
|
||||||
|
LogUtils.d(TAG, String.format("responseBody %s", responseBody));
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseData result = gson.fromJson(responseBody, ResponseData.class); // 转为 Result 实例
|
||||||
|
if(result.getStatus().equals(ResponseData.STATUS_SUCCESS)) {
|
||||||
|
|
||||||
|
UserInfoModel userInfoModel = result.getData();
|
||||||
|
if (userInfoModel != null) {
|
||||||
|
LogUtils.d(TAG, "收到网站 UserInfoModel");
|
||||||
|
String token = userInfoModel.getToken();
|
||||||
|
saveLocalToken(token);
|
||||||
|
checkLoginStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(result.getStatus().equals(ResponseData.STATUS_ERROR)) {
|
||||||
|
try {
|
||||||
|
String decodedMessage = URLDecoder.decode(result.getMessage(), "UTF-8");
|
||||||
|
LogUtils.d(TAG, "服务器返回信息: " + decodedMessage);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 失败回调(主线程)
|
||||||
|
@Override
|
||||||
|
public void onFailure(String errorMsg) {
|
||||||
|
LogUtils.d(TAG, errorMsg);
|
||||||
|
// 处理错误
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveLocalToken(String token) {
|
||||||
|
UserInfoModel userInfoModel = new UserInfoModel();
|
||||||
|
userInfoModel.setToken(token);
|
||||||
|
saveUserInfoModel(userInfoModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfoModel loadUserInfoModel() {
|
||||||
|
LogUtils.d(TAG, "loadUserInfoModel");
|
||||||
|
if (new File(mUserInfoModelPath).exists()) {
|
||||||
|
try {
|
||||||
|
// 加载加密后的模型数据
|
||||||
|
byte[] encryptedData = FileUtils.readByteArrayFromFile(mUserInfoModelPath);
|
||||||
|
// 加载 RSA 工具
|
||||||
|
RSAUtils utils = RSAUtils.getInstance(mContext);
|
||||||
|
KeyPair keyPair = utils.getOrGenerateKeys();
|
||||||
|
//PublicKey publicKey = keyPair.getPublic();
|
||||||
|
PrivateKey privateKey = keyPair.getPrivate();
|
||||||
|
// 私钥解密模型数据
|
||||||
|
String szInfo = utils.decryptWithPrivateKey(encryptedData, keyPair.getPrivate());
|
||||||
|
LogUtils.d(TAG, String.format("szInfo %s", szInfo));
|
||||||
|
mUserInfoModel = UserInfoModel.parseStringToBean(szInfo, UserInfoModel.class);
|
||||||
|
if (mUserInfoModel == null) {
|
||||||
|
LogUtils.d(TAG, "模型数据解析为空数据。");
|
||||||
|
}
|
||||||
|
LogUtils.d(TAG, "UserInfoModel 解密加载结束。");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogUtils.d(TAG, "云服务登录信息不存在。");
|
||||||
|
mUserInfoModel = null;
|
||||||
|
}
|
||||||
|
return mUserInfoModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveUserInfoModel(UserInfoModel userInfoModel) {
|
||||||
|
LogUtils.d(TAG, "saveUserInfoModel");
|
||||||
|
try {
|
||||||
|
String szInfo = userInfoModel.toString();
|
||||||
|
LogUtils.d(TAG, "原始数据: " + szInfo);
|
||||||
|
|
||||||
|
RSAUtils utils = RSAUtils.getInstance(mContext);
|
||||||
|
KeyPair keyPair = utils.getOrGenerateKeys();
|
||||||
|
PublicKey publicKey = keyPair.getPublic();
|
||||||
|
|
||||||
|
// 公钥加密(传入字节数组,避免中间字符串转换)
|
||||||
|
byte[] encryptedData = utils.encryptWithPublicKey(szInfo, publicKey);
|
||||||
|
|
||||||
|
// 保存加密字节数组到文件(直接操作字节,无需转字符串)
|
||||||
|
FileUtils.writeByteArrayToFile(encryptedData, mUserInfoModelPath);
|
||||||
|
LogUtils.d(TAG, "加密数据已保存");
|
||||||
|
|
||||||
|
// 测试解密(仅调试用)
|
||||||
|
String szInfo2 = utils.decryptWithPrivateKey(encryptedData, keyPair.getPrivate());
|
||||||
|
LogUtils.d(TAG, "解密结果: " + szInfo2);
|
||||||
|
|
||||||
|
mUserInfoModel = UserInfoModel.parseStringToBean(szInfo2, UserInfoModel.class);
|
||||||
|
if (mUserInfoModel == null) {
|
||||||
|
LogUtils.d(TAG, "模型解析失败");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.d(TAG, "加密/解密失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送 POST 请求(JSON 数据)
|
||||||
|
public void sendPostRequest(String url, String data, OnResponseListener listener) {
|
||||||
|
RequestBody requestBody = RequestBody.create(
|
||||||
|
MediaType.parse("application/json; charset=utf-8"), // 关键头信息
|
||||||
|
data.getBytes(StandardCharsets.UTF_8)
|
||||||
|
);
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.post(requestBody)
|
||||||
|
.addHeader("Content-Type", "application/json") // 显式添加头
|
||||||
|
.build();
|
||||||
|
|
||||||
|
executeRequest(request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送 GET 请求
|
||||||
|
public void sendGetRequest(String url, OnResponseListener listener) {
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.get()
|
||||||
|
.build();
|
||||||
|
executeRequest(request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行请求(子线程处理)
|
||||||
|
private void executeRequest(final Request request, final OnResponseListener listener) {
|
||||||
|
okHttpClient.newCall(request).enqueue(new Callback() {
|
||||||
|
// 响应成功(子线程)
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call call, Response response) throws IOException {
|
||||||
|
try {
|
||||||
|
if (!response.isSuccessful()) {
|
||||||
|
postFailure(listener, "响应码错误:" + response.code());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String responseBody = response.body().string();
|
||||||
|
postSuccess(listener, responseBody);
|
||||||
|
} catch (Exception e) {
|
||||||
|
postFailure(listener, "解析失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应失败(子线程)
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, IOException e) {
|
||||||
|
postFailure(listener, "网络失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主线程回调(使用 Handler)
|
||||||
|
private void postSuccess(final OnResponseListener listener, final String msg) {
|
||||||
|
mainHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
listener.onSuccess(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postFailure(final OnResponseListener listener, final String msg) {
|
||||||
|
mainHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
listener.onFailure(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnResponseListener {
|
||||||
|
/**
|
||||||
|
* 成功响应(主线程回调)
|
||||||
|
* @param responseBody 响应体字符串
|
||||||
|
*/
|
||||||
|
void onSuccess(String responseBody);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败回调(包含错误信息)
|
||||||
|
* @param errorMsg 错误描述
|
||||||
|
*/
|
||||||
|
void onFailure(String errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.widgets;
|
package cc.winboll.studio.winboll.widgets;
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
* @Date 2025/02/15 14:41:25
|
* @Date 2025/02/15 14:41:25
|
||||||
@@ -11,18 +11,17 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import cc.winboll.studio.appbase.R;
|
import cc.winboll.studio.libaes.models.WinBoLLModel;
|
||||||
import cc.winboll.studio.appbase.receivers.APPNewsWidgetClickListener;
|
import cc.winboll.studio.libaes.winboll.WinBoLL;
|
||||||
import cc.winboll.studio.libappbase.AppUtils;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.models.APPModel;
|
import cc.winboll.studio.libapputils.utils.AppUtils;
|
||||||
import cc.winboll.studio.libappbase.models.WinBoLLNewsBean;
|
import cc.winboll.studio.winboll.R;
|
||||||
import cc.winboll.studio.libappbase.winboll.WinBoLL;
|
import cc.winboll.studio.winboll.models.WinBoLLNewsBean;
|
||||||
|
import cc.winboll.studio.winboll.receivers.APPNewsWidgetClickListener;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import cc.winboll.studio.libappbase.models.WinBoLLModel;
|
|
||||||
|
|
||||||
public class APPNewsWidget extends AppWidgetProvider {
|
public class APPNewsWidget extends AppWidgetProvider {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.appbase.widgets;
|
package cc.winboll.studio.winboll.widgets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -11,12 +11,8 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.winboll.R;
|
||||||
import cc.winboll.studio.libappbase.R;
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
import cc.winboll.studio.libappbase.utils.ServiceUtils;
|
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
|
||||||
|
|
||||||
public class StatusWidget extends AppWidgetProvider {
|
public class StatusWidget extends AppWidgetProvider {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cc.winboll.studio.libappbase.widgets;
|
package cc.winboll.studio.winboll.widgets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -9,7 +9,7 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
|
|
||||||
public class StatusWidgetClickListener extends BroadcastReceiver {
|
public class StatusWidgetClickListener extends BroadcastReceiver {
|
||||||
|
|
||||||
|
|||||||
11
winboll/src/main/res/drawable/ic_cloud.xml
Normal file
11
winboll/src/main/res/drawable/ic_cloud.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#ff000000"
|
||||||
|
android:pathData="M6.5,20Q4.22,20 2.61,18.43 1,16.85 1,14.58 1,12.63 2.17,11.1 3.35,9.57 5.25,9.15 5.88,6.85 7.75,5.43 9.63,4 12,4 14.93,4 16.96,6.04 19,8.07 19,11 20.73,11.2 21.86,12.5 23,13.78 23,15.5 23,17.38 21.69,18.69 20.38,20 18.5,20Z"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
11
winboll/src/main/res/drawable/ic_cloud_outline.xml
Normal file
11
winboll/src/main/res/drawable/ic_cloud_outline.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#ff000000"
|
||||||
|
android:pathData="M6.5,20Q4.22,20 2.61,18.43 1,16.85 1,14.58 1,12.63 2.17,11.1 3.35,9.57 5.25,9.15 5.88,6.85 7.75,5.43 9.63,4 12,4 14.93,4 16.96,6.04 19,8.07 19,11 20.73,11.2 21.86,12.5 23,13.78 23,15.5 23,17.38 21.69,18.69 20.38,20 18.5,20M6.5,18H18.5Q19.55,18 20.27,17.27 21,16.55 21,15.5 21,14.45 20.27,13.73 19.55,13 18.5,13H17V11Q17,8.93 15.54,7.46 14.08,6 12,6 9.93,6 8.46,7.46 7,8.93 7,11H6.5Q5.05,11 4.03,12.03 3,13.05 3,14.5 3,15.95 4.03,17 5.05,18 6.5,18M12,12Z"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
Reference in New Issue
Block a user