diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 00b7515..8ac24cf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,6 +19,8 @@ + + - + + + diff --git a/app/src/main/java/com/example/studyapp/MainActivity.java b/app/src/main/java/com/example/studyapp/MainActivity.java index 3661983..cd4d7c1 100644 --- a/app/src/main/java/com/example/studyapp/MainActivity.java +++ b/app/src/main/java/com/example/studyapp/MainActivity.java @@ -11,6 +11,8 @@ import android.net.NetworkCapabilities; import android.os.Build; import android.os.Bundle; import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; @@ -30,7 +32,13 @@ import com.example.studyapp.device.ChangeDeviceInfoUtil; import com.example.studyapp.utils.ClashUtil; import com.example.studyapp.worker.CheckAccessibilityWorker; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; public class MainActivity extends AppCompatActivity { @@ -38,6 +46,8 @@ public class MainActivity extends AppCompatActivity { private static final int ALLOW_ALL_FILES_ACCESS_PERMISSION_CODE = 1001; + private ExecutorService executorService; + // 假设我们从配置文件中提取出了以下 name 项数据(仅为部分示例数据) private final String[] proxyNames = { "mr", "sr", "bq", "ml", "ht", "ga", "mk", "by", "pr", "hr", "hu", @@ -55,12 +65,25 @@ public class MainActivity extends AppCompatActivity { "ge", "ps" }; + // 初始化 ExecutorService + private void initializeExecutorService() { + if (executorService == null || executorService.isShutdown()) { + executorService = new ThreadPoolExecutor( + 1, // 核心线程数 + 1, // 最大线程数 + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(50), // 阻塞队列 + new ThreadPoolExecutor.AbortPolicy() // 拒绝策略 + ); + } + } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + initializeExecutorService(); System.setProperty("java.library.path", this.getApplicationInfo().nativeLibraryDir); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { // 针对 Android 10 或更低版本检查普通存储权限 @@ -123,7 +146,7 @@ public class MainActivity extends AppCompatActivity { Button modifyDeviceInfoButton = findViewById(R.id.modifyDeviceInfoButton); if (modifyDeviceInfoButton != null) { - modifyDeviceInfoButton.setOnClickListener(v -> ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(),this)); + modifyDeviceInfoButton.setOnClickListener(v -> ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this)); } else { Toast.makeText(this, "modifyDeviceInfo button not found", Toast.LENGTH_SHORT).show(); } @@ -135,47 +158,117 @@ public class MainActivity extends AppCompatActivity { Toast.makeText(this, "resetDeviceInfo button not found", Toast.LENGTH_SHORT).show(); } + // 初始化 ChangeDeviceInfoUtil + ChangeDeviceInfoUtil.initialize("US", 2); // 获取输入框和按钮 EditText inputNumber = findViewById(R.id.input_number); Button executeButton = findViewById(R.id.execute_button); + Button stopExecuteButton = findViewById(R.id.stop_execute_button); // 设置按钮的点击事件 - executeButton.setOnClickListener(v -> executeLogic(inputNumber) ); + if (inputNumber != null && executeButton != null) { + executeButton.setOnClickListener(v -> { + executeButton.setEnabled(false); + Toast.makeText(this, "任务正在执行", Toast.LENGTH_SHORT).show(); + executeLogic(inputNumber); + }); + } + if (stopExecuteButton != null) { + stopExecuteButton.setOnClickListener(v -> { + if (executorService != null && !executorService.isShutdown()) { + executorService.shutdownNow(); + ClashUtil.stopProxy(this); + AutoJsUtil.stopAutojsScript(this); + executeButton.setEnabled(true); + } + }); + } else { + Toast.makeText(this, "Stop button not found", Toast.LENGTH_SHORT).show(); + } } - // 提取的独立方法 private void executeLogic(EditText inputNumber) { - String numberText = inputNumber.getText().toString(); // 获取输入框内容 + Log.i("MainActivity", "executeLogic: Start execution"); - if (numberText.isEmpty()) { + 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; // 退出执行 + return; } int number; try { - number = Integer.parseInt(numberText); // 将输入内容转换为整数 + 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; // 输入无效的退出 + return; } - // 循环执行逻辑代码 - for (int i = 0; i < number; i++) { - // 假设这里是您需要选中的代码逻辑 - try { - if (!ClashUtil.checkProxy(this)) { - startProxyVpn(this); - } else { - ClashUtil.switchProxyGroup("GLOBAL", proxyNames[i], "http://127.0.0.1:6170"); - } - ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this); - AutoJsUtil.runAutojsScript(this); - Toast.makeText(this, "第 " + (i + 1) + " 次执行完成", Toast.LENGTH_SHORT).show(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + if (number > proxyNames.length) { + Log.e("MainActivity", "executeLogic: Number exceeds proxyNames length: " + number); + Toast.makeText(this, "输入的数字超出代理名称范围", Toast.LENGTH_SHORT).show(); + return; } + + if (!isNetworkAvailable(this)) { + Log.e("MainActivity", "executeLogic: Network is not available!"); + Toast.makeText(this, "网络不可用,请检查网络连接", Toast.LENGTH_SHORT).show(); + return; + } + + Log.i("MainActivity", "executeLogic: Submitting job to executor"); + long startTime = System.currentTimeMillis(); // 开始计时 + + initializeExecutorService(); + executorService.submit(() -> { + try { + for (int i = 0; i < number; i++) { + executeSingleLogic(i); + } + } catch (Exception e) { + Log.e("MainActivity", "executeLogic: Unexpected task error.", e); + } + }); + } + + private void executeSingleLogic(int i) { + Log.i("MainActivity", "executeSingleLogic: Start execution for index " + i); + long startTime = System.currentTimeMillis(); // 开始计时 + + Log.i("MainActivity", "executeSingleLogic: Proxy not active, starting VPN"); + startProxyVpn(this); + + Log.i("MainActivity", "executeSingleLogic: Switching proxy group to " + proxyNames[i]); + try { + ClashUtil.switchProxyGroup("GLOBAL", proxyNames[i], "http://127.0.0.1:6170"); + } catch (Exception e) { + Log.e("MainActivity", "executeSingleLogic: Failed to switch proxy group", e); + runOnUiThread(() -> Toast.makeText(this, "切换代理组失败:" + e.getMessage(), Toast.LENGTH_SHORT).show()); + } + + Log.i("MainActivity", "executeSingleLogic: Changing device info"); + ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this); + + Log.i("MainActivity", "executeSingleLogic: Running AutoJs script"); + AutoJsUtil.runAutojsScript(this); + + runOnUiThread(() -> Toast.makeText(this, "第 " + (i + 1) + " 次执行完成", Toast.LENGTH_SHORT).show()); + + long endTime = System.currentTimeMillis(); // 结束计时 + Log.i("MainActivity", "executeSingleLogic: Finished execution for index " + i + " in " + (endTime - startTime) + " ms"); } @@ -189,7 +282,6 @@ public class MainActivity extends AppCompatActivity { Toast.makeText(context, "Context must be an Activity", Toast.LENGTH_SHORT).show(); return; } - Activity activity = (Activity) context; try { ClashUtil.startProxy(context); // 在主线程中调用 @@ -255,6 +347,9 @@ public class MainActivity extends AppCompatActivity { if (AutoJsUtil.scriptResultReceiver != null) { unregisterReceiver(AutoJsUtil.scriptResultReceiver); } + if (executorService != null) { + executorService.shutdown(); // 关闭线程池 + } } private boolean isNetworkAvailable(Context context) { diff --git a/app/src/main/java/com/example/studyapp/autoJS/AutoJsUtil.java b/app/src/main/java/com/example/studyapp/autoJS/AutoJsUtil.java index 8b93305..2464f39 100644 --- a/app/src/main/java/com/example/studyapp/autoJS/AutoJsUtil.java +++ b/app/src/main/java/com/example/studyapp/autoJS/AutoJsUtil.java @@ -1,11 +1,17 @@ package com.example.studyapp.autoJS; +import static androidx.core.content.ContextCompat.startActivity; + +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Environment; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; import android.widget.Toast; import androidx.core.content.ContextCompat; @@ -27,39 +33,58 @@ public class AutoJsUtil { public static BroadcastReceiver scriptResultReceiver; public static void runAutojsScript(Context context) { - // 定义脚本文件路径 - File scriptFile = new File(Environment.getExternalStorageDirectory(), "脚本/chromium.js"); - - // 检查文件是否存在 + // 检查脚本文件 + File scriptFile = new File(Environment.getExternalStorageDirectory(), "autojs/chromium.js"); if (!scriptFile.exists()) { - Toast.makeText(context, "Script file not found: " + scriptFile.getAbsolutePath(), Toast.LENGTH_SHORT).show(); + runOnUiThread(() -> Toast.makeText(context, "Script file not found: " + scriptFile.getAbsolutePath(), Toast.LENGTH_SHORT).show()); return; } - // 检查 Auto.js 应用是否安装 - if (!isAppInstalled("org.autojs.autojs6",context.getPackageManager())) { - Toast.makeText(context, "Auto.js app not installed", Toast.LENGTH_SHORT).show(); + // 检查是否安装 Auto.js + if (!isAppInstalled("org.autojs.autojs6", context.getPackageManager())) { + runOnUiThread(() -> Toast.makeText(context, "Auto.js app not installed", Toast.LENGTH_SHORT).show()); return; } - // 准备启动 Auto.js 的 Intent + // 开始运行脚本 Intent intent = new Intent(); intent.setClassName("org.autojs.autojs6", "org.autojs.autojs.external.open.RunIntentActivity"); - intent.putExtra("path", scriptFile.getAbsolutePath()); // 传递脚本路径 + intent.putExtra("path", scriptFile.getAbsolutePath()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // 启动 Auto.js try { - // 模拟:通过广播监听脚本运行结果 - registerScriptResultReceiver(context); // 注册结果回调监听(假设脚本通过广播返回结果) context.startActivity(intent); - Toast.makeText(context, "Running script: " + scriptFile.getAbsolutePath(), Toast.LENGTH_SHORT).show(); + runOnUiThread(() -> Toast.makeText(context, "Running script: " + scriptFile.getAbsolutePath(), Toast.LENGTH_SHORT).show()); } catch (Exception e) { e.printStackTrace(); - Toast.makeText(context, "Failed to run script", Toast.LENGTH_SHORT).show(); + runOnUiThread(() -> Toast.makeText(context, "Failed to run script", Toast.LENGTH_SHORT).show()); } } + public static void stopAutojsScript(Context context) { + // 停止运行脚本 + Intent stopIntent = new Intent(); + stopIntent.setClassName("org.autojs.autojs6", "org.autojs.autojs.external.open.StopServiceActivity"); + stopIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // 设置任务栈优先级 + + + try { + context.startActivity(stopIntent); // 发送停止脚本的 Intent + Toast.makeText(context, "脚本停止管理已发送", Toast.LENGTH_SHORT).show(); + } catch (ActivityNotFoundException e) { + Toast.makeText(context, "目标活动未找到:请确认 AutoJs 配置", Toast.LENGTH_LONG).show(); + Log.e("AutoJsUtil", "ActivityNotFoundException: 请确保目标应用的包名和活动名正确 (org.autojs.autojs6).", e); + } catch (Exception e) { + Toast.makeText(context, "无法发送停止命令,请检查 AutoJs 配置", Toast.LENGTH_SHORT).show(); + Log.e("AutoJsUtil", "Error occurred when trying to stop AutoJs script", e); + } + } + + // 在主线程运行 + private static void runOnUiThread(Runnable action) { + new Handler(Looper.getMainLooper()).post(action); + } + // 检查目标应用是否安装 public static boolean isAppInstalled(String packageName,PackageManager packageManager) { try { diff --git a/app/src/main/java/com/example/studyapp/device/ChangeDeviceInfoUtil.java b/app/src/main/java/com/example/studyapp/device/ChangeDeviceInfoUtil.java index b861821..f8faf8c 100644 --- a/app/src/main/java/com/example/studyapp/device/ChangeDeviceInfoUtil.java +++ b/app/src/main/java/com/example/studyapp/device/ChangeDeviceInfoUtil.java @@ -5,12 +5,15 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.Uri; import android.util.Log; import com.example.studyapp.utils.HttpUtil; import com.example.studyapp.utils.ShellUtils; import com.google.android.gms.ads.identifier.AdvertisingIdClient; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -20,50 +23,111 @@ import java.lang.reflect.Method; public class ChangeDeviceInfoUtil { - private static final String BIGO_URL = "http://8.217.137.25/tt/zj/dispatcher!bigo.do?country=US&tag=2"; - private static final JSONObject bigoDeviceObject; - private static final String AF_URL = "http://8.217.137.25/tt/zj/dispatcher!bigo.do?country=US&tag=2"; - private static final JSONObject afDeviceObject; + private static JSONObject bigoDeviceObject; - static { - try { - // 请求接口并获取 JSON - String bigoJson = HttpUtil.requestGet(BIGO_URL); - final String afJson = HttpUtil.requestGet(AF_URL); - // 解析 JSON 字符串 - JSONObject bigoObject = new JSONObject(bigoJson); - bigoDeviceObject = bigoObject.optJSONObject("device"); - JSONObject afObject = new JSONObject(bigoJson); - afDeviceObject = bigoObject.optJSONObject("device"); - if (bigoDeviceObject == null) { - throw new JSONException("Device object is missing in the bigo response JSON"); - } - if (afDeviceObject == null) { - throw new JSONException("Device object is missing in the af response JSON"); - } - Log.d("Debug", "bigoDeviceObject: " + bigoDeviceObject.toString()); - Log.d("Debug", "afDeviceObject: " + afDeviceObject.toString()); - } catch (Exception e) { - throw new IllegalStateException("Failed to load or parse the response JSON", e); - } + private static JSONObject afDeviceObject; + + public static String buildBigoUrl(String country, int tag) { + return Uri.parse("http://8.217.137.25/tt/zj/dispatcher!bigo.do") + .buildUpon() + .appendQueryParameter("country", country) + .appendQueryParameter("tag", String.valueOf(tag)) + .toString(); } + public static String buildAfUrl(String country, int tag) { + return Uri.parse("http://8.217.137.25/tt/zj/dispatcher!af.do") + .buildUpon() + .appendQueryParameter("country", country) + .appendQueryParameter("tag", String.valueOf(tag)) + .toString(); + } + + // 创建一个线程池用于执行网络任务 + private static final ExecutorService executorService = Executors.newSingleThreadExecutor(); + + public static void initialize(String country, int tag) { + executorService.submit(() -> { + try { + String bigoJson = HttpUtil.requestGet(buildBigoUrl(country, tag)); + String afJson = HttpUtil.requestGet(buildAfUrl(country, tag )); + + bigoDeviceObject = new JSONObject(bigoJson).optJSONObject("device"); + afDeviceObject = new JSONObject(afJson).optJSONObject("device"); + + if (bigoDeviceObject == null || afDeviceObject == null) { + throw new JSONException("Device object is missing in the response JSON"); + } + + Log.d("Debug", "bigoDeviceObject: " + bigoDeviceObject.toString()); + Log.d("Debug", "afDeviceObject: " + afDeviceObject.toString()); + } catch (Exception e) { + Log.e("Error", "Failed to load or parse the response JSON", e); + } + }); + } + + public static void changeDeviceInfo(String current_pkg_name, Context context) { try { - // 动态读取 JSON 中的值 + // BIGO String cpuClockSpeed = bigoDeviceObject.getString("cpu_clock_speed"); - // String country = bigoDeviceObject.getString("country"); String gaid = bigoDeviceObject.getString("gaid"); String userAgent = bigoDeviceObject.getString("User-Agent"); String osLang = bigoDeviceObject.getString("os_lang"); String osVer = bigoDeviceObject.getString("os_ver"); - // String model = bigoDeviceObject.getString("model"); String tz = bigoDeviceObject.getString("tz"); + String systemCountry = bigoDeviceObject.getString("system_country"); + String simCountry = bigoDeviceObject.getString("sim_country"); + long romFreeIn = bigoDeviceObject.getLong("rom_free_in"); + String resolution = bigoDeviceObject.getString("resolution"); + String vendor = bigoDeviceObject.getString("vendor"); + int batteryScale = bigoDeviceObject.getInt("bat_scale"); + //String model = deviceObject.getString("model"); + String net = bigoDeviceObject.getString("net"); + int dpi = bigoDeviceObject.getInt("dpi"); + long romFreeExt = bigoDeviceObject.getLong("rom_free_ext"); + String dpiF = bigoDeviceObject.getString("dpi_f"); + int cpuCoreNum = bigoDeviceObject.getInt("cpu_core_num"); + // 自动处理分辨率信息 + // int widthPixels = Integer.parseInt(resolution.split("x")[0]); + // int heightPixels = Integer.parseInt(resolution.split("x")[1]); - // 动态读取 JSON 中的值 + // 更新屏幕显示相关参数 + // JSONObject displayMetrics = new JSONObject(); + // displayMetrics.put("widthPixels", widthPixels); + // displayMetrics.put("heightPixels", heightPixels); + // displayMetrics.put("densityDpi", dpi); + // callVCloudSettings_put("screen.device.displayMetrics", displayMetrics.toString(), context); + + 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 String advertiserId = afDeviceObject.getString(".advertiserId"); String model = afDeviceObject.getString(".model"); String brand = afDeviceObject.getString(".brand"); @@ -71,193 +135,38 @@ public class ChangeDeviceInfoUtil { int xPixels = afDeviceObject.optInt(".deviceData.dim.x_px"); int yPixels = afDeviceObject.optInt(".deviceData.dim.y_px"); int densityDpi = afDeviceObject.optInt(".deviceData.dim.d_dpi"); - String lang = afDeviceObject.getString(".lang"); String country = afDeviceObject.getString(".country"); String batteryLevel = afDeviceObject.getString(".batteryLevel"); - + String stackInfo = Thread.currentThread().getStackTrace()[2].toString(); + String product = afDeviceObject.getString(".product"); + String network = afDeviceObject.getString(".network"); + String langCode = afDeviceObject.getString(".lang_code"); + String cpuAbi = afDeviceObject.getString(".deviceData.cpu_abi"); + int yDp = afDeviceObject.getInt(".deviceData.dim.ydp"); + String lang = afDeviceObject.getString(".lang"); // 替换写死的值为 JSON 动态值 callVCloudSettings_put(current_pkg_name + ".advertiserId", advertiserId, context); callVCloudSettings_put(current_pkg_name + ".model", model, context); callVCloudSettings_put(current_pkg_name + ".brand", brand, context); callVCloudSettings_put(current_pkg_name + ".android_id", androidId, context); + callVCloudSettings_put(current_pkg_name + ".lang", lang, context); + callVCloudSettings_put(current_pkg_name + ".country", country, context); + callVCloudSettings_put(current_pkg_name + ".batteryLevel", batteryLevel, context); + callVCloudSettings_put(current_pkg_name + "_screen.getMetrics.stack", stackInfo, context); + callVCloudSettings_put(current_pkg_name + ".product", product, context); + callVCloudSettings_put(current_pkg_name + ".network", network, context); + callVCloudSettings_put(current_pkg_name + ".cpu_abi", cpuAbi, context); + callVCloudSettings_put(current_pkg_name + ".lang_code", langCode, context); + // **广告标识符 (advertiserId)** 及 **启用状态** + boolean isAdIdEnabled = true; // 默认启用广告 ID + callVCloudSettings_put(current_pkg_name + ".advertiserIdEnabled", String.valueOf(isAdIdEnabled), context); JSONObject displayMetrics = new JSONObject(); displayMetrics.put("widthPixels", xPixels); displayMetrics.put("heightPixels", yPixels); displayMetrics.put("densityDpi", densityDpi); - callVCloudSettings_put("screen.getDisplayMetrics", displayMetrics.toString(), context); - - callVCloudSettings_put(current_pkg_name + ".lang", lang, context); - callVCloudSettings_put(current_pkg_name + ".country", country, context); - callVCloudSettings_put(current_pkg_name + ".batteryLevel", batteryLevel, context); - - Log.d("ChangeDeviceInfoUtil", "Device info successfully updated."); - - - // 指定包名优先级高于全局 - callVCloudSettings_put(current_pkg_name + "_android_id", "my123456", context); - callVCloudSettings_put(current_pkg_name + "_screen_brightness", "100", context); - callVCloudSettings_put(current_pkg_name + "_adb_enabled", "1", context); - callVCloudSettings_put(current_pkg_name + "_development_settings_enabled", "1", context); - - callVCloudSettings_put("pm_list_features", "my_pm_list_features", context); - callVCloudSettings_put("pm_list_libraries", "my_pm_list_libraries", context); - callVCloudSettings_put("system.http.agent", "my_system.http.agent", context); - callVCloudSettings_put("webkit.http.agent", "my_webkit.http.agent", context); - - callVCloudSettings_put("global_android_id", "123456", context); - - callVCloudSettings_put("anticheck_pkgs", current_pkg_name, context); - - JSONObject pkg_info_json = new JSONObject(); - pkg_info_json.put("versionName", "1.0.0"); - pkg_info_json.put("versionCode", 100); - pkg_info_json.put("firstInstallTime", 1); - pkg_info_json.put("lastUpdateTime", 1); - callVCloudSettings_put("com.fk.tools_pkgInfo", pkg_info_json.toString(), context); - - JSONObject tmp_json = new JSONObject(); - tmp_json.put("widthPixels", 1080); - tmp_json.put("heightPixels", 1920); - tmp_json.put("densityDpi", 440); - tmp_json.put("xdpi", 160); - tmp_json.put("ydpi", 160); - tmp_json.put("density", 3.0); - tmp_json.put("scaledDensity", 3.0); - callVCloudSettings_put("screen.getDisplayMetrics", tmp_json.toString(), context); - callVCloudSettings_put("screen.getMetrics", tmp_json.toString(), context); - callVCloudSettings_put("screen.getRealMetrics", tmp_json.toString(), context); - callVCloudSettings_put(current_pkg_name + "_screen.getDisplayMetrics.stack", ".getDeviceInfo", context); - String stackInfo = Thread.currentThread().getStackTrace()[2].toString(); - callVCloudSettings_put(current_pkg_name + "_screen.getMetrics.stack", stackInfo, context); - callVCloudSettings_put(current_pkg_name + "_screen.getRealMetrics.stack", ".getDeviceInfo", context); - - tmp_json = new JSONObject(); - tmp_json.put("width", 1080); - tmp_json.put("height", 1820); - callVCloudSettings_put("screen.getRealSize", tmp_json.toString(), context); - callVCloudSettings_put(current_pkg_name + "_screen.getRealSize.stack", ".getDeviceInfo", context); - - tmp_json = new JSONObject(); - tmp_json.put("left", 0); - tmp_json.put("top", 0); - tmp_json.put("right", 1080); - tmp_json.put("bottom", 1920); - callVCloudSettings_put("screen.getCurrentBounds", tmp_json.toString(), context); - callVCloudSettings_put("screen.getMaximumBounds", tmp_json.toString(), context); - callVCloudSettings_put(current_pkg_name + "_screen.getCurrentBounds.stack", ".getDeviceInfo", context); - callVCloudSettings_put(current_pkg_name + "_screen.getMaximumBounds.stack", ".getDeviceInfo", context); - - // **User-Agent** - callVCloudSettings_put(current_pkg_name + "_user_agent", userAgent, context); - - // **os_ver** - callVCloudSettings_put(current_pkg_name + "_os_ver", osVer, context); - - // **os_lang**系统语言 - callVCloudSettings_put(current_pkg_name + "_os_lang", osLang, context); - - // **dpi** - JSONObject densityJson = new JSONObject(); - densityJson.put("density", context.getResources().getDisplayMetrics().density); - callVCloudSettings_put(current_pkg_name + "_dpi", densityJson.toString(), context); - - // **dpi_f** - JSONObject realResolutionJson = new JSONObject(); - realResolutionJson.put("width", 411); - realResolutionJson.put("height", 731); - callVCloudSettings_put(current_pkg_name + "_dpi_f", realResolutionJson.toString(), context); - - // **tz** (时区) - callVCloudSettings_put(current_pkg_name + "_tz", tz, context); - - // **isp** (网络运营商) - android.telephony.TelephonyManager telephonyManager = (android.telephony.TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - String isp = telephonyManager != null ? telephonyManager.getNetworkOperatorName() : "unknown"; - callVCloudSettings_put(current_pkg_name + "_isp", isp, context); - - // **net** (网络类型:WiFi/流量) - ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - - if (connectivityManager != null) { - Network activeNetwork = connectivityManager.getActiveNetwork(); - NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(activeNetwork); - - String netType = "Unknown"; - if (capabilities != null) { - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - netType = "WiFi"; - } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - netType = "Cellular"; - } - } - - callVCloudSettings_put(current_pkg_name + "_net", netType, context); - } - - // **广告标识符 (advertiserId)** 及 **启用状态** - boolean isAdIdEnabled = true; // 默认启用广告 ID - String advertiserId = "test-advertiser-id"; // 模拟广告 ID - callVCloudSettings_put(current_pkg_name + ".advertiserId", advertiserId, context); - callVCloudSettings_put(current_pkg_name + ".advertiserIdEnabled", String.valueOf(isAdIdEnabled), context); - - // **AppsFlyer 参数** - callVCloudSettings_put(current_pkg_name + ".af_currentstore", "Google Play", context); - callVCloudSettings_put(current_pkg_name + ".af_events_api", "2.0", context); - callVCloudSettings_put(current_pkg_name + ".af_installstore", "official", context); - callVCloudSettings_put(current_pkg_name + ".af_timestamp", String.valueOf(System.currentTimeMillis()), context); - callVCloudSettings_put(current_pkg_name + ".af_v", "v1.0", context); - callVCloudSettings_put(current_pkg_name + ".af_v2", "v2.0", context); - - // **设备信息参数** - callVCloudSettings_put(current_pkg_name + ".android_id", "android-test-id", context); - callVCloudSettings_put(current_pkg_name + ".app_version_code", "100", context); - callVCloudSettings_put(current_pkg_name + ".app_version_name", "1.0.0", context); - callVCloudSettings_put(current_pkg_name + ".brand", android.os.Build.BRAND, context); - callVCloudSettings_put(current_pkg_name + ".device", android.os.Build.DEVICE, context); - callVCloudSettings_put(current_pkg_name + ".model", model, context); - callVCloudSettings_put(current_pkg_name + ".cpu_clock_speed", cpuClockSpeed, context); - - // **语言及区域** - String lang = context.getResources().getConfiguration().locale.getLanguage(); - String langCode = context.getResources().getConfiguration().locale.toString(); - callVCloudSettings_put(current_pkg_name + ".lang", lang, context); - callVCloudSettings_put(current_pkg_name + ".lang_code", langCode, context); - callVCloudSettings_put(current_pkg_name + ".country", country, context); - - // **传感器模拟数据** - JSONObject sensorsJson = new JSONObject(); - sensorsJson.put("sN", "TestSensor"); // 传感器名称 - sensorsJson.put("sT", "type_sample"); // 传感器类型 - sensorsJson.put("sV", "1.2"); // 传感器版本 - JSONArray sensorValues = new JSONArray(); - sensorValues.put("v0"); - sensorValues.put("v1"); - sensorValues.put("v2"); - sensorsJson.put("sVE", sensorValues); - callVCloudSettings_put(current_pkg_name + ".deviceData.sensors.[0]", sensorsJson.toString(), context); - - // **电量、电磁 MCC/MNC** - callVCloudSettings_put(current_pkg_name + ".batteryLevel", "85", context); - callVCloudSettings_put(current_pkg_name + ".cell.mcc", "310", context); // MCC: 示例 - callVCloudSettings_put(current_pkg_name + ".cell.mnc", "260", context); // MNC: 示例 - - // **日期与时间戳** - callVCloudSettings_put(current_pkg_name + ".date1", String.valueOf(System.currentTimeMillis()), context); - callVCloudSettings_put(current_pkg_name + ".date2", String.valueOf(System.nanoTime()), context); - - // **其他示例条目** - callVCloudSettings_put(current_pkg_name + ".appsflyerKey", "example-key", context); - callVCloudSettings_put(current_pkg_name + ".appUserId", "test-user-id", context); - callVCloudSettings_put(current_pkg_name + ".disk", "128GB", context); - callVCloudSettings_put(current_pkg_name + ".operator", "Fake Operator", context); - - // **gaid** (Google 广告 ID) - try { - callVCloudSettings_put(current_pkg_name + "_gaid", gaid, context); - } catch (Throwable e) { - Log.e("ChangeDeviceInfoUtil", "Failed to get GAID", e); - } + displayMetrics.put("yDp", yDp); + callVCloudSettings_put("screen.device.displayMetrics", displayMetrics.toString(), context); } catch (Throwable e) { Log.e("ChangeDeviceInfoUtil", "Error occurred while changing device info", e); @@ -280,21 +189,16 @@ public class ChangeDeviceInfoUtil { ShellUtils.execRootCmd("setprop ro.board.platform acr980m"); Native.setBootId("400079ef55a4475558eb60a0544a43d5"); - // 修改drm id ShellUtils.execRootCmd("setprop persist.sys.cloud.drm.id 400079ef55a4475558eb60a0544a43d5171258f13fdd48c10026e2847a6fc7a5"); - // 电量模拟需要大于1000 ShellUtils.execRootCmd("setprop persist.sys.cloud.battery.capacity 5000"); - ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_vendor my_gl_vendor"); ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_renderer my_gl_renderer"); // 这个值不能随便改 必须是 OpenGL ES %d.%d 这个格式 ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_version \"OpenGL ES 3.2\""); - ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_vendor my_egl_vendor"); ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_version my_egl_version"); - } private static void callVCloudSettings_put(String key, String value, Context context) { diff --git a/app/src/main/java/com/example/studyapp/utils/ClashUtil.java b/app/src/main/java/com/example/studyapp/utils/ClashUtil.java index 2d4e4ac..ebf94d8 100644 --- a/app/src/main/java/com/example/studyapp/utils/ClashUtil.java +++ b/app/src/main/java/com/example/studyapp/utils/ClashUtil.java @@ -52,10 +52,16 @@ public class ClashUtil { } }; - public static boolean checkProxy(Context context) throws InterruptedException { + public static boolean checkProxy(Context context) { CountDownLatch latch = new CountDownLatch(1); - checkClashStatus(context, latch); - latch.await(); // 等待广播接收器更新状态 + try { + checkClashStatus(context, latch); + latch.await(); // 等待广播接收器更新状态 + } catch (InterruptedException e) { + Log.e("ClashUtil", "checkProxy: Waiting interrupted", e); + Thread.currentThread().interrupt(); // 重新设置中断状态 + return false; // 返回默认状态或尝试重试 + } return isRunning; } diff --git a/app/src/main/java/com/example/studyapp/utils/ShellUtils.java b/app/src/main/java/com/example/studyapp/utils/ShellUtils.java index 3f1638a..35460dd 100644 --- a/app/src/main/java/com/example/studyapp/utils/ShellUtils.java +++ b/app/src/main/java/com/example/studyapp/utils/ShellUtils.java @@ -9,6 +9,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.InterruptedIOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.util.ArrayList; @@ -257,13 +258,22 @@ public class ShellUtils { os.flush(); } - // 等待子进程完成 - process.waitFor(); + try { + // 执行命令、等待解决 + process.waitFor(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // 恢复中断 + Log.e("ShellUtils", "Error executing commands", e); + } + // 等待子线程完成 stdThread.join(); errThread.join(); + } catch (InterruptedIOException e) { + Log.e("ShellUtils", "Error reading stdout: Interrupted", e); + Thread.currentThread().interrupt(); // 恢复线程的中断状态 } catch (Exception e) { Log.e("ShellUtils", "Error executing commands", e); } finally { diff --git a/app/src/main/jniLibs/arm64-v8a/libnative.so b/app/src/main/jniLibs/arm64-v8a/libnative.so index f87c13d..1935dd8 100644 Binary files a/app/src/main/jniLibs/arm64-v8a/libnative.so and b/app/src/main/jniLibs/arm64-v8a/libnative.so differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 20eec31..99bec1d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" - android:background="@drawable/background" tools:context=".MainActivity"> +