diff --git a/winboll/build.gradle b/winboll/build.gradle
index 820fc34..dc782b2 100644
--- a/winboll/build.gradle
+++ b/winboll/build.gradle
@@ -90,12 +90,12 @@ dependencies {
//annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
// WinBoLL库 nexus.winboll.cc 地址
- api 'cc.winboll.studio:libaes:15.12.13'
- api 'cc.winboll.studio:libappbase:15.14.2'
+ api 'cc.winboll.studio:libaes:15.15.7'
+ api 'cc.winboll.studio:libappbase:15.15.4'
// WinBoLL备用库 jitpack.io 地址
- //api 'com.github.ZhanGSKen:AES:aes-v15.12.9'
- //api 'com.github.ZhanGSKen:APPBase:appbase-v15.14.1'
+ //api 'com.github.ZhanGSKen:AES:aes-v15.15.7'
+ //api 'com.github.ZhanGSKen:APPBase:appbase-v15.15.4'
api fileTree(dir: 'libs', include: ['*.jar'])
}
diff --git a/winboll/build.properties b/winboll/build.properties
index f6c4c0f..1ddcdbd 100644
--- a/winboll/build.properties
+++ b/winboll/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Tue Jan 13 03:11:40 HKT 2026
-stageCount=10
+#Mon Jan 19 03:57:58 GMT 2026
+stageCount=11
libraryProject=
baseVersion=15.11
-publishVersion=15.11.9
-buildCount=0
-baseBetaVersion=15.11.10
+publishVersion=15.11.10
+buildCount=12
+baseBetaVersion=15.11.11
diff --git a/winboll/src/main/AndroidManifest.xml b/winboll/src/main/AndroidManifest.xml
index 8236f00..6fac454 100644
--- a/winboll/src/main/AndroidManifest.xml
+++ b/winboll/src/main/AndroidManifest.xml
@@ -1,7 +1,8 @@
+ package="cc.winboll.studio.winboll"
+ android:sharedUserId="com.termux">
@@ -282,6 +283,8 @@
+
+
-
\ No newline at end of file
+
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/CustomToolbar.java b/winboll/src/main/java/cc/winboll/studio/winboll/CustomToolbar.java
deleted file mode 100644
index d9d255b..0000000
--- a/winboll/src/main/java/cc/winboll/studio/winboll/CustomToolbar.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package cc.winboll.studio.winboll;
-
-/**
- * @Author ZhanGSKen
- * @Date 2025/05/22 13:08
- */
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.Toolbar;
-
-public class CustomToolbar extends Toolbar {
-
- private View viewMain;
-
- public CustomToolbar(Context context) {
- this(context, null);
- }
-
- public CustomToolbar(Context context, @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public CustomToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initView(context, attrs);
- }
-
- private void initView(Context context, AttributeSet attrs) {
- TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomToolbar);
-
- // 获取属性值
- String toolbarTitle = typedArray.getString(R.styleable.CustomToolbar_toolbarTitle);
- int toolbarTitleColor = typedArray.getColor(R.styleable.CustomToolbar_toolbarTitleColor, android.graphics.Color.WHITE);
- int toolbarBackgroundColor = typedArray.getColor(R.styleable.CustomToolbar_toolbarBackgroundColor, android.graphics.Color.BLUE);
-
- // 加载布局
- viewMain = LayoutInflater.from(context).inflate(R.layout.view_toolbar, this, true);
-
- // 应用属性值
- TextView toolbarTitleTextView = viewMain.findViewById(R.id.toolbar_title);
- toolbarTitleTextView.setText(toolbarTitle);
- toolbarTitleTextView.setTextColor(toolbarTitleColor);
- viewMain.setBackgroundColor(toolbarBackgroundColor);
-
- // 释放 TypedArray
- typedArray.recycle();
- }
-}
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/MainActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/MainActivity.java
index 935b86f..356a756 100644
--- a/winboll/src/main/java/cc/winboll/studio/winboll/MainActivity.java
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/MainActivity.java
@@ -8,23 +8,22 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
-import cc.winboll.studio.libaes.activitys.AboutActivity;
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
-import cc.winboll.studio.libaes.models.APPInfo;
import cc.winboll.studio.libaes.models.DrawerMenuBean;
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.winboll.R;
+import cc.winboll.studio.winboll.activities.AboutActivity;
import cc.winboll.studio.winboll.activities.SettingsActivity;
-import cc.winboll.studio.winboll.activities.WXPayActivity;
import cc.winboll.studio.winboll.fragments.BrowserFragment;
+import cc.winboll.studio.winboll.unittest.TermuxEnvTestActivity;
import java.util.ArrayList;
public class MainActivity extends DrawerFragmentActivity {
public static final String TAG = "MainActivity";
-
+
BrowserFragment mBrowserFragment;
// ------------------- 新增:Handler 消息定义(接收URL历史更新消息) -------------------
@@ -46,6 +45,12 @@ public class MainActivity extends DrawerFragmentActivity {
showFragment(mBrowserFragment);
}
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+
public static void sendMessage(Message msg) {
_mMainHandler.sendMessage(msg);
}
@@ -123,6 +128,7 @@ public class MainActivity extends DrawerFragmentActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_main, menu);
+ getMenuInflater().inflate(R.menu.toolbar_termux, menu);
return super.onCreateOptionsMenu(menu);
}
@@ -149,12 +155,13 @@ public class MainActivity extends DrawerFragmentActivity {
}
} else if (nItemId == R.id.item_settings) {
WinBoLLActivityManager.getInstance().startWinBoLLActivity(getApplicationContext(), SettingsActivity.class);
- } else if (nItemId == R.id.item_wxpayactivity) {
- WinBoLLActivityManager.getInstance().startWinBoLLActivity(getApplicationContext(), WXPayActivity.class);
- } else if (nItemId == cc.winboll.studio.libaes.R.id.item_about) {
+ } else if (nItemId == R.id.item_about) {
Intent intent = new Intent(getApplicationContext(), AboutActivity.class);
- APPInfo appInfo = genDefaultAPPInfo();
- intent.putExtra(AboutActivity.EXTRA_APPINFO, appInfo);
+
+ WinBoLLActivityManager.getInstance().startWinBoLLActivity(getApplicationContext(), intent, AboutActivity.class);
+ } else if (nItemId == R.id.item_termux_env_test) {
+ Intent intent = new Intent(getApplicationContext(), TermuxEnvTestActivity.class);
+
WinBoLLActivityManager.getInstance().startWinBoLLActivity(getApplicationContext(), intent, AboutActivity.class);
} else {
return super.onOptionsItemSelected(item);
@@ -163,23 +170,6 @@ public class MainActivity extends DrawerFragmentActivity {
return true;
}
-
- APPInfo genDefaultAPPInfo() {
- String szBranchName = "winboll";
- APPInfo appInfo = new APPInfo();
- appInfo.setAppName("WinBoLL");
- appInfo.setAppIcon(cc.winboll.studio.libaes.R.drawable.ic_winboll);
- appInfo.setAppDescription("WinBoLL 网站浏览器。");
- appInfo.setAppGitName("WinBoLL");
- appInfo.setAppGitOwner("Studio");
- appInfo.setAppGitAPPBranch(szBranchName);
- appInfo.setAppGitAPPSubProjectFolder(szBranchName);
- appInfo.setAppHomePage("https://www.winboll.cc/apks/index.php?project=WinBoLL");
- appInfo.setAppAPKName("WinBoLL");
- appInfo.setAppAPKFolderName("WinBoLL");
- return appInfo;
- }
-
// ------------------- 新增:对外提供Handler(供其他组件发送消息,如BrowserFragment) -------------------
public Handler getMainHandler() {
return _mMainHandler;
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/activities/AboutActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/activities/AboutActivity.java
new file mode 100644
index 0000000..b1761b4
--- /dev/null
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/activities/AboutActivity.java
@@ -0,0 +1,80 @@
+package cc.winboll.studio.winboll.activities;
+
+import android.os.Bundle;
+import android.view.View;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libappbase.models.APPInfo;
+import cc.winboll.studio.libappbase.views.AboutView;
+import cc.winboll.studio.winboll.MainActivity;
+import cc.winboll.studio.winboll.R;
+
+/**
+ * @Author 豆包&ZhanGSKen
+ * @Date 2026/01/13 11:54
+ * @Describe 应用介绍窗口
+ */
+public class AboutActivity extends BaseWinBoLLActivity {
+
+ public static final String TAG = "AboutActivity";
+
+ private Toolbar mToolbar;
+
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_about);
+
+ // 设置工具栏
+ initToolbar();
+
+ AboutView aboutView = getActivity().findViewById(R.id.aboutview);
+ aboutView.setAPPInfo(genDefaultAppInfo());
+ }
+
+ private void initToolbar() {
+ LogUtils.d(TAG, "initToolbar() 开始初始化");
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
+ if (mToolbar == null) {
+ LogUtils.e(TAG, "initToolbar() | Toolbar未找到");
+ return;
+ }
+ setSupportActionBar(mToolbar);
+ mToolbar.setSubtitle(getTag());
+ ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ LogUtils.d(TAG, "导航栏 点击返回按钮");
+ getActivity().finish();
+ WinBoLLActivityManager.getInstance().startWinBoLLActivity(getActivity(), MainActivity.class);
+ }
+ });
+ LogUtils.d(TAG, "initToolbar() 配置完成");
+ }
+
+ private APPInfo genDefaultAppInfo() {
+ LogUtils.d(TAG, "genDefaultAppInfo() 调用");
+ String branchName = "winboll";
+ APPInfo appInfo = new APPInfo();
+ appInfo.setAppName(getActivity().getString(R.string.app_name));
+ appInfo.setAppIcon(R.drawable.ic_winboll);
+ appInfo.setAppDescription(getActivity().getString(R.string.app_description));
+ appInfo.setAppGitName("WinBoLL");
+ appInfo.setAppGitOwner("Studio");
+ appInfo.setAppGitAPPBranch(branchName);
+ appInfo.setAppGitAPPSubProjectFolder(branchName);
+ appInfo.setAppHomePage("https://www.winboll.cc/apks/index.php?project=WinBoLL");
+ appInfo.setAppAPKName("WinBoLL");
+ appInfo.setAppAPKFolderName("WinBoLL");
+ LogUtils.d(TAG, "genDefaultAppInfo: 应用信息已生成");
+ return appInfo;
+ }
+}
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/activities/BaseWinBoLLActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/activities/BaseWinBoLLActivity.java
new file mode 100644
index 0000000..f9edcd4
--- /dev/null
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/activities/BaseWinBoLLActivity.java
@@ -0,0 +1,59 @@
+package cc.winboll.studio.winboll.activities;
+
+import android.app.Activity;
+import android.os.Bundle;
+import androidx.appcompat.app.AppCompatActivity;
+import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
+import cc.winboll.studio.libaes.models.AESThemeBean;
+import cc.winboll.studio.libaes.utils.AESThemeUtil;
+import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
+
+/**
+ * @Author 豆包&ZhanGSKen
+ * @Date 2026/01/13 16:33
+ * BaseWinBollActivity 【继承AppCompatActivity,保留核心能力,不额外暴露方法】
+ * 继承链路:BaseWinBoLLActivity → AppCompatActivity → FragmentActivity,AppCompat能力天然继承可用
+ */
+public abstract class BaseWinBoLLActivity extends AppCompatActivity implements IWinBoLLActivity {
+ public static final String TAG = "BaseWinBoLLActivity";
+
+ protected volatile AESThemeBean.ThemeType mThemeType;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ mThemeType = getThemeType();
+ setThemeStyle();
+ super.onCreate(savedInstanceState);
+ WinBoLLActivityManager.getInstance().add(this);
+ //ToastUtils.show(getTag() + ": onCreate");
+ }
+
+ 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
+ protected void onDestroy() {
+ WinBoLLActivityManager.getInstance().registeRemove(this);
+ super.onDestroy();
+ }
+
+ // 子类必须实现getTag(),确保唯一标识
+ @Override
+ public abstract String getTag();
+
+ @Override
+ public Activity getActivity() {
+ return this;
+ }
+}
+
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/activities/New2Activity.java b/winboll/src/main/java/cc/winboll/studio/winboll/activities/New2Activity.java
index 21620b5..7b19999 100644
--- a/winboll/src/main/java/cc/winboll/studio/winboll/activities/New2Activity.java
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/activities/New2Activity.java
@@ -5,20 +5,25 @@ package cc.winboll.studio.winboll.activities;
* @Date 2025/03/25 11:46:40
* @Describe 测试窗口2
*/
-import android.app.Activity;
import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.View;
-import android.widget.Toolbar;
+import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.winboll.R;
-public class New2Activity extends WinBoLLActivity {
+public class New2Activity extends BaseWinBoLLActivity {
public static final String TAG = "New2Activity";
Toolbar mToolbar;
+
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
//LogView mLogView;
+
+
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -28,15 +33,10 @@ public class New2Activity extends WinBoLLActivity {
// mLogView = findViewById(R.id.logview);
// mLogView.start();
mToolbar = findViewById(R.id.toolbar);
- setActionBar(mToolbar);
+ setSupportActionBar(mToolbar);
}
- @Override
- protected void onResume() {
- super.onResume();
- //mLogView.start();
- }
public void onCloseThisActivity(View view) {
//WinBoLLActivityManager.getInstance().finish(this);
@@ -49,17 +49,4 @@ public class New2Activity extends WinBoLLActivity {
public void onNewActivity(View view) {
//WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, NewActivity.class);
}
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- //getMenuInflater().inflate(R.menu.toolbar_main, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
- return super.onOptionsItemSelected(item);
- }
}
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/activities/NewActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/activities/NewActivity.java
index a120f7b..430a0e9 100644
--- a/winboll/src/main/java/cc/winboll/studio/winboll/activities/NewActivity.java
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/activities/NewActivity.java
@@ -5,29 +5,19 @@ package cc.winboll.studio.winboll.activities;
* @Date 2025/03/25 05:04:22
* @Describe
*/
-import android.app.Activity;
import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.View;
-import android.widget.Toolbar;
-import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
+import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
import cc.winboll.studio.winboll.R;
-import cc.winboll.studio.winboll.App;
-public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
+public class NewActivity extends BaseWinBoLLActivity {
public static final String TAG = "NewActivity";
Toolbar mToolbar;
//LogView mLogView;
- @Override
- public Activity getActivity() {
- return this;
- }
-
@Override
public String getTag() {
return TAG;
@@ -40,15 +30,10 @@ public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
// mLogView = findViewById(R.id.logview);
// mLogView.start();
mToolbar = findViewById(R.id.toolbar);
- setActionBar(mToolbar);
+ setSupportActionBar(mToolbar);
}
- @Override
- protected void onResume() {
- super.onResume();
- //mLogView.start();
- }
public void onCloseThisActivity(View view) {
WinBoLLActivityManager.getInstance().finish(this);
@@ -61,17 +46,4 @@ public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
public void onNew2Activity(View view) {
// WinBoLLActivityManager.getInstance().startWinBoLLActivity(App.getInstance(), New2Activity.class);
}
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- //getMenuInflater().inflate(R.menu.toolbar_main, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
- return super.onOptionsItemSelected(item);
- }
}
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/activities/SettingsActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/activities/SettingsActivity.java
index 19a2908..d3bb54e 100644
--- a/winboll/src/main/java/cc/winboll/studio/winboll/activities/SettingsActivity.java
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/activities/SettingsActivity.java
@@ -1,10 +1,8 @@
package cc.winboll.studio.winboll.activities;
-import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.widget.Toolbar;
-import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.winboll.R;
@@ -13,15 +11,10 @@ import cc.winboll.studio.winboll.R;
* @Date 2025/12/05 18:48
* @Describe Settings Activity
*/
-public class SettingsActivity extends WinBoLLActivity implements IWinBoLLActivity {
+public class SettingsActivity extends BaseWinBoLLActivity {
public static final String TAG = "SettingsActivity";
- @Override
- public Activity getActivity() {
- return this;
- }
-
@Override
public String getTag() {
return TAG;
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/activities/WXPayActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/activities/WXPayActivity.java
deleted file mode 100644
index e881993..0000000
--- a/winboll/src/main/java/cc/winboll/studio/winboll/activities/WXPayActivity.java
+++ /dev/null
@@ -1,211 +0,0 @@
-package cc.winboll.studio.winboll.activities;
-
-import android.app.Activity;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
-import cc.winboll.studio.winboll.R;
-import cc.winboll.studio.winboll.WxPayConfig;
-import cc.winboll.studio.winboll.utils.SpecUtil;
-import cc.winboll.studio.winboll.utils.WxPayApi;
-import cc.winboll.studio.winboll.utils.ZXingUtils;
-import java.util.Timer;
-import java.util.TimerTask;
-
-
-
-/**
- * 主界面:生成二维码 + 轮询查询支付结果
- * @Author ZhanGSKen
- * @Date 2026/01/07
- */
-public class WXPayActivity extends WinBoLLActivity implements IWinBoLLActivity {
-
- private static final String TAG = "WXPayActivity";
-
- // Handler消息标识
- private static final int MSG_POLL_TIMEOUT = 1001;
- private static final int MSG_POLL_SUCCESS = 1002;
- private static final int MSG_POLL_FAILED = 1003;
-
- private ImageView mIvQrCode;
- private TextView mTvOrderNo;
- private TextView mTvPayStatus;
- private Button mBtnCreateOrder;
-
- private String mOutTradeNo; // 商户订单号
- private Timer mPollTimer; // 轮询定时器
- private long mPollStartTime; // 轮询开始时间
-
-
-
- @Override
- public Activity getActivity() {
- return this;
- }
-
- @Override
- public String getTag() {
- return TAG;
- }
-
- private Handler mPollHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- switch (msg.what) {
- case MSG_POLL_TIMEOUT:
- stopPoll();
- mTvPayStatus.setText("支付状态:轮询超时");
- mTvPayStatus.setTextColor(getResources().getColor(android.R.color.darker_gray));
- Toast.makeText(WXPayActivity.this, "轮询超时,请手动查询", Toast.LENGTH_SHORT).show();
- break;
- case MSG_POLL_SUCCESS:
- boolean isPaySuccess = (boolean) msg.obj;
- String tradeState = (String) msg.getData().getString("tradeState");
- stopPoll();
- if (isPaySuccess) {
- mTvPayStatus.setText("支付状态:支付成功 ✅");
- mTvPayStatus.setTextColor(getResources().getColor(android.R.color.holo_green_dark));
- Toast.makeText(WXPayActivity.this, "支付成功!", Toast.LENGTH_SHORT).show();
- } else {
- mTvPayStatus.setText("支付状态:" + tradeState);
- mTvPayStatus.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
- }
- break;
- case MSG_POLL_FAILED:
- String errorMsg = (String) msg.obj;
- mTvPayStatus.setText("查询失败:" + errorMsg);
- break;
- }
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_wxpay);
-
- initView();
- initListener();
- }
-
- private void initView() {
- mIvQrCode = findViewById(R.id.iv_qrcode);
- mTvOrderNo = findViewById(R.id.tv_order_no);
- mTvPayStatus = findViewById(R.id.tv_pay_status);
- mBtnCreateOrder = findViewById(R.id.btn_create_order);
- }
-
- private void initListener() {
- mBtnCreateOrder.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- createOrder();
- }
- });
- }
-
- /**
- * 统一下单,生成二维码
- */
- private void createOrder() {
- mBtnCreateOrder.setEnabled(false);
- mTvPayStatus.setText("支付状态:生成订单中...");
- mIvQrCode.setImageBitmap(null);
-
- WxPayApi.createOrder(new WxPayApi.OnCreateOrderCallback() {
- @Override
- public void onSuccess(String outTradeNo, String codeUrl) {
- mOutTradeNo = outTradeNo;
- mTvOrderNo.setText("商户订单号:" + outTradeNo);
- mTvPayStatus.setText("支付状态:未支付,请扫码");
-
- // 生成二维码
- Bitmap qrCodeBitmap = ZXingUtils.createQRCodeBitmap(codeUrl, 250, 250);
- if (qrCodeBitmap != null) {
- mIvQrCode.setImageBitmap(qrCodeBitmap);
- // 开始轮询查询支付结果
- startPoll();
- } else {
- mTvPayStatus.setText("支付状态:生成二维码失败");
- mBtnCreateOrder.setEnabled(true);
- }
- }
-
- @Override
- public void onFailure(String errorMsg) {
- SpecUtil.WWSpecLogError(TAG, "统一下单失败:" + errorMsg);
- mTvPayStatus.setText("生成订单失败:" + errorMsg);
- mBtnCreateOrder.setEnabled(true);
- Toast.makeText(WXPayActivity.this, errorMsg, Toast.LENGTH_SHORT).show();
- }
- });
- }
-
- /**
- * 开始轮询查询支付结果
- */
- private void startPoll() {
- stopPoll(); // 先停止之前的轮询
- mPollStartTime = System.currentTimeMillis();
- mPollTimer = new Timer();
- mPollTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- // 检查是否超时
- long elapsedTime = System.currentTimeMillis() - mPollStartTime;
- if (elapsedTime >= WxPayConfig.POLL_TIMEOUT) {
- mPollHandler.sendEmptyMessage(MSG_POLL_TIMEOUT);
- return;
- }
-
- // 查询订单状态
- WxPayApi.queryOrder(mOutTradeNo, new WxPayApi.OnQueryOrderCallback() {
- @Override
- public void onSuccess(boolean isPaySuccess, String tradeState) {
- Message msg = Message.obtain();
- msg.what = MSG_POLL_SUCCESS;
- msg.obj = isPaySuccess;
- Bundle bundle = new Bundle();
- bundle.putString("tradeState", tradeState);
- msg.setData(bundle);
- mPollHandler.sendMessage(msg);
- }
-
- @Override
- public void onFailure(String errorMsg) {
- Message msg = Message.obtain();
- msg.what = MSG_POLL_FAILED;
- msg.obj = errorMsg;
- mPollHandler.sendMessage(msg);
- }
- });
- }
- }, 0, WxPayConfig.POLL_INTERVAL);
- }
-
- /**
- * 停止轮询
- */
- private void stopPoll() {
- if (mPollTimer != null) {
- mPollTimer.cancel();
- mPollTimer = null;
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- stopPoll();
- }
-}
-
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/activities/WinBoLLActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/activities/WinBoLLActivity.java
deleted file mode 100644
index 8f47d37..0000000
--- a/winboll/src/main/java/cc/winboll/studio/winboll/activities/WinBoLLActivity.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package cc.winboll.studio.winboll.activities;
-
-/**
- * @Author ZhanGSKen
- * @Date 2025/05/10 09:48
- * @Describe WinBoLL 窗口基础类
- */
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.MenuItem;
-import androidx.appcompat.app.AppCompatActivity;
-import cc.winboll.studio.libappbase.LogUtils;
-
-public class WinBoLLActivity extends AppCompatActivity {
-
- public static final String TAG = "WinBoLLActivity";
-
- @Override
- protected void onResume() {
- super.onResume();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- /*if (item.getItemId() == R.id.item_log) {
- WinBoLLActivityManager.getInstance().startLogActivity(this);
- return true;
- } else if (item.getItemId() == R.id.item_home) {
- startActivity(new Intent(this, MainActivity.class));
- return true;
- }*/
- // 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- //WinBoLLActivityManager.getInstance().add(this);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- //WinBoLLActivityManager.getInstance().registeRemove(this);
- }
-}
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TermuxEnvTestActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TermuxEnvTestActivity.java
new file mode 100644
index 0000000..94c432a
--- /dev/null
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TermuxEnvTestActivity.java
@@ -0,0 +1,147 @@
+package cc.winboll.studio.winboll.unittest;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
+import cc.winboll.studio.libappbase.LogUtils;
+import cc.winboll.studio.libappbase.ToastUtils;
+import cc.winboll.studio.winboll.MainActivity;
+import cc.winboll.studio.winboll.R;
+import cc.winboll.studio.winboll.activities.BaseWinBoLLActivity;
+import java.io.File;
+
+/**
+ * @Author 豆包&ZhanGSKen
+ * @Date 2026/01/19 11:11
+ * @LastEditTime 2026/01/19 15:30
+ * @Describe Termux 环境测试(新增:读取Termux主目录文件列表功能)
+ */
+public class TermuxEnvTestActivity extends BaseWinBoLLActivity {
+
+ public static final String TAG = "TermuxEnvTestActivity";
+ // Termux主目录固定路径
+ private static final String TERMUX_HOME_PATH = "/data/data/com.termux/files/home/WinBoLLStudio";
+
+ private Toolbar mToolbar;
+
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_termux_env_test);
+ initToolbar();
+ }
+
+ private void initToolbar() {
+ LogUtils.d(TAG, "initToolbar() 开始初始化");
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
+ if (mToolbar == null) {
+ LogUtils.e(TAG, "initToolbar() | Toolbar未找到");
+ return;
+ }
+ setSupportActionBar(mToolbar);
+ mToolbar.setSubtitle(getTag());
+ ((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ LogUtils.d(TAG, "导航栏 点击返回按钮");
+ getActivity().finish();
+ WinBoLLActivityManager.getInstance().startWinBoLLActivity(getActivity(), MainActivity.class);
+ }
+ });
+ LogUtils.d(TAG, "initToolbar() 配置完成");
+ }
+
+ /**
+ * 核心功能:读取Termux主目录文件列表,返回字符串格式
+ * @return 目录路径+文件列表(换行分隔),异常时返回错误信息
+ */
+ public String readTermuxHomeFileList() {
+ LogUtils.d(TAG, "开始读取Termux目录:" + TERMUX_HOME_PATH);
+ File termuxHomeDir = new File(TERMUX_HOME_PATH);
+ StringBuilder result = new StringBuilder();
+
+ // 1. 检查目录是否存在
+ if (!termuxHomeDir.exists()) {
+ String errorMsg = "错误:Termux目录不存在 → " + TERMUX_HOME_PATH;
+ LogUtils.e(TAG, errorMsg);
+ return errorMsg;
+ }
+
+ // 2. 检查是否为目录
+ if (!termuxHomeDir.isDirectory()) {
+ String errorMsg = "错误:指定路径不是目录 → " + TERMUX_HOME_PATH;
+ LogUtils.e(TAG, errorMsg);
+ return errorMsg;
+ }
+
+ // 3. 检查读写权限
+ if (!termuxHomeDir.canRead()) {
+ String errorMsg = "错误:无目录读取权限 → " + TERMUX_HOME_PATH;
+ LogUtils.e(TAG, errorMsg);
+ return errorMsg;
+ }
+
+ // 4. 获取目录下所有文件/子目录
+ File[] files = termuxHomeDir.listFiles();
+ if (files == null || files.length == 0) {
+ String emptyMsg = "Termux目录为空 → " + TERMUX_HOME_PATH;
+ LogUtils.d(TAG, emptyMsg);
+ return emptyMsg;
+ }
+
+ // 5. 拼接文件列表字符串(包含类型、名称、路径)
+ result.append("Termux主目录:").append(TERMUX_HOME_PATH).append("\n");
+ result.append("文件/子目录总数:").append(files.length).append("\n");
+ result.append("-------------------------\n");
+ for (File file : files) {
+ String fileType = file.isDirectory() ? "[目录]" : "[文件]";
+ String fileName = file.getName();
+ String filePath = file.getAbsolutePath();
+ result.append(fileType).append(" ").append(fileName).append(" → ").append(filePath).append("\n");
+ }
+
+ // 6. 去除末尾多余换行
+ String fileListStr = result.toString().trim();
+ LogUtils.d(TAG, "Termux目录读取完成,结果长度:" + fileListStr.length());
+ return fileListStr;
+ }
+
+ public void onTestTermuxEnv(View view) {
+ TextView tvMessage = findViewById(R.id.tv_message);
+ // 测试:读取Termux目录文件列表并打印日志
+ String fileListStr = readTermuxHomeFileList();
+ tvMessage.append(fileListStr);
+ }
+
+ public void onTestTermuxCMD(View view) {
+ // pkg update && pkg upgrade -y
+ // pkg install termux-api -y
+
+ Intent intent = new Intent();
+ intent.setPackage("com.termux");
+ intent.setAction("com.termux.RUN_COMMAND");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.putExtra("com.termux.RUN_COMMAND_PATH", "/data/data/com.termux/files/home");
+ intent.putExtra("com.termux.RUN_COMMAND_ARGUMENTS", new String[]{"ls"});
+ intent.putExtra("com.termux.RUN_COMMAND_WAIT_FOR_RESULT", false);
+ intent.putExtra("com.termux.RUN_COMMAND_BACKGROUND", false);
+ if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(intent);
+ } else {
+ Toast.makeText(this, "Termux或Termux:API未正确安装", Toast.LENGTH_SHORT).show();
+ }
+
+ }
+}
+
diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TestWeWorkSpecSDK.java b/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TestWeWorkSpecSDK.java
index 5fdac27..08aa2a1 100644
--- a/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TestWeWorkSpecSDK.java
+++ b/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TestWeWorkSpecSDK.java
@@ -7,10 +7,10 @@ import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
+import androidx.appcompat.app.AppCompatActivity;
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.winboll.R;
-import cc.winboll.studio.winboll.activities.WinBoLLActivity;
/**
* @Author 豆包&ZhanGSKen
@@ -18,7 +18,7 @@ import cc.winboll.studio.winboll.activities.WinBoLLActivity;
* @Describe 企业微信SDK接口测试(基础调试版)
* 包含:SDK初始化、基础接口调用、日志输出、主线程回调处理
*/
-public class TestWeWorkSpecSDK extends WinBoLLActivity implements IWinBoLLActivity, View.OnClickListener {
+public class TestWeWorkSpecSDK extends AppCompatActivity implements IWinBoLLActivity, View.OnClickListener {
public static final String TAG = "TestWeWorkSpecSDK";
diff --git a/winboll/src/main/java/com/tencent/wework/SpecCallbackSDK.java b/winboll/src/main/java/com/tencent/wework/SpecCallbackSDK.java
deleted file mode 100644
index 18faee5..0000000
--- a/winboll/src/main/java/com/tencent/wework/SpecCallbackSDK.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package com.tencent.wework;
-
-import java.util.Map;
-import java.util.HashMap;;
-
-/**
- * @warning: 1. 不要修改成员变量名,native方法内有反射调用
- * 2. 调用本地方法需保持包结构,本工具需放在包com.tencent.wework内
- * 3. 不允许继承,类名和函数名均不可修改,会影响本地方法的引用,详见:javah生成本地方法头文件
- */
-public final class SpecCallbackSDK {
-
- /**
- * @description 调用本地方法后实例化的对象指针
- */
- private long specCallbackSDKptr = 0;
-
- public long GetPtr() { return specCallbackSDKptr; }
-
- /**
- * @description: 回包的headers
- */
- private Map responseHeaders;
-
- public Map GetResponseHeaders() { return responseHeaders; }
-
- /**
- * @description: 回包的加密后的body
- */
- private String responseBody;
-
- public String GetResponseBody() { return responseBody; }
-
- /**
- * @description: 每个请求构造一个SpecCallbackSDK示例,
- * SpecCallbackSDK仅持有headers和body的引用,
- * 因此需保证headers和body的生存期比SpecCallbackSDK长
- * @param method: 请求方法GET/POST
- * @param headers: 请求header
- * @param body: 请求body
- * @example:
- * SpecCallbackSDK sdk = new SpecCallbackSDK(method, headers, body);
- * if (sdk.IsOk()) {
- * String corpid = sdk.GetCorpId();
- * String agentid = sdk.GetAgentId();
- * String call_type = sdk.GetCallType();
- * String data = sdk.GetData();
- * //do something...
- * }
- * String response = ...;
- * sdk.BuildResponseHeaderBody(response);
- * Map responseHeaders = sdk.GetResponseHeaders();
- * String body = sdk.GetResponseBody();
- * //do response
- *
- * @return errorcode 示例如下:
- * -920001: 未设置请求方法
- * -920002: 未设置请求header
- * -920003: 未设置请求body
- * */
- public SpecCallbackSDK(String method, Map headers, String body) {
- try {
- specCallbackSDKptr = NewCallbackSDK(method, headers, body);
- } catch (Exception e) {
- SpecUtil.WWSpecLogError("SpecCallbackSDK exception caught", e.getMessage());
- }
- }
-
- private native long NewCallbackSDK(String method, Map headers, String body);
-
- /**
- * @usage 在Java对象的内存回收前析构C++对象
- */
- @Override
- protected void finalize() throws Throwable {
- DeleteCPPInstance(specCallbackSDKptr);
- super.finalize();
- }
-
- private native void DeleteCPPInstance(long specCallbackSDKptr);
-
- /**
- * @description: 判断构造函数中传入的请求是否解析成功
- * @return: 成功与否
- * */
- public boolean IsOk() {
- return IsOk(specCallbackSDKptr);
- }
-
- private native boolean IsOk(long specCallbackSDKptr);
-
- /**
- * @description: 获取请求的企业
- * @require: 仅当IsOk() == true可调用
- * @return: corpid
- * */
- public String GetCorpId() {
- return GetCorpId(specCallbackSDKptr);
- }
-
- private native String GetCorpId(long specCallbackSDKptr);
-
- /**
- * @description: 获取请求的应用
- * @require: 仅当IsOk() == true可调用
- * @return: agentid
- * */
- public long GetAgentId() {
- return GetAgentId(specCallbackSDKptr);
- }
-
- private native long GetAgentId(long specCallbackSDKptr);
-
- /**
- * @description: 获取请求的类型
- * @require: 仅当IsOk() == true可调用
- * @return: 1 - 来自[应用调用专区]的请求
- * 2 - 来自企业微信的回调事件
- * */
- public long GetCallType() {
- return GetCallType(specCallbackSDKptr);
- }
-
- private native long GetCallType(long specCallbackSDKptr);
-
- /**
- * @description: 获取请求数据
- * @require: 仅当IsOk() == true可调用
- * @return: 请求数据,根据call_type可能是:
- * - 企业微信回调事件
- * - [应用调用专区]接口中的request_data
- * */
- public String GetData() {
- return GetData(specCallbackSDKptr);
- }
-
- private native String GetData(long specCallbackSDKptr);
-
- /**
- * @description: 是否异步请求
- * @require: 仅当IsOk() == true可调用
- * @return: 是否异步请求
- * */
- public boolean GetIsAsync() {
- return GetIsAsync(specCallbackSDKptr);
- }
-
- private native boolean GetIsAsync(long specCallbackSDKptr);
-
- /**
- * @description: 获取请求的job_info,
- * @require: 仅当IsOk() == true可调用
- * @return: job_info,无需理解内容,
- * 在同一个请求上下文中使用SpecSDK的时候传入
- * */
- public String GetJobInfo() {
- return GetJobInfo(specCallbackSDKptr);
- }
-
- private native String GetJobInfo(long specCallbackSDKptr);
-
- /**
- * @description: 获取请求的ability_id,[应用调用专区]接口时指定
- * @require: 仅当IsOk() == true可调用
- * @return: ability_id
- * */
- public String GetAbilityId() {
- return GetAbilityId(specCallbackSDKptr);
- }
-
- private native String GetAbilityId(long specCallbackSDKptr);
-
- /**
- * @description: 获取请求的notify_id,用于[应用同步调用专区程序]接口
- * @require: 仅当IsOk() == true可调用
- * @return: notify_id
- * */
- public String GetNotifyId() {
- return GetNotifyId(specCallbackSDKptr);
- }
-
- private native String GetNotifyId(long specCallbackSDKptr);
-
- /**
- * @description: 对返回包计算签名&加密
- * @param response: 待加密的回包明文.如果IsOk()==false,传入空串即可
- * @note 本接口的执行问题可查看日志
- * */
- public void BuildResponseHeaderBody(String response) {
- try {
- responseHeaders = new HashMap();
- responseBody = "";
- BuildResponseHeaderBody(specCallbackSDKptr, response);
- } catch (Exception e) {
- SpecUtil.WWSpecLogError("SpecCallbackSDK exception caught", e.getMessage());
- }
- }
-
- private native void BuildResponseHeaderBody(long specCallbackSDKptr, String response);
-
- // 静态代码块内还无法调用native日志函数,这里的日志在管理系统无法查询
- static {
- try {
- Class.forName("com.tencent.wework.SpecUtil");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-}
diff --git a/winboll/src/main/java/com/tencent/wework/SpecSDK.java b/winboll/src/main/java/com/tencent/wework/SpecSDK.java
deleted file mode 100644
index 8cf555a..0000000
--- a/winboll/src/main/java/com/tencent/wework/SpecSDK.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package com.tencent.wework;
-
-/**
- * @warning: 1. 不要修改成员变量名,native方法内有反射调用
- * 2. 调用本地方法需保持包结构,本工具需放在包com.tencent.wework内
- * 3. 不允许继承,类名和函数名均不可修改,会影响本地方法的引用,详见:javah生成本地方法头文件
- */
-public final class SpecSDK {
-
- /**
- * @description 调用本地方法后实例化的对象指针
- */
- private long specSDKptr = 0;
-
- /**
- * @usage invoke的请求
- * @example "{\"limit\":1}
- */
- private String request;
-
- public void SetRequest(String request) {
- this.request = request;
- }
-
- /**
- * @usage 访问上一次invoke的结果
- */
- private String response;
-
- public String GetResponse() {
- return response;
- }
-
- /**
- * @param corpid: 企业corpid,必选参数
- * @param agentid: 应用id,必选参数
- * @param ability_id: 能力ID,可选参数
- * @param job_info: job_info,可选参数
- * */
- public SpecSDK(String corpId, long agentId) {
- specSDKptr = NewSDK1(corpId, agentId);
- }
-
- private native long NewSDK1(String corpId, long agentId);
-
- public SpecSDK(String corpId, long agentId, String abilityId) {
- specSDKptr = NewSDK2(corpId, agentId, abilityId);
- }
-
- private native long NewSDK2(String corpId, long agentId, String abilityId);
-
- public SpecSDK(String corpId, long agentId, String abilityId, String jobInfo) {
- specSDKptr = NewSDK3(corpId, agentId, abilityId, jobInfo);
- }
-
- private native long NewSDK3(String corpId, long agentId, String abilityId, String jobInfo);
-
- /**
- * @description 使用callback的请求来初始化
- * @param callback_sdk: 要求IsOk()==true
- * @return C++内部指针,创建失败时指针仍为0,并输出错误日志
- * */
- public SpecSDK(SpecCallbackSDK callbackSDK) {
- specSDKptr = NewSDK4(callbackSDK.GetPtr());
- }
-
- private native long NewSDK4(long callbackSDK);
-
- /**
- * @usage 在Java对象的内存回收前析构C++对象
- */
- @Override
- protected void finalize() throws Throwable {
- DeleteCPPInstance(specSDKptr);
- super.finalize();
- }
-
- private native void DeleteCPPInstance(long specSDKptr);
-
- /**
- * @description 用于在专区内调用企业微信接口
- * @param api_name 接口名
- * @param request json格式的请求数据
- * @param response json格式的返回数据
- * @return errorcode 参考如下:
- * 0: 成功
- * -910001: SDK没有初始化
- * -910002: 没有设置请求体
- * -910003: 没有设置请求的API
- * -910004: 在SDK成员内找不到成员"response",注意lib内有反射机制,不要修改成员变量名
- * -910005: 使用未初始化的callback初始化SDK
- * -910006: invoke调用失败,应检查日志查看具体原因
- * -910007: 响应体为空
- * @note 当返回0时,表示没有网络或请求协议层面或调用方法的失败,
- * 调用方需继续检查response中的errcode字段确保业务层面的成功
- *
- * @usage 当前版本sdk支持的接口列表,每个接口的具体协议请查看企业微信文档:
- * https://developer.work.weixin.qq.com/document/path/91201
- *
- * +--------------------------------+--------------------------------+
- * |接口名 |描述 |
- * |--------------------------------|--------------------------------|
- * |program_async_job_call_back |上报异步任务结果 |
- * |sync_msg |获取会话记录 |
- * |get_group_chat |获取内部群信息 |
- * |get_agree_status_single |获取单聊会话同意情况 |
- * |get_agree_status_room |获取群聊会话同意情况 |
- * |set_hide_sensitiveinfo_config |设置成员会话组件敏感信息隐藏配置|
- * |get_hide_sensitiveinfo_config |获取成员会话组件敏感信息隐藏配置|
- * |search_chat |会话名称搜索 |
- * |search_msg |会话消息搜索 |
- * |create_rule |新增关键词规则 |
- * |get_rule_list |获取关键词列表 |
- * |get_rule_detail |获取关键词规则详情 |
- * |update_rule |修改关键词规则 |
- * |delete_rule |删除关键词规则 |
- * |get_hit_msg_list |获取命中关键词规则的会话记录 |
- * |create_sentiment_task |创建情感分析任务 |
- * |get_sentiment_result |获取情感分析结果 |
- * |create_summary_task |创建摘要提取任务 |
- * |get_summary_result |获取摘要提取结果 |
- * |create_customer_tag_task |创建标签匹配任务 |
- * |get_customer_tag_result |获取标签任务结果 |
- * |create_recommend_dialog_task |创建话术推荐任务 |
- * |get_recommend_dialog_result |获取话术推荐结果 |
- * |create_private_task |创建自定义模型任务 |
- * |get_private_task_result |获取自定义模型结果 |
- * |(废弃)document_list |获取知识集列表 |
- * |create_spam_task |会话反垃圾创建分析任务 |
- * |get_spam_result |会话反垃圾获取任务结果 |
- * |create_chatdata_export_job |创建会话内容导出任务 |
- * |get_chatdata_export_job_status |获取会话内容导出任务结果 |
- * |spec_notify_app |专区通知应用 |
- * |create_program_task |创建自定义程序任务 |
- * |get_program_task_result |获取自定义程序结果 |
- * |knowledge_base_list |获取企业授权给应用的知识集列表 |
- * |knowledge_base_create |创建知识集 |
- * |knowledge_base_detail |获取知识集详情 |
- * |knowledge_base_add_doc |添加知识集內容 |
- * |knowledge_base_remove_doc |删除知识集內容 |
- * |knowledge_base_modify_name |修改知识集名称 |
- * |knowledge_base_delete |删除知识集 |
- * |search_contact_or_customer |员工或者客户名称搜索 |
- * |create_ww_model_task |创建企微通用模型任务 |
- * |get_ww_model_result |获取企微通用模型结果 |
- * |get_msg_list_by_page_id |page_id获取消息列表 |
- * +-----------------------------------------------------------------+
- * */
- public int Invoke(String apiName) {
- return Invoke(specSDKptr, apiName, request);
- }
-
- private native int Invoke(long sdk, String apiName, String request);
-
- // 静态代码块内还无法调用native日志函数,这里的日志在管理系统无法查询
- static {
- try {
- Class.forName("com.tencent.wework.SpecUtil");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/winboll/src/main/java/com/tencent/wework/SpecUtil.java b/winboll/src/main/java/com/tencent/wework/SpecUtil.java
deleted file mode 100644
index 85ea23b..0000000
--- a/winboll/src/main/java/com/tencent/wework/SpecUtil.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.tencent.wework;
-
-//import java.lang.management.ManagementFactory;
-//import java.lang.management.RuntimeMXBean;
-
-/**
- * @warning: 1. 不要修改成员变量名,native方法内有反射调用
- * 2. 调用本地方法需保持包结构,本工具需放在包com.tencent.wework内
- * 3. 不允许继承,类名和函数名均不可修改,会影响本地方法的引用,详见:javah生成本地方法头文件
- * 4. 使用其他工具打印的日志将无法被查询,如需使用SLF4j风格的日志或性能更好的日志框架,
- * 请自行封装SpecUtil.SpecLog或SpecUtil.SpecLogNative方法
- *
- * @usage: 1. 获取SDK的版本号
- * 2. 打印三个级别的日志
- * 3. 开启调试模式
- */
-public final class SpecUtil {
-
- /**
- * @description SDK版本号
- * @usage 可用于校对不同SDK版本,或后续针对不同的SDK版本添加业务逻辑
- */
- private static final String SDK_VERSION = "1.4.0";
-
- public static String GetSDKVersion() {
- return SDK_VERSION;
- }
-
- /**
- * @description 正确的包名,SDK必须存放在"com.tencent.wework"下,否则会影响本地方法的调用
- */
- private static final String EXPECTED_PACKAGE_NAME = "com.tencent.wework";
-
- public static String GetExpectedPackageName() {
- return EXPECTED_PACKAGE_NAME;
- }
-
- private static final String LINE_SEPERATOR = System.getProperty("line.separator");
-
- public static void WWSpecLogInfo(String... args) {
- SpecLog('I', args);
- }
-
- public static void WWSpecLogError(String... args) {
- SpecLog('E', args);
- }
-
- public static void WWSpecLogDebug(String... args) {
- SpecLog('D', args);
- }
-
- public static void WWSpecLogInfoWithReqId(String reqId, String... args) {
- SpecLogWithReqId(reqId, 'I', args);
- }
-
- public static void WWSpecLogErrorWithReqId(String reqId, String... args) {
- SpecLogWithReqId(reqId, 'E', args);
- }
-
- public static void WWSpecLogDebugWithReqId(String reqId, String... args) {
- SpecLogWithReqId(reqId, 'D', args);
- }
-
- /**
- * @usage 打印标准日志
- * @note 只有使用SpecLog和SpecLogNative函数打印的日志能被调试平台查询,其他框架的日志仅能本地查看
- * @param logLevel 日志级别,使用char传递,目前支持I——INFO、E——ERROR、D——DEBUG
- * @param args 自定义参数
- */
- public static void SpecLog(char logLevel, String... args) {
- StackTraceElement element = Thread.currentThread().getStackTrace()[3];
- SpecLogNative(
- logLevel,
- element.getFileName(),
- element.getLineNumber(),
- String.join(",", args).replace(LINE_SEPERATOR, " ")
- );
- }
-
- /**
- * @usage 打印标准日志
- * @note 只有使用SpecLog和SpecLogNative函数打印的日志能被调试平台查询,其他框架的日志仅能本地查看
- * @param reqid 请求id
- * @param logLevel 日志级别,使用char传递,目前支持I——INFO、E——ERROR、D——DEBUG
- * @param args 自定义参数
- */
- public static void SpecLogWithReqId(String reqId, char logLevel, String... args) {
- StackTraceElement element = Thread.currentThread().getStackTrace()[3];
- SpecLogNativeWithReqId(
- reqId,
- logLevel,
- element.getFileName(),
- element.getLineNumber(),
- String.join(",", args).replace(LINE_SEPERATOR, " ")
- );
- }
-
- /**
- * @usage 打印标准日志
- * @note 只有使用SpecLog和SpecLogNative函数打印的日志能被调试平台查询,其他框架的日志仅能本地查看
- * 如需SLF4J风格的接口或对日志性能有进一步需求,开发者可以自行封装该函数
- * @param logLevel 日志级别,使用char传递,目前支持I——INFO、E——ERROR、D——DEBUG
- * @param fileName 文件名(类名)
- * @param lineNumber 行号
- * @param argsString 自定义参数
- */
- public static native void SpecLogNative(char logLevel, String fileName, int lineNumber, String argsString);
-
- /**
- * @usage 打印标准日志
- * @note 只有使用SpecLog和SpecLogNative函数打印的日志能被调试平台查询,其他框架的日志仅能本地查看
- * 如需SLF4J风格的接口或对日志性能有进一步需求,开发者可以自行封装该函数
- * @param reqid 请求id
- * @param logLevel 日志级别,使用char传递,目前支持I——INFO、E——ERROR、D——DEBUG
- * @param fileName 文件名(类名)
- * @param lineNumber 行号
- * @param argsString 自定义参数
- */
- public static native void SpecLogNativeWithReqId(String reqId, char logLevel, String fileName, int lineNumber, String argsString);
-
-
-
- /**
- * @usage 开启调试模式,进程级别开关
- * @param debugToken 调试凭证,在管理端获取
- * @param accessToken 应用access token
- * @return 是否开启成功
- */
- public static boolean SpecOpenDebugMode(String debugToken, String accessToken) {
- return SpecOpenDebugModeNative(debugToken, accessToken);
- }
-
- private static native boolean SpecOpenDebugModeNative(String debugToken, String accessToken);
-
- /**
- * @usage 生成notify id。用户可调用本接口生成notify id,也可完全自定义生成
- * @return 新的notify id,支持纳秒级隔离,内部异常时会输出日志并返回空串
- * @note 1. 用户可先生成notify id,将其与回调数据关联存储后,再使用该notify id通知应用,
- * 从而保证回调数据被请求时已存储完毕
- */
- public static String GenerateNotifyId() {
- return GenerateNotifyIdNative();
- }
-
- private static native String GenerateNotifyIdNative();
-
- static {
- // 检查包名
- String packageName = SpecUtil.class.getPackage().getName();
- if (!EXPECTED_PACKAGE_NAME.equals(packageName)) {
- // 静态代码块内还无法调用native日志函数,这里的日志在管理系统无法查询
- System.out.println("SpecUtil class must be in package com.tencent.wework");
- System.exit(1);
- }
-
- // 加载so库
- try {
- System.loadLibrary("WeWorkSpecSDK");
- } catch (UnsatisfiedLinkError e) {
- System.out.println("libWeWorkSpecSDK.so not found in java.library.path");
- e.printStackTrace();
- System.exit(1);
- } catch (Exception e) {
- System.out.println("unexpected exception: " + e.getMessage());
- e.printStackTrace();
- System.exit(1);
- }
-
- SpecUtil.WWSpecLogInfo("SDK init done", "packageName=" + packageName, "SDK_VERSION=" + SDK_VERSION);
- }
-}
diff --git a/winboll/src/main/res/layout/activity_about.xml b/winboll/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..b38ba39
--- /dev/null
+++ b/winboll/src/main/res/layout/activity_about.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
diff --git a/winboll/src/main/res/layout/activity_main.xml b/winboll/src/main/res/layout/activity_main.xml
index 3ea6554..60d6fd3 100644
--- a/winboll/src/main/res/layout/activity_main.xml
+++ b/winboll/src/main/res/layout/activity_main.xml
@@ -6,14 +6,6 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
-
-
diff --git a/winboll/src/main/res/layout/activity_new2.xml b/winboll/src/main/res/layout/activity_new2.xml
index 697e613..8d9b4e5 100644
--- a/winboll/src/main/res/layout/activity_new2.xml
+++ b/winboll/src/main/res/layout/activity_new2.xml
@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
diff --git a/winboll/src/main/res/layout/activity_termux_env_test.xml b/winboll/src/main/res/layout/activity_termux_env_test.xml
new file mode 100644
index 0000000..ff442a5
--- /dev/null
+++ b/winboll/src/main/res/layout/activity_termux_env_test.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/winboll/src/main/res/menu/toolbar_main.xml b/winboll/src/main/res/menu/toolbar_main.xml
index 9054e7f..bda3b26 100644
--- a/winboll/src/main/res/menu/toolbar_main.xml
+++ b/winboll/src/main/res/menu/toolbar_main.xml
@@ -8,6 +8,6 @@
android:id="@+id/item_settings"
android:title="Settings"/>
+ android:id="@+id/item_about"
+ android:title="About"/>
diff --git a/winboll/src/main/res/menu/toolbar_termux.xml b/winboll/src/main/res/menu/toolbar_termux.xml
new file mode 100644
index 0000000..28e17a6
--- /dev/null
+++ b/winboll/src/main/res/menu/toolbar_termux.xml
@@ -0,0 +1,9 @@
+
+
diff --git a/winboll/src/main/res/values/strings.xml b/winboll/src/main/res/values/strings.xml
index c967735..daf6947 100644
--- a/winboll/src/main/res/values/strings.xml
+++ b/winboll/src/main/res/values/strings.xml
@@ -1,5 +1,6 @@
WinBoLL
+ WinBoLL 网站浏览器。
筋斗云
金抖云
WinBoLL
diff --git a/winboll/src/main/res/xml/network_security_config.xml b/winboll/src/main/res/xml/network_security_config.xml
index e0ea145..84e403f 100644
--- a/winboll/src/main/res/xml/network_security_config.xml
+++ b/winboll/src/main/res/xml/network_security_config.xml
@@ -11,5 +11,11 @@
+
+
+ 127.0.0.1
+ localhost
+
+