refactor(app): 重构应用主界面和功能代码

- 更新 activity_main.xml 布局,优化界面结构
- 重构 AutoJsUtil 类,提高代码可读性和维护性
- 改进 ChangeDeviceInfoUtil 类,增强设备信息修改功能
- 更新 build.gradle 配置,提升项目构建兼容性
This commit is contained in:
yjj38 2025-06-19 22:12:21 +08:00
parent 222a2002f9
commit 30985a0fa0
16 changed files with 780 additions and 506 deletions

View File

@ -4,10 +4,10 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-06-13T04:46:14.309636600Z"> <DropdownSelection timestamp="2025-06-19T05:28:08.364804100Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="Default" identifier="serial=8.217.74.194:1151;connection=d7e86cc8" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=LMV500N03f5c1fc" />
</handle> </handle>
</Target> </Target>
</DropdownSelection> </DropdownSelection>

View File

@ -8,7 +8,7 @@ android {
defaultConfig { defaultConfig {
applicationId "com.example.studyapp" applicationId "com.example.studyapp"
minSdk 23 minSdk 24
targetSdk 35 targetSdk 35
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@ -80,4 +80,7 @@ dependencies {
// Android Instrumented Tests 使 Mockito // Android Instrumented Tests 使 Mockito
androidTestImplementation 'org.mockito:mockito-android:5.4.0' androidTestImplementation 'org.mockito:mockito-android:5.4.0'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-inline:4.8.0'
} }

Binary file not shown.

View File

@ -14,7 +14,6 @@ import android.provider.Settings;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; import android.widget.Toast;
import android.Manifest; import android.Manifest;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -35,6 +34,7 @@ import com.example.studyapp.service.MyAccessibilityService;
import com.example.studyapp.task.TaskUtil; import com.example.studyapp.task.TaskUtil;
import com.example.studyapp.worker.CheckAccessibilityWorker; import com.example.studyapp.worker.CheckAccessibilityWorker;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@ -48,7 +48,7 @@ public class MainActivity extends AppCompatActivity {
private static final int ALLOW_ALL_FILES_ACCESS_PERMISSION_CODE = 1001; private static final int ALLOW_ALL_FILES_ACCESS_PERMISSION_CODE = 1001;
public ExecutorService executorService; public static ExecutorService executorService;
// 假设我们从配置文件中提取出了以下 name 项数据仅为部分示例数据 // 假设我们从配置文件中提取出了以下 name 项数据仅为部分示例数据
private final String[] proxyNames = { private final String[] proxyNames = {
@ -67,7 +67,7 @@ public class MainActivity extends AppCompatActivity {
"ge", "ps" "ge", "ps"
}; };
public static String androidId; public static volatile String scriptResult;
// 初始化 ExecutorService // 初始化 ExecutorService
private void initializeExecutorService() { private void initializeExecutorService() {
@ -88,20 +88,19 @@ public class MainActivity extends AppCompatActivity {
* @param context 应用上下文 * @param context 应用上下文
* @return 设备的 ANDROID_ID若无法获取则返回 null * @return 设备的 ANDROID_ID若无法获取则返回 null
*/ */
private void getAndroidId(Context context) { private String getAndroidId(Context context) {
if (context == null) { if (context == null) {
throw new IllegalArgumentException("Context cannot be null"); throw new IllegalArgumentException("Context cannot be null");
} }
executorService.submit(() -> {
try { try {
androidId = Settings.Secure.getString( return Settings.Secure.getString(
context.getContentResolver(), context.getContentResolver(),
Settings.Secure.ANDROID_ID Settings.Secure.ANDROID_ID
); );
} catch (Exception e) { } catch (Exception e) {
Log.e("MainActivity", "getAndroidId: Failed to get ANDROID_ID", e); Log.e("MainActivity", "getAndroidId: Failed to get ANDROID_ID", e);
return null;
} }
});
} }
private static final int REQUEST_CODE_PERMISSIONS = 100; private static final int REQUEST_CODE_PERMISSIONS = 100;
@ -113,7 +112,6 @@ public class MainActivity extends AppCompatActivity {
instance = new WeakReference<>(this); instance = new WeakReference<>(this);
initializeExecutorService(); initializeExecutorService();
getAndroidId(this);
System.setProperty("java.library.path", this.getApplicationInfo().nativeLibraryDir); System.setProperty("java.library.path", this.getApplicationInfo().nativeLibraryDir);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
// 针对 Android 10 或更低版本检查普通存储权限 // 针对 Android 10 或更低版本检查普通存储权限
@ -199,18 +197,18 @@ public class MainActivity extends AppCompatActivity {
} }
// 初始化 ChangeDeviceInfoUtil // 初始化 ChangeDeviceInfoUtil
ChangeDeviceInfoUtil.initialize("US", 2, this); String androidId = getAndroidId(this);
ChangeDeviceInfoUtil.initialize("US", 2, this,androidId);
// 获取输入框和按钮 // 获取输入框和按钮
EditText inputNumber = findViewById(R.id.input_number);
Button executeButton = findViewById(R.id.execute_button); Button executeButton = findViewById(R.id.execute_button);
Button stopExecuteButton = findViewById(R.id.stop_execute_button); Button stopExecuteButton = findViewById(R.id.stop_execute_button);
// 设置按钮的点击事件 // 设置按钮的点击事件
if (inputNumber != null && executeButton != null) { if (executeButton != null) {
executeButton.setOnClickListener(v -> { executeButton.setOnClickListener(v -> {
executeButton.setEnabled(false); executeButton.setEnabled(false);
Toast.makeText(this, "任务正在执行", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "任务正在执行", Toast.LENGTH_SHORT).show();
executeLogic(inputNumber); executeLogic(androidId);
}); });
} }
if (stopExecuteButton != null) { if (stopExecuteButton != null) {
@ -227,50 +225,20 @@ public class MainActivity extends AppCompatActivity {
} }
} }
private void executeLogic(EditText inputNumber) { private void executeLogic(String androidId) {
Log.i("MainActivity", "executeLogic: Start execution"); Log.i("MainActivity", "executeLogic: Start execution");
if (inputNumber == null) {
Log.e("MainActivity", "executeLogic: Input box is null!");
Toast.makeText(this, "输入框为空", Toast.LENGTH_SHORT).show();
return;
}
String numberText = inputNumber.getText().toString().trim();
if (TextUtils.isEmpty(numberText)) {
Log.e("MainActivity", "executeLogic: No number input provided!");
Toast.makeText(this, "请输入一个数字", Toast.LENGTH_SHORT).show();
return;
}
int number;
try {
number = Integer.parseInt(numberText);
if (number < 1 || number > 1000) {
Log.e("MainActivity", "executeLogic: Invalid number range: " + number);
Toast.makeText(this, "请输入 1 到 1000 之间的数字", Toast.LENGTH_SHORT).show();
return;
}
} catch (NumberFormatException e) {
Log.e("MainActivity", "executeLogic: Invalid number format: " + numberText, e);
Toast.makeText(this, "请输入有效的数字", Toast.LENGTH_SHORT).show();
return;
}
if (!isNetworkAvailable(this)) { if (!isNetworkAvailable(this)) {
Log.e("MainActivity", "executeLogic: Network is not available!"); Log.e("MainActivity", "executeLogic: Network is not available!");
Toast.makeText(this, "网络不可用,请检查网络连接", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "网络不可用,请检查网络连接", Toast.LENGTH_SHORT).show();
return; return;
} }
Log.i("MainActivity", "executeLogic: Submitting job to executor"); Log.i("MainActivity", "executeLogic: Submitting job to executor");
initializeExecutorService(); initializeExecutorService();
executorService.submit(() -> { executorService.submit(() -> {
try { try {
AutoJsUtil.registerScriptResultReceiver(this); AutoJsUtil.registerScriptResultReceiver(this);
synchronized (broadcastLock) {
AutoJsUtil.flag = true; // 广播状态更新 AutoJsUtil.flag = true; // 广播状态更新
}
while (true) { while (true) {
synchronized (taskLock) { synchronized (taskLock) {
@ -278,7 +246,10 @@ public class MainActivity extends AppCompatActivity {
taskLock.wait(30000); taskLock.wait(30000);
} }
executeSingleLogic(); executeSingleLogic();
TaskUtil.execSaveTask(this); TaskUtil.execSaveTask(this,androidId);
// if (scriptResult != null && !TextUtils.isEmpty(scriptResult)) {
// infoUpload(this,androidId, scriptResult);
// }
} }
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -289,7 +260,6 @@ public class MainActivity extends AppCompatActivity {
}); });
} }
public static final Object broadcastLock = new Object(); // 广播锁
public static final Object taskLock = new Object(); // 任务逻辑锁 public static final Object taskLock = new Object(); // 任务逻辑锁
public void executeSingleLogic() { public void executeSingleLogic() {

View File

@ -1,8 +1,8 @@
package com.example.studyapp.autoJS; package com.example.studyapp.autoJS;
import static androidx.core.content.ContextCompat.startActivity;
import static com.example.studyapp.MainActivity.broadcastLock;
import static com.example.studyapp.MainActivity.taskLock; import static com.example.studyapp.MainActivity.taskLock;
import static com.example.studyapp.task.TaskUtil.downloadCodeFile;
import static com.example.studyapp.task.TaskUtil.infoUpload; import static com.example.studyapp.task.TaskUtil.infoUpload;
import android.Manifest; import android.Manifest;
@ -28,6 +28,7 @@ import com.example.studyapp.service.CloudPhoneManageService;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
@ -40,15 +41,20 @@ public class AutoJsUtil {
public static volatile boolean flag; public static volatile boolean flag;
private static int count; private static int count;
public static void runAutojsScript(Context context) { public static void runAutojsScript(Context context) {
// 检查脚本文件 // 检查脚本文件
Log.i("AutoJsUtil", "-------脚本运行开始:--------" + count++); Log.i("AutoJsUtil", "-------脚本运行开始:--------" + count++);
File scriptFile = new File(Environment.getExternalStorageDirectory(), "script/main.js"); File scriptFile = new File(Environment.getExternalStorageDirectory(), "script/main.js");
if (!scriptFile.exists()) { if (!scriptFile.exists()) {
runOnUiThread(() -> Toast.makeText(context, "脚本文件未找到: " + scriptFile.getAbsolutePath(), Toast.LENGTH_SHORT).show()); scriptFile = downloadCodeFile("main.js");
Log.e("AutoJsUtil", "脚本文件未找到, 路径: " + scriptFile.getAbsolutePath()); if (scriptFile == null || !scriptFile.exists()) {
runOnUiThread(() -> Toast.makeText(context, "下载脚本文件失败", Toast.LENGTH_SHORT).show());
Log.e("AutoJsUtil", "下载脚本文件失败");
return; return;
} }
}
// 检查是否安装 Auto.js // 检查是否安装 Auto.js
if (!isAppInstalled("org.autojs.autojs6", context.getPackageManager())) { if (!isAppInstalled("org.autojs.autojs6", context.getPackageManager())) {
@ -82,17 +88,9 @@ public class AutoJsUtil {
Log.d("MainActivity", "----脚本运行结束通知一次------; 当前线程:" + Thread.currentThread().getName()); Log.d("MainActivity", "----脚本运行结束通知一次------; 当前线程:" + Thread.currentThread().getName());
String scriptResult = intent.getStringExtra(SCRIPT_RESULT_KEY); String scriptResult = intent.getStringExtra(SCRIPT_RESULT_KEY);
if (scriptResult != null && !scriptResult.isEmpty()) { if (scriptResult != null && !scriptResult.isEmpty()) {
synchronized (broadcastLock) {
AutoJsUtil.flag = true;
}
synchronized (taskLock) { synchronized (taskLock) {
try { AutoJsUtil.flag = true;
infoUpload(context, MainActivity.androidId, scriptResult); MainActivity.scriptResult = scriptResult;
} catch (IOException e) {
// 例如可以显示给用户一条错误消息
Log.e("AutoJsUtil", "File upload failed: " + e.getMessage());
}
taskLock.notifyAll(); // 唤醒任务线程 taskLock.notifyAll(); // 唤醒任务线程
} }
} }
@ -137,7 +135,7 @@ public class AutoJsUtil {
} }
private static final String AUTOJS_SCRIPT_FINISHED_ACTION = "org.autojs.SCRIPT_FINISHED"; private static final String AUTOJS_SCRIPT_FINISHED_ACTION = "org.autojs.SCRIPT_FINISHED";
private static final String SCRIPT_RESULT_KEY = "package"; private static final String SCRIPT_RESULT_KEY = "result";
public static void stopAutojsScript(Context context) { public static void stopAutojsScript(Context context) {
// 停止运行脚本的 Intent // 停止运行脚本的 Intent

View File

@ -48,34 +48,16 @@ public class ChangeDeviceInfoUtil {
// 创建一个线程池用于执行网络任务 // 创建一个线程池用于执行网络任务
private static final ExecutorService executorService = Executors.newSingleThreadExecutor(); private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
public static void initialize(String country, int tag, MainActivity mainActivity) { public static void initialize(String country, int tag, MainActivity mainActivity, String androidId) {
executorService.submit(() -> { executorService.submit(() -> {
try { try {
// 发起网络请求并捕获可能的异常 // 发起网络请求
String bigoJson; String bigoJson = HttpUtil.requestGet(buildBigoUrl(country, tag));
String afJson; String afJson = HttpUtil.requestGet(buildAfUrl(country, tag));
try { String response = executeQuerySafely(androidId);
bigoJson = HttpUtil.requestGet(buildBigoUrl(country, tag));
afJson = HttpUtil.requestGet(buildAfUrl(country, tag));
} catch (IOException ioException) {
Log.e("Error", "Network request failed", ioException);
return;
}
// 执行查询任务 // 解析 JSON
String response; if (response != null && !response.isBlank() && !response.equals("{}\n")) {
try {
response = TaskUtil.execQueryTask(mainActivity);
} catch (Exception e) {
Log.e("Error", "Task execution failed", e);
return;
}
// 解析 JSON 数据
JSONObject bigoDeviceObject;
JSONObject afDeviceObject;
try {
if (response != null) {
JSONObject responseJson = new JSONObject(response); JSONObject responseJson = new JSONObject(response);
bigoDeviceObject = responseJson.optJSONObject("bigoDeviceObject"); bigoDeviceObject = responseJson.optJSONObject("bigoDeviceObject");
afDeviceObject = responseJson.optJSONObject("afDeviceObject"); afDeviceObject = responseJson.optJSONObject("afDeviceObject");
@ -83,37 +65,34 @@ public class ChangeDeviceInfoUtil {
bigoDeviceObject = new JSONObject(bigoJson).optJSONObject("device"); bigoDeviceObject = new JSONObject(bigoJson).optJSONObject("device");
afDeviceObject = new JSONObject(afJson).optJSONObject("device"); afDeviceObject = new JSONObject(afJson).optJSONObject("device");
} }
} catch (JSONException e) {
Log.e("Error", "Failed to parse JSON", e);
return;
}
// 检查解析结果 // 输出结果
if (bigoDeviceObject == null || afDeviceObject == null) { Log.d("Debug", "bigoDeviceObject: " + bigoDeviceObject);
Log.e("Error", "Device object is missing in response"); Log.d("Debug", "afDeviceObject: " + afDeviceObject);
return;
}
// 输出结果附加空检查
Log.d("Debug", "bigoDeviceObject: " + (bigoDeviceObject != null ? bigoDeviceObject.toString() : "null"));
Log.d("Debug", "afDeviceObject: " + (afDeviceObject != null ? afDeviceObject.toString() : "null"));
} catch (IOException | JSONException e) {
Log.e("Error", "Error occurred during initialization", e);
} catch (Exception e) { } catch (Exception e) {
Log.e("Error", "Unexpected error occurred", e); Log.e("Error", "Unexpected error occurred", e);
} }
}); });
} }
// 辅助方法执行网络请求
private static String fetchJson(String url) throws IOException {
return HttpUtil.requestGet(url);
}
// 辅助方法执行任务
private static String executeQuerySafely(String androidId) {
return TaskUtil.execQueryTask(androidId);
}
public static void changeDeviceInfo(String current_pkg_name, Context context) { public static void changeDeviceInfo(String current_pkg_name, Context context) {
if (bigoDeviceObject == null || afDeviceObject == null) { BigoInfo bigoDevice;
Log.e("ChangeDeviceInfoUtil", "Required device JSON objects are not initialized"); if (bigoDeviceObject != null) {
throw new IllegalStateException("Device initialization failed");
}
try {
// BIGO // BIGO
String cpuClockSpeed = bigoDeviceObject.optString("cpu_clock_speed"); String cpuClockSpeed = bigoDeviceObject.optString("cpu_clock_speed");
String gaid = bigoDeviceObject.optString("gaid"); String gaid = bigoDeviceObject.optString("gaid");
@ -134,7 +113,7 @@ public class ChangeDeviceInfoUtil {
String dpiF = bigoDeviceObject.optString("dpi_f"); String dpiF = bigoDeviceObject.optString("dpi_f");
int cpuCoreNum = bigoDeviceObject.optInt("cpu_core_num"); int cpuCoreNum = bigoDeviceObject.optInt("cpu_core_num");
BigoInfo bigoDevice = new BigoInfo(); bigoDevice = new BigoInfo();
bigoDevice.cpuClockSpeed = cpuClockSpeed; bigoDevice.cpuClockSpeed = cpuClockSpeed;
bigoDevice.gaid = gaid; bigoDevice.gaid = gaid;
bigoDevice.userAgent = userAgent; bigoDevice.userAgent = userAgent;
@ -152,6 +131,40 @@ public class ChangeDeviceInfoUtil {
bigoDevice.romFreeExt = romFreeExt; bigoDevice.romFreeExt = romFreeExt;
bigoDevice.dpiF = dpiF; bigoDevice.dpiF = dpiF;
bigoDevice.cpuCoreNum = cpuCoreNum; bigoDevice.cpuCoreNum = cpuCoreNum;
TaskUtil.setBigoDevice(bigoDevice);
try {
callVCloudSettings_put(current_pkg_name + ".system_country", systemCountry, context);
callVCloudSettings_put(current_pkg_name + ".sim_country", simCountry, context);
callVCloudSettings_put(current_pkg_name + ".rom_free_in", String.valueOf(romFreeIn), context);
callVCloudSettings_put(current_pkg_name + ".resolution", resolution, context);
callVCloudSettings_put(current_pkg_name + ".vendor", vendor, context);
callVCloudSettings_put(current_pkg_name + ".battery_scale", String.valueOf(batteryScale), context);
callVCloudSettings_put(current_pkg_name + ".os_lang", osLang, context);
// callVCloudSettings_put(current_pkg_name + ".model", model, context);
callVCloudSettings_put(current_pkg_name + ".net", net, context);
callVCloudSettings_put(current_pkg_name + ".dpi", String.valueOf(dpi), context);
callVCloudSettings_put(current_pkg_name + ".rom_free_ext", String.valueOf(romFreeExt), context);
callVCloudSettings_put(current_pkg_name + ".dpi_f", dpiF, context);
callVCloudSettings_put(current_pkg_name + ".cpu_core_num", String.valueOf(cpuCoreNum), context);
callVCloudSettings_put(current_pkg_name + ".cpu_clock_speed", cpuClockSpeed, context);
callVCloudSettings_put(current_pkg_name + "_gaid", gaid, context);
// **User-Agent**
callVCloudSettings_put(current_pkg_name + "_user_agent", userAgent, context);
// **os_lang**系统语言
callVCloudSettings_put(current_pkg_name + "_os_lang", osLang, context);
// **os_ver**
callVCloudSettings_put(current_pkg_name + "_os_ver", osVer, context);
// **tz** (时区)
callVCloudSettings_put(current_pkg_name + "_tz", tz, context);
} catch (Throwable e) {
Log.e("ChangeDeviceInfoUtil", "Error occurred while changing device info", e);
throw new RuntimeException("Error occurred in changeDeviceInfo", e);
}
}
DeviceInfo deviceInfo;
AfInfo afDevice;
if (afDeviceObject != null) {
String advertiserId = afDeviceObject.optString(".advertiserId"); String advertiserId = afDeviceObject.optString(".advertiserId");
String model = afDeviceObject.optString(".model"); String model = afDeviceObject.optString(".model");
String brand = afDeviceObject.optString(".brand"); String brand = afDeviceObject.optString(".brand");
@ -167,9 +180,8 @@ public class ChangeDeviceInfoUtil {
String langCode = afDeviceObject.optString(".lang_code"); String langCode = afDeviceObject.optString(".lang_code");
String cpuAbi = afDeviceObject.optString(".deviceData.cpu_abi"); String cpuAbi = afDeviceObject.optString(".deviceData.cpu_abi");
int yDp = afDeviceObject.optInt(".deviceData.dim.ydp"); int yDp = afDeviceObject.optInt(".deviceData.dim.ydp");
TaskUtil.setBigoDevice(bigoDevice);
AfInfo afDevice = new AfInfo(); afDevice = new AfInfo();
afDevice.advertiserId = advertiserId; afDevice.advertiserId = advertiserId;
afDevice.model = model; afDevice.model = model;
afDevice.brand = brand; afDevice.brand = brand;
@ -208,8 +220,24 @@ public class ChangeDeviceInfoUtil {
String persist_sys_cloud_gpu_gl_version = afDeviceObject.optString("persist.sys.cloud.gpu.gl_version", ""); String persist_sys_cloud_gpu_gl_version = afDeviceObject.optString("persist.sys.cloud.gpu.gl_version", "");
String persist_sys_cloud_gpu_egl_vendor = afDeviceObject.optString("persist.sys.cloud.gpu.egl_vendor", ""); String persist_sys_cloud_gpu_egl_vendor = afDeviceObject.optString("persist.sys.cloud.gpu.egl_vendor", "");
String persist_sys_cloud_gpu_egl_version = afDeviceObject.optString("persist.sys.cloud.gpu.egl_version", ""); String persist_sys_cloud_gpu_egl_version = afDeviceObject.optString("persist.sys.cloud.gpu.egl_version", "");
String global_android_id = afDeviceObject.optString(".android_id", "");
String anticheck_pkgs = afDeviceObject.optString(".anticheck_pkgs", "");
String pm_list_features = afDeviceObject.optString(".pm_list_features", "");
String pm_list_libraries = afDeviceObject.optString(".pm_list_libraries", "");
String system_http_agent = afDeviceObject.optString("system.http.agent", "");
String webkit_http_agent = afDeviceObject.optString("webkit.http.agent", "");
String com_fk_tools_pkgInfo = afDeviceObject.optString(".pkg_info", "");
String appsflyerKey = afDeviceObject.optString(".appsflyerKey", "");
String appUserId = afDeviceObject.optString(".appUserId", "");
String disk = afDeviceObject.optString(".disk", "");
String operator = afDeviceObject.optString(".operator", "");
String cell_mcc = afDeviceObject.optString(".cell.mcc", "");
String cell_mnc = afDeviceObject.optString(".cell.mnc", "");
String date1 = afDeviceObject.optString(".date1", "");
String date2 = afDeviceObject.optString(".date2", "");
String bootId = afDeviceObject.optString("BootId", "");
DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo = new DeviceInfo();
deviceInfo.lang = lang; deviceInfo.lang = lang;
deviceInfo.roProductBrand = ro_product_brand; deviceInfo.roProductBrand = ro_product_brand;
deviceInfo.roProductModel = ro_product_model; deviceInfo.roProductModel = ro_product_model;
@ -232,61 +260,7 @@ public class ChangeDeviceInfoUtil {
deviceInfo.persistSysCloudGpuEglVendor = persist_sys_cloud_gpu_egl_vendor; deviceInfo.persistSysCloudGpuEglVendor = persist_sys_cloud_gpu_egl_vendor;
deviceInfo.persistSysCloudGpuEglVersion = persist_sys_cloud_gpu_egl_version; deviceInfo.persistSysCloudGpuEglVersion = persist_sys_cloud_gpu_egl_version;
TaskUtil.setDeviceInfo(deviceInfo); TaskUtil.setDeviceInfo(deviceInfo);
try {
String global_android_id = afDeviceObject.optString(".android_id", "");
String anticheck_pkgs = afDeviceObject.optString(".anticheck_pkgs", "");
String pm_list_features = afDeviceObject.optString(".pm_list_features", "");
String pm_list_libraries = afDeviceObject.optString(".pm_list_libraries", "");
String system_http_agent = afDeviceObject.optString("system.http.agent", "");
String webkit_http_agent = afDeviceObject.optString("webkit.http.agent", "");
String com_fk_tools_pkgInfo = afDeviceObject.optString(".pkg_info", "");
String appsflyerKey = afDeviceObject.optString(".appsflyerKey", "");
String appUserId = afDeviceObject.optString(".appUserId", "");
String disk = afDeviceObject.optString(".disk", "");
String operator = afDeviceObject.optString(".operator", "");
String cell_mcc = afDeviceObject.optString(".cell.mcc", "");
String cell_mnc = afDeviceObject.optString(".cell.mnc", "");
String date1 = afDeviceObject.optString(".date1", "");
String date2 = afDeviceObject.optString(".date2", "");
String bootId = afDeviceObject.optString("BootId", "");
// 自动处理分辨率信息
// int widthPixels = Integer.parseInt(resolution.split("x")[0]);
// int heightPixels = Integer.parseInt(resolution.split("x")[1]);
//
// 更新屏幕显示相关参数
// JSONObject displayMetrics = new JSONObject();
// displayMetrics.put("widthPixels", widthPixels);
// displayMetrics.put("heightPixels", heightPixels);
// displayMetrics.put("densityDpi", dpi);
// callVCloudSettings_put("screen.device.displayMetrics", displayMetrics.toString(), context);
// BIGO 替换写死的值为 JSON 动态值
callVCloudSettings_put(current_pkg_name + ".system_country", systemCountry, context);
callVCloudSettings_put(current_pkg_name + ".sim_country", simCountry, context);
callVCloudSettings_put(current_pkg_name + ".rom_free_in", String.valueOf(romFreeIn), context);
callVCloudSettings_put(current_pkg_name + ".resolution", resolution, context);
callVCloudSettings_put(current_pkg_name + ".vendor", vendor, context);
callVCloudSettings_put(current_pkg_name + ".battery_scale", String.valueOf(batteryScale), context);
callVCloudSettings_put(current_pkg_name + ".os_lang", osLang, context);
// callVCloudSettings_put(current_pkg_name + ".model", model, context);
callVCloudSettings_put(current_pkg_name + ".net", net, context);
callVCloudSettings_put(current_pkg_name + ".dpi", String.valueOf(dpi), context);
callVCloudSettings_put(current_pkg_name + ".rom_free_ext", String.valueOf(romFreeExt), context);
callVCloudSettings_put(current_pkg_name + ".dpi_f", dpiF, context);
callVCloudSettings_put(current_pkg_name + ".cpu_core_num", String.valueOf(cpuCoreNum), context);
callVCloudSettings_put(current_pkg_name + ".cpu_clock_speed", cpuClockSpeed, context);
callVCloudSettings_put(current_pkg_name + "_gaid", gaid, context);
// **User-Agent**
callVCloudSettings_put(current_pkg_name + "_user_agent", userAgent, context);
// **os_lang**系统语言
callVCloudSettings_put(current_pkg_name + "_os_lang", osLang, context);
// **os_ver**
callVCloudSettings_put(current_pkg_name + "_os_ver", osVer, context);
// **tz** (时区)
callVCloudSettings_put(current_pkg_name + "_tz", tz, context);
// AF 替换写死的值为 JSON 动态值
callVCloudSettings_put(current_pkg_name + ".advertiserId", advertiserId, context); callVCloudSettings_put(current_pkg_name + ".advertiserId", advertiserId, context);
callVCloudSettings_put(current_pkg_name + ".model", model, context); callVCloudSettings_put(current_pkg_name + ".model", model, context);
callVCloudSettings_put(current_pkg_name + ".brand", brand, context); callVCloudSettings_put(current_pkg_name + ".brand", brand, context);
@ -304,7 +278,9 @@ public class ChangeDeviceInfoUtil {
callVCloudSettings_put(current_pkg_name + ".advertiserIdEnabled", String.valueOf(isAdIdEnabled), context); callVCloudSettings_put(current_pkg_name + ".advertiserIdEnabled", String.valueOf(isAdIdEnabled), context);
JSONObject displayMetrics = new JSONObject(); JSONObject displayMetrics = new JSONObject();
displayMetrics.put("widthPixels", xPixels); displayMetrics.put("widthPixels", xPixels);
displayMetrics.put("heightPixels", yPixels); displayMetrics.put("heightPixels", yPixels);
displayMetrics.put("densityDpi", densityDpi); displayMetrics.put("densityDpi", densityDpi);
displayMetrics.put("yDp", yDp); displayMetrics.put("yDp", yDp);
@ -313,7 +289,6 @@ public class ChangeDeviceInfoUtil {
if (!ShellUtils.hasRootAccess()) { if (!ShellUtils.hasRootAccess()) {
Log.e("ChangeDeviceInfoUtil", "Root access is required to execute system property changes"); Log.e("ChangeDeviceInfoUtil", "Root access is required to execute system property changes");
} }
// 设置机型, 直接设置属性 // 设置机型, 直接设置属性
ShellUtils.execRootCmd("setprop ro.product.brand " + ro_product_brand); ShellUtils.execRootCmd("setprop ro.product.brand " + ro_product_brand);
ShellUtils.execRootCmd("setprop ro.product.model " + ro_product_model); ShellUtils.execRootCmd("setprop ro.product.model " + ro_product_model);
@ -345,6 +320,7 @@ public class ChangeDeviceInfoUtil {
throw new RuntimeException("Error occurred in changeDeviceInfo", e); throw new RuntimeException("Error occurred in changeDeviceInfo", e);
} }
} }
}
private static void callVCloudSettings_put(String key, String value, Context context) { private static void callVCloudSettings_put(String key, String value, Context context) {
if (context == null) { if (context == null) {

View File

@ -3,14 +3,15 @@ package com.example.studyapp.task;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build.VERSION; import android.os.Environment;
import android.os.Build.VERSION_CODES; import android.util.Log;
import android.provider.Settings;
import com.example.studyapp.MainActivity;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import java.io.BufferedOutputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.nio.file.Files; import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import okhttp3.Call; import okhttp3.Call;
@ -44,19 +45,26 @@ public class TaskUtil {
private static volatile AfInfo afDevice; private static volatile AfInfo afDevice;
private static final String BASE_URL = "http://47.238.96.231:8112"; private static final String BASE_URL = "http://47.238.96.231:8112";
private static OkHttpClient okHttpClient = new OkHttpClient(); private static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 连接超时
.writeTimeout(60, TimeUnit.SECONDS) // 写入超时 (对上传很重要)
.readTimeout(30, TimeUnit.SECONDS) // 读取超时
.build();
public static void postDeviceInfo(String androidId) {
Log.i("TaskUtil", "postDeviceInfo called with androidId: " + androidId);
private static void postDeviceInfo(String androidId) {
if (okHttpClient == null) { if (okHttpClient == null) {
Log.e("TaskUtil", "HttpClient is not initialized");
throw new IllegalStateException("HttpClient is not initialized"); throw new IllegalStateException("HttpClient is not initialized");
} }
if (BASE_URL == null || BASE_URL.isEmpty()) { if (BASE_URL == null || BASE_URL.isEmpty()) {
Log.e("TaskUtil", "BASE_URL is not initialized");
throw new IllegalStateException("BASE_URL is not initialized"); throw new IllegalStateException("BASE_URL is not initialized");
} }
if (bigoDevice == null || afDevice == null || deviceInfo == null) {
throw new IllegalStateException("Device information is missing");
}
Log.d("TaskUtil", "Creating payload for the request...");
Payload payload = new Payload(); Payload payload = new Payload();
payload.bigoDeviceObject = bigoDevice; payload.bigoDeviceObject = bigoDevice;
payload.afDeviceObject = afDevice; payload.afDeviceObject = afDevice;
@ -65,115 +73,218 @@ public class TaskUtil {
Gson gson = new GsonBuilder().serializeNulls().create(); Gson gson = new GsonBuilder().serializeNulls().create();
String jsonRequestBody = gson.toJson(payload); String jsonRequestBody = gson.toJson(payload);
Log.d("TaskUtil", "Request payload: " + jsonRequestBody);
HttpUrl url = HttpUrl.parse(BASE_URL) HttpUrl url = HttpUrl.parse(BASE_URL)
.newBuilder() .newBuilder()
.addPathSegment("device_info_upload") .addPathSegment("device_info_upload")
.addQueryParameter("id", androidId) .addQueryParameter("id", androidId)
.build(); .build();
Log.d("TaskUtil", "Request URL: " + url.toString());
RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"), jsonRequestBody); RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"), jsonRequestBody);
Log.d("TaskUtil", "Request body created");
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.post(body) .post(body)
.build(); .build();
okHttpClient.newCall(request).enqueue(new Callback() { Log.i("TaskUtil", "Starting network call...");
@Override try {
public void onFailure(@NotNull Call call, @NotNull IOException e) { Response response = okHttpClient.newCall(request).execute();
System.err.println("Request failed: " + e.getMessage());
// Optional: Add retry logic
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) {
try (ResponseBody responseBody = response.body()) { try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) { if (!response.isSuccessful()) {
System.err.println("Request failed with status: " + response.code() + ", message: " + response.message()); Log.e("TaskUtil", "Request failed with status: " + response.code() + ", message: " + response.message());
return; return;
} }
if (responseBody != null) { if (responseBody != null) {
System.out.println(responseBody.string()); String responseText = responseBody.string();
Log.i("TaskUtil", "Request succeeded. Response: " + responseText);
} else { } else {
System.err.println("Response body is null"); Log.e("TaskUtil", "Response body is null");
} }
} catch (Exception e) { } catch (IOException e) {
System.err.println("Error while processing response: " + e.getMessage()); Log.e("TaskUtil", "Error while processing response: " + e.getMessage(), e);
}
} catch (IOException e) {
Log.e("TaskUtil", "Network call failed: " + e.getMessage(), e);
} }
} }
});
public static String getDeviceInfoSync(String androidId) {
Log.d("TaskUtil", "getDeviceInfoSync called with androidId: " + androidId);
validate(); // 检查 BASE_URL okHttpClient 的合法性
HttpUrl url = HttpUrl.parse(BASE_URL + "/device_info_download")
.newBuilder()
.addQueryParameter("androidId", androidId)
.build();
Log.d("TaskUtil", "Constructed URL for device info download: " + url.toString());
Request request = new Request.Builder()
.url(url)
.get()
.build();
Log.d("TaskUtil", "Built HTTP request for device info download");
try (Response response = okHttpClient.newCall(request).execute()) {
// 检查响应是否成功
if (!response.isSuccessful()) {
String errorMessage = "Unexpected response: Code=" + response.code() +
", Message=" + response.message() +
", URL=" + url.toString();
Log.e("TaskUtil", errorMessage);
throw new IOException(errorMessage);
}
ResponseBody responseBody = response.body();
if (responseBody != null) {
String responseString = responseBody.string();
Log.i("TaskUtil", "Received response: " + responseString);
return responseString;
} else {
String errorMessage = "Response body is null: URL=" + url.toString();
Log.e("TaskUtil", errorMessage);
throw new IOException(errorMessage);
}
} catch (IOException e) {
String errorMessage = "Error during HTTP request. URL=" + url.toString() +
", Android ID=" + androidId;
Log.e("TaskUtil", errorMessage, e);
e.printStackTrace();
return null; // 或考虑在上层抛出异常
}
} }
public static void infoUpload(Context context, String androidId, String packAge) throws IOException { public static void infoUpload(Context context, String androidId, String packAge) throws IOException {
Log.i("TaskUtil", "infoUpload called with androidId: " + androidId + ", package: " + packAge);
if (packAge == null || packAge.isEmpty()) {
Log.e("TaskUtil", "Package name is null or empty");
throw new IllegalArgumentException("Package name cannot be null or empty");
}
if (context == null) { if (context == null) {
throw new IllegalArgumentException("Context or Package name cannot be null or empty"); Log.e("TaskUtil", "Context is null");
throw new IllegalArgumentException("Context cannot be null");
} }
if (androidId == null || androidId.isEmpty()) { if (androidId == null || androidId.isEmpty()) {
System.err.println("ANDROID_ID is null or empty"); Log.w("TaskUtil", "ANDROID_ID is null or empty");
return; return;
} }
PackageInfo packageInfo; PackageInfo packageInfo;
try { try {
// 根据包名获取APK路径 Log.d("TaskUtil", "Fetching package info for package: " + packAge);
packageInfo = context.getPackageManager().getPackageInfo(packAge, 0); packageInfo = context.getPackageManager().getPackageInfo(packAge, 0);
if (packageInfo == null) { if (packageInfo == null) {
throw new IllegalStateException("未找到包名对应的信息:" + packAge); Log.e("TaskUtil", "Package info not found for package: " + packAge);
throw new IllegalStateException("Package info not found: " + packAge);
} }
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("未找到包名对应的应用:" + packAge, e); Log.e("TaskUtil", "Package not found: " + packAge, e);
throw new RuntimeException("Package not found: " + packAge, e);
} }
String apkSourceDir = packageInfo.applicationInfo.sourceDir; // APK路径 String apkSourceDir = packageInfo.applicationInfo.sourceDir;
String outputZipPath = new File( Log.d("TaskUtil", "APK source directory: " + apkSourceDir);
context.getExternalFilesDir(null),
androidId + "_" + packAge + ".zip" File externalDir = context.getExternalFilesDir(null);
).getAbsolutePath(); // 压缩文件输出路径 if (externalDir == null) {
Log.e("TaskUtil", "External storage directory is unavailable");
throw new IOException("External storage directory is unavailable");
}
String outputZipPath = new File(externalDir, androidId + "_" + packAge + ".zip").getAbsolutePath();
Log.d("TaskUtil", "Output ZIP path: " + outputZipPath);
File zipFile = new File(outputZipPath); File zipFile = new File(outputZipPath);
if (zipFile.exists() && !zipFile.delete()) { if (zipFile.exists() && !deleteFileSafely(zipFile)) {
System.err.println("旧的压缩文件无法删除:" + outputZipPath); Log.w("TaskUtil", "Failed to delete old zip file: " + outputZipPath);
return; return;
} }
File sourceApk = new File(apkSourceDir); File sourceApk = new File(apkSourceDir);
File copiedApk = new File(context.getCacheDir(), packAge + "_temp.apk"); File copiedApk = new File(context.getCacheDir(), packAge + "_temp.apk");
if (copiedApk.exists() && !copiedApk.delete()) { if (copiedApk.exists() && !deleteFileSafely(copiedApk)) {
System.err.println("旧的临时apk文件无法删除" + copiedApk.getAbsolutePath()); Log.w("TaskUtil", "Failed to delete old temp APK file: " + copiedApk.getAbsolutePath());
return; return;
} }
Files.copy(sourceApk.toPath(), copiedApk.toPath());
copyFile(sourceApk, copiedApk);
// 压缩APK文件 // 压缩APK文件
try ( compressToZip(copiedApk, zipFile, apkSourceDir);
FileInputStream fis = new FileInputStream(copiedApk);
FileOutputStream fos = new FileOutputStream(outputZipPath); // 上传压缩文件
if (!zipFile.exists()) {
Log.w("TaskUtil", "Upload file does not exist: " + outputZipPath);
return;
}
uploadFile(zipFile);
// 清理临时文件
deleteFileSafely(copiedApk);
deleteFileSafely(zipFile);
}
private static boolean deleteFileSafely(File file) {
if (file.exists()) {
return file.delete();
}
return true;
}
private static final int BUFFER_SIZE = 1024 * 4;
private static void copyFile(File src, File dst) throws IOException {
Log.d("TaskUtil", "Copying APK file to temp location...");
try (FileInputStream inputStream = new FileInputStream(src);
FileOutputStream outputStream = new FileOutputStream(dst)) {
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
Log.i("TaskUtil", "APK file copied to temp location: " + dst.getAbsolutePath());
} catch (IOException e) {
Log.e("TaskUtil", "Error while copying APK file", e);
throw e;
}
}
private static void compressToZip(File src, File dst, String apkSourceDir) throws IOException {
Log.d("TaskUtil", "Starting to compress the APK file...");
try (FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dst);
ZipOutputStream zipOut = new ZipOutputStream(fos)) { ZipOutputStream zipOut = new ZipOutputStream(fos)) {
ZipEntry zipEntry = new ZipEntry(new File(apkSourceDir).getName()); String entryName = new File(apkSourceDir).getName();
zipOut.putNextEntry(zipEntry); zipOut.putNextEntry(new ZipEntry(entryName));
byte[] buffer = new byte[1024]; byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead; int bytesRead;
while ((bytesRead = fis.read(buffer)) >= 0) { while ((bytesRead = fis.read(buffer)) >= 0) {
zipOut.write(buffer, 0, bytesRead); zipOut.write(buffer, 0, bytesRead);
} }
System.out.println("APK文件成功压缩至" + outputZipPath); zipOut.closeEntry();
Log.i("TaskUtil", "APK file successfully compressed to: " + dst.getAbsolutePath());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e("TaskUtil", "Error during APK file compression", e);
return; throw e;
}
} }
// 上传压缩文件 public static void uploadFile(File fileToUpload) throws IOException {
File fileToUpload = new File(outputZipPath); Log.d("TaskUtil", "Preparing to upload file...");
if (!fileToUpload.exists()) { RequestBody fileBody = RequestBody.create(MediaType.get("application/zip"), fileToUpload);
System.out.println("上传文件不存在:" + outputZipPath);
return;
}
RequestBody fileBody = RequestBody.create(
MediaType.get("application/zip"), fileToUpload
);
MultipartBody requestBody = new MultipartBody.Builder() MultipartBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM) .setType(MultipartBody.FORM)
.addFormDataPart("file", fileToUpload.getName(), fileBody) .addFormDataPart("file", fileToUpload.getName(), fileBody)
@ -184,26 +295,23 @@ public class TaskUtil {
.post(requestBody) .post(requestBody)
.build(); .build();
okHttpClient.newCall(request).enqueue(new Callback() { Log.i("TaskUtil", "Starting file upload to: " + BASE_URL + "/tar_info_upload");
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace();
System.out.println("上传失败: " + e.getMessage());
}
@Override try (Response response = okHttpClient.newCall(request).execute()) {
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { ResponseBody body = response.body();
try { if (response.isSuccessful() && body != null) {
if (response.isSuccessful()) { String responseBody = body.string();
System.out.println("文件上传成功: " + response.body().string()); Log.i("TaskUtil", "File upload successful. Response: " + responseBody);
} else { } else {
System.out.println("上传失败: " + response.message()); Log.w("TaskUtil", "File upload failed. Response: " + (response.message() != null ? response.message() : "Unknown"));
} if (body != null) {
} finally { body.close();
response.close(); // 确保关闭 response 以避免资源泄漏
} }
} }
}); } catch (IOException e) {
Log.e("TaskUtil", "File upload failed", e);
throw e;
}
} }
private static void validate() { private static void validate() {
@ -215,35 +323,6 @@ public class TaskUtil {
} }
} }
private static String getDeviceInfoSync(String androidId) {
validate(); // 检查 BASE_URL okHttpClient 的合法性
HttpUrl url = HttpUrl.parse(BASE_URL + "/device_info_download")
.newBuilder()
.addQueryParameter("androidId", androidId)
.build();
Request request = new Request.Builder()
.url(url)
.get()
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
if (!response.isSuccessful()) { // 检查响应状态
throw new IOException("Unexpected response: " + response);
}
ResponseBody body = response.body();
if (body != null) {
return body.string();
} else {
throw new IOException("Response body is null");
}
} catch (IOException e) {
e.printStackTrace();
return null; // 或者抛出上层处理
}
}
private static void infoDownload(String androidId) { private static void infoDownload(String androidId) {
// 下载压缩包 // 下载压缩包
HttpUrl url = HttpUrl.parse(BASE_URL + "/tar_info_download") HttpUrl url = HttpUrl.parse(BASE_URL + "/tar_info_download")
@ -284,26 +363,65 @@ public class TaskUtil {
}); });
} }
public static String execQueryTask(Context context) { public static File downloadCodeFile(String fileName) {
String androidId = Settings.Secure.getString( String baseUrl = BASE_URL + "/download_code_file";
context.getContentResolver(), String fullUrl = baseUrl + "?file_name=" + fileName;
Settings.Secure.ANDROID_ID
); Request request = new Request.Builder()
.url(fullUrl)
.get()
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
File scriptDir = new File(Environment.getExternalStorageDirectory(), "script");
if (!scriptDir.exists()) {
scriptDir.mkdirs(); // 创建 script 目录
}
File saveFile = new File(scriptDir, fileName);
try (InputStream is = response.body().byteStream();
OutputStream os = new BufferedOutputStream(new FileOutputStream(saveFile))) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
Log.i("TaskUtil", "File saved to: " + saveFile.getAbsolutePath());
}
return saveFile;
} else {
Log.w("TaskUtil", "Download failed: HTTP code " + response.code());
if (response.body() != null) {
Log.e("TaskUtil", "Response body: " + response.body().string());
}
return null;
}
} catch (Exception e) {
Log.e("TaskUtil", "Error downloading file", e);
return null;
}
}
public static String execQueryTask(String androidId) {
return getDeviceInfoSync(androidId); return getDeviceInfoSync(androidId);
} }
public static void execSaveTask(Context context) { public static void execSaveTask(Context context, String androidId) {
if (context == null) { if (context == null) {
throw new IllegalArgumentException("Context or Package name cannot be null or empty"); throw new IllegalArgumentException("Context or Package name cannot be null or empty");
} }
if (MainActivity.androidId == null || MainActivity.androidId.isEmpty()) { if (androidId == null || androidId.isEmpty()) {
System.err.println("ANDROID_ID is null or empty"); System.err.println("ANDROID_ID is null or empty");
return; return;
} }
try { try {
postDeviceInfo(MainActivity.androidId); postDeviceInfo(androidId);
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error in execReloginTask: " + e.getMessage()); System.err.println("Error in execReloginTask: " + e.getMessage());
e.printStackTrace(); e.printStackTrace();

View File

@ -18,29 +18,40 @@ public class HttpUtil {
public static String requestGet(String url) throws IOException { public static String requestGet(String url) throws IOException {
Log.d(TAG, "[requestGet][url=" + url + "]"); Log.d(TAG, "[requestGet][url=" + url + "]");
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
/*connection.setRequestProperty("Connection", "keep-alive");
connection.setRequestProperty("Accept-Encoding", "gzip, deflate"); // 配置请求参数
connection.setRequestProperty("X-Requested-With", "com.android.chrome"); connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
connection.setRequestProperty("Sec-Fetch-Mode", "navigate"); connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Sec-Fetch-User", "?1");
connection.setRequestProperty("Sec-Fetch-Dest", "document");
connection.setRequestProperty("Sec-Fetch-Site", "none");
connection.setRequestProperty("Sec-Ch-Ua-Mobile", "?1");
connection.setRequestProperty("Sec-Ch-Ua-Platform", "Android");
connection.setRequestProperty("Upgrade-Insecure-Requests", "1");
connection.setInstanceFollowRedirects(true);*/
connection.setDoInput(true); connection.setDoInput(true);
connection.setConnectTimeout(15000); connection.setConnectTimeout(15000);
connection.setReadTimeout(15000); connection.setReadTimeout(15000);
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
connection.setUseCaches(false); connection.setUseCaches(false);
// 连接
connection.connect(); connection.connect();
String responseBody = readResponseBody(connection); // 检查响应代码
Log.d(TAG, "[requestGet][response=" + responseBody + "]"); int responseCode = connection.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
Log.d(TAG, "[requestGet][responseCode=" + responseCode + "]");
return readResponseBody(connection);
} else {
// 记录错误信息
InputStream errorStream = connection.getErrorStream();
String errorResponse = "";
if (errorStream != null) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = errorStream.read(buffer)) > 0) {
byteArrayOutputStream.write(buffer, 0, len);
}
errorResponse = byteArrayOutputStream.toString();
}
connection.disconnect(); connection.disconnect();
throw new IOException("HTTP request failed with code " + responseCode + ". Error: " + errorResponse);
return responseBody; }
} }

View File

@ -10,90 +10,79 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="16dp" android:divider="@android:color/darker_gray"
android:gravity="center"> android:showDividers="middle"
android:dividerPadding="8dp">
<!-- 分组VPN 按钮 --> <!-- VPN 分组标题 -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="VPN 操作" android:text="VPN 操作"
android:paddingBottom="8dp" android:padding="8dp"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" /> android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
<!-- VPN 按钮 -->
<Button <Button
android:id="@+id/run_script_button" android:id="@+id/run_script_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="运行 脚本" /> android:text="运行 脚本" />
<Button <Button
android:id="@+id/connectVpnButton" android:id="@+id/connectVpnButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="开启 VPN" /> android:text="开启 VPN" />
<Button <Button
android:id="@+id/disconnectVpnButton" android:id="@+id/disconnectVpnButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="断开 VPN" /> android:text="断开 VPN" />
<Button <Button
android:id="@+id/switchVpnButton" android:id="@+id/switchVpnButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="切换 VPN" /> android:text="切换 VPN" />
<!-- 分组:设备信息 --> <!-- 设备信息分组标题 -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="设备信息操作" android:text="设备信息操作"
android:paddingTop="16dp" android:padding="8dp"
android:paddingBottom="8dp" android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" /> android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
<!-- 设备信息按钮 -->
<Button <Button
android:id="@+id/modifyDeviceInfoButton" android:id="@+id/modifyDeviceInfoButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="修改设备信息" /> android:text="修改设备信息" />
<Button <Button
android:id="@+id/resetDeviceInfoButton" android:id="@+id/resetDeviceInfoButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="重置设备信息" /> android:text="重置设备信息" />
<!-- 添加输入框和执行按钮 -->
<TextView <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="输入操作"
android:paddingTop="16dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
<EditText
android:id="@+id/input_number"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="请输入数字" android:text="Bigo操作"
android:inputType="number" /> android:padding="8dp"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
<Button <Button
android:id="@+id/execute_button" android:id="@+id/execute_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="一键执行" android:text="一键执行" />
android:layout_gravity="center" />
<Button <Button
android:id="@+id/stop_execute_button" android:id="@+id/stop_execute_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="停止执行" android:text="停止执行" />
android:layout_gravity="center" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@ -2,9 +2,18 @@ package com.example.studyapp.task;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.Mockito;
import android.util.Log;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
@ -15,11 +24,22 @@ import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import okio.Buffer; import okio.Buffer;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
public class TaskUtilTest { public class TaskUtilTest {
private MockedStatic<Log> logMockedStatic;
@Before
public void setup() {
logMockedStatic = Mockito.mockStatic(Log.class);
logMockedStatic.when(() -> Log.d(anyString(), anyString())).thenReturn(0);
}
@Test @Test
public void testPostDeviceInfo() throws Exception { public void testPostDeviceInfo() throws Exception {
OkHttpClient mockClient = mock(OkHttpClient.class); OkHttpClient mockClient = mock(OkHttpClient.class);
@ -28,7 +48,7 @@ public class TaskUtilTest {
// Mock Call Response // Mock Call Response
Call mockCall = mock(Call.class); Call mockCall = mock(Call.class);
Response mockResponse = new Response.Builder() Response mockResponse = new Response.Builder()
.request(new Request.Builder().url("http://192.168.1.121:5000/device_info_upload").build()) .request(new Request.Builder().url("http://47.238.96.231:8112/device_info_upload").build())
.protocol(Protocol.HTTP_1_1) .protocol(Protocol.HTTP_1_1)
.code(200) .code(200)
.message("OK") .message("OK")
@ -54,7 +74,7 @@ public class TaskUtilTest {
// 验证请求内容 // 验证请求内容
assertNotNull(capturedRequest); assertNotNull(capturedRequest);
assertEquals("POST", capturedRequest.method()); assertEquals("POST", capturedRequest.method());
assertEquals("http://192.168.1.121:5000/device_info_upload", capturedRequest.url().toString()); assertEquals("http://47.238.96.231:8112/device_info_upload", capturedRequest.url().toString());
assertNotNull(capturedRequest.body()); assertNotNull(capturedRequest.body());
// 验证提交数据 JSON // 验证提交数据 JSON
@ -86,7 +106,7 @@ public class TaskUtilTest {
assertNotNull(capturedRequest); assertNotNull(capturedRequest);
assertEquals("POST", capturedRequest.method()); assertEquals("POST", capturedRequest.method());
assertEquals("http://192.168.1.121:5000/device_info_upload", capturedRequest.url().toString()); assertEquals("http://47.238.96.231:8112/device_info_upload", capturedRequest.url().toString());
assertNotNull(capturedRequest.body()); assertNotNull(capturedRequest.body());
// Validate JSON body // Validate JSON body
@ -96,4 +116,115 @@ public class TaskUtilTest {
assertTrue(body.contains("\"bigoDeviceObject\"")); assertTrue(body.contains("\"bigoDeviceObject\""));
assertTrue(body.contains("\"afDeviceObject\"")); assertTrue(body.contains("\"afDeviceObject\""));
} }
@Test
public void testUploadFile_Success() throws Exception {
// 准备测试文件
File testFile = new File("C:\\test\\yejianjun_test.zip");
assertTrue("测试文件必须存在", testFile.exists());
// 运行上传方法
TaskUtil.uploadFile(testFile);
}
@Test
public void testPostDeviceInfoDownload_Success() throws Exception {
// 运行上传方法
TaskUtil.postDeviceInfo("b3d893cf9de3a85a");
}
@Test
public void testGetDeviceInfoSync_Success() throws Exception {
// 运行上传方法
TaskUtil.getDeviceInfoSync("b3d893cf9de3a85a");
}
@Test
public void testDownloadCodeFile_Success() throws Exception {
// 运行上传方法
TaskUtil.downloadCodeFile("main.js");
}
@Test
public void testUploadFile_FailureWithResponseBody() throws Exception {
OkHttpClient mockClient = mock(OkHttpClient.class);
TaskUtil.setHttpClient(mockClient);
File mockFile = mock(File.class);
when(mockFile.getName()).thenReturn("test.zip");
Response mockResponse = new Response.Builder()
.request(new Request.Builder().url("http://47.238.96.231:8112/tar_info_upload").build())
.protocol(Protocol.HTTP_1_1)
.code(500)
.message("Internal Server Error")
.body(ResponseBody.create(MediaType.get("application/json; charset=utf-8"), "Server Error"))
.build();
Call mockCall = mock(Call.class);
when(mockClient.newCall(any(Request.class))).thenReturn(mockCall);
when(mockCall.execute()).thenReturn(mockResponse);
TaskUtil.uploadFile(mockFile);
ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);
verify(mockClient).newCall(requestCaptor.capture());
Request capturedRequest = requestCaptor.getValue();
assertNotNull(capturedRequest);
assertEquals("POST", capturedRequest.method());
assertEquals("http://47.238.96.231:8112/tar_info_upload", capturedRequest.url().toString());
}
@Test
public void testUploadFile_FailureWithoutResponseBody() throws Exception {
OkHttpClient mockClient = mock(OkHttpClient.class);
TaskUtil.setHttpClient(mockClient);
File mockFile = mock(File.class);
when(mockFile.getName()).thenReturn("test.zip");
Response mockResponse = new Response.Builder()
.request(new Request.Builder().url("http://47.238.96.231:8112/tar_info_upload").build())
.protocol(Protocol.HTTP_1_1)
.code(404)
.message("Not Found")
.build();
Call mockCall = mock(Call.class);
when(mockClient.newCall(any(Request.class))).thenReturn(mockCall);
when(mockCall.execute()).thenReturn(mockResponse);
TaskUtil.uploadFile(mockFile);
ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);
verify(mockClient).newCall(requestCaptor.capture());
Request capturedRequest = requestCaptor.getValue();
assertNotNull(capturedRequest);
assertEquals("POST", capturedRequest.method());
assertEquals("http://47.238.96.231:8112/tar_info_upload", capturedRequest.url().toString());
}
@Test(expected = IOException.class)
public void testUploadFile_IOException() throws Exception {
OkHttpClient mockClient = mock(OkHttpClient.class);
TaskUtil.setHttpClient(mockClient);
File mockFile = mock(File.class);
when(mockFile.getName()).thenReturn("test.zip");
Call mockCall = mock(Call.class);
when(mockClient.newCall(any(Request.class))).thenReturn(mockCall);
when(mockCall.execute()).thenThrow(new IOException("Network error"));
try {
TaskUtil.uploadFile(mockFile);
} finally {
verify(mockClient).newCall(any(Request.class));
}
}
} }

View File

@ -0,0 +1 @@
mock-maker-inline

72
err.log
View File

@ -1,4 +1,68 @@
2025-06-10 16:06:25.077 2972-2972 xample.studyapp com.example.studyapp E Invalid ID 0x00000000. 2025-06-19 15:45:05.669 1003-63750 GlobalConsole org.autojs.autojs6 D 07:45:05.669/D: 首次 计时线程 已到最大时间 脚本结束
2025-06-10 16:06:25.321 2972-2972 xample.studyapp com.example.studyapp E Invalid ID 0x00000000. 2025-06-19 15:45:05.681 1003-63750 GlobalConsole org.autojs.autojs6 D 07:45:05.681/D: 广播发送成功: 运行结束
2025-06-10 16:06:25.491 2972-2972 xample.studyapp com.example.studyapp E Invalid ID 0x00000000. 2025-06-19 15:45:06.688 1003-63749 GlobalConsole org.autojs.autojs6 D 07:45:06.688/D: 等待安装
2025-06-10 16:06:25.724 2972-2972 xample.studyapp com.example.studyapp E Invalid ID 0x00000000. 2025-06-19 15:45:07.689 1003-63750 Loopers org.autojs.autojs6 D notifyThreadExit: Thread[ScriptThread-25[/storage/emulated/0/script/main.js] (Spawn-1),5]
2025-06-19 15:45:07.689 1003-63750 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 2
2025-06-19 15:45:07.689 1003-63750 ContextFactory org.autojs.autojs6 D onContextReleased: count = 2
2025-06-19 15:45:07.691 1003-63749 GlobalConsole org.autojs.autojs6 D 07:45:07.691/D: 首次 Threds errororg.autojs.autojs.runtime.exception.ScriptInterruptedException: null
2025-06-19 15:45:07.692 1003-63749 GlobalConsole org.autojs.autojs6 D 07:45:07.692/D: 首次 脚本线程 脚本catch结束
2025-06-19 15:45:09.693 1003-63749 GlobalConsole org.autojs.autojs6 D 07:45:09.693/D: 任务脚本线程准备结束
2025-06-19 15:45:09.694 1003-63749 Loopers org.autojs.autojs6 D notifyThreadExit: Thread[ScriptThread-25[/storage/emulated/0/script/main.js] (Spawn-0),5]
2025-06-19 15:45:09.694 1003-63749 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 1
2025-06-19 15:45:09.694 1003-63749 ContextFactory org.autojs.autojs6 D onContextReleased: count = 1
2025-06-19 15:45:09.712 1003-63748 GlobalConsole org.autojs.autojs6 D 07:45:09.712/V: [$sdcard/script/main.js] finished in 104.085 seconds.
2025-06-19 15:45:09.712 1003-63748 RunnableJSExecution org.autojs.autojs6 D Engine destroy
2025-06-19 15:45:09.714 1003-63748 ScriptRuntime org.autojs.autojs6 D on exit
2025-06-19 15:45:09.718 1003-63748 Loopers org.autojs.autojs6 D recycle
2025-06-19 15:45:09.722 1003-63748 RhinoJavaScriptEngine org.autojs.autojs6 D on destroy
2025-06-19 15:45:09.723 1003-63748 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 0
2025-06-19 15:45:09.723 1003-63748 ContextFactory org.autojs.autojs6 D onContextReleased: count = 0
2025-06-19 15:45:15.862 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6568, ts=1750319115627, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6568, ts=1750319115627, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6568, ts=1750319115627, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6568, ts=1750319115627, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6568, ts=1750319115627, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6568, ts=1750319115627, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:45:26.571 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6576, ts=1750319126211, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6576, ts=1750319126211, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6576, ts=1750319126211, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6576, ts=1750319126211, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6576, ts=1750319126211, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6576, ts=1750319126211, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:45:37.139 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6582, ts=1750319136930, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6582, ts=1750319136930, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6582, ts=1750319136930, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6582, ts=1750319136930, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6582, ts=1750319136930, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6582, ts=1750319136930, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:45:47.793 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6542, ts=1750319147469, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6542, ts=1750319147469, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6542, ts=1750319147469, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6542, ts=1750319147469, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6542, ts=1750319147469, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6542, ts=1750319147469, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:45:58.305 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6556, ts=1750319158128, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6556, ts=1750319158128, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6556, ts=1750319158128, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6556, ts=1750319158128, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6556, ts=1750319158128, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6556, ts=1750319158128, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:46:08.800 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6555, ts=1750319168646, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6555, ts=1750319168646, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6555, ts=1750319168646, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6555, ts=1750319168646, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6555, ts=1750319168646, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6555, ts=1750319168646, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:46:19.422 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6560, ts=1750319179156, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6560, ts=1750319179156, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6560, ts=1750319179156, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6560, ts=1750319179156, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6560, ts=1750319179156, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6560, ts=1750319179156, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:46:30.083 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6564, ts=1750319189782, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6564, ts=1750319189782, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6564, ts=1750319189782, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6564, ts=1750319189782, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6564, ts=1750319189782, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6564, ts=1750319189782, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:46:40.640 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6517, ts=1750319200432, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6517, ts=1750319200432, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6517, ts=1750319200432, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6517, ts=1750319200432, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6517, ts=1750319200432, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6517, ts=1750319200432, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:46:51.238 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6521, ts=1750319210971, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6521, ts=1750319210971, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6521, ts=1750319210971, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6521, ts=1750319210971, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6521, ts=1750319210971, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6521, ts=1750319210971, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:47:01.758 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6523, ts=1750319221588, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6523, ts=1750319221588, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6523, ts=1750319221588, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6523, ts=1750319221588, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6523, ts=1750319221588, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6523, ts=1750319221588, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:47:12.365 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6529, ts=1750319232109, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6529, ts=1750319232109, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6529, ts=1750319232109, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6529, ts=1750319232109, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6529, ts=1750319232109, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6529, ts=1750319232109, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:47:22.984 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=63183, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=1, total=6539, ts=1750319242700, pr=20, ni=0, virt=1228, shr=69, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=80, time=0, total=6539, ts=1750319242700, pr=20, ni=0, virt=1126, shr=42, s=S, cpu=0.0, mem=2.4, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=0, total=6539, ts=1750319242700, pr=20, ni=0, virt=703, shr=12, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=63432, user=u0_a113, name=Script helper, pkg=com.example.studyapp, res=200, time=22, total=6539, ts=1750319242700, pr=20, ni=0, virt=14336, shr=106, s=S, cpu=0.0, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1003, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=301, time=742, total=6539, ts=1750319242700, pr=20, ni=0, virt=33792, shr=130, s=S, cpu=0.0, mem=9.1, args=org.autojs.autojs6), MemEntity(id=null, pid=16171, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6539, ts=1750319242700, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-19 15:47:25.325 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.325 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.326 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.326 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.326 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.326 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.326 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.327 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.327 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.327 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.327 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.328 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.328 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.328 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.328 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.329 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.329 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.329 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.329 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.330 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.330 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.330 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.330 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.330 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.331 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.331 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.331 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.331 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.332 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.332 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.332 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.332 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.333 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.333 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.333 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6
2025-06-19 15:47:25.333 297-375 AlarmManager system_server D setImplLocked() callingPackage=org.autojs.autojs6

13
main.js Normal file
View File

@ -0,0 +1,13 @@
var message = "任务已启动";
function sendMessage(message) {
app.sendBroadcast({
action: "org.autojs.SCRIPT_FINISHED", // 自定义广播 Action
extras: {
result: message,
package: "org.autojs.autojs6"// 将结果附加到广播中
}
});
}
sendMessage(message + "点击开始")