From 431267228f70ad835b408b603cfc8d1a291a9ffb Mon Sep 17 00:00:00 2001 From: yjj38 Date: Thu, 3 Jul 2025 13:17:14 +0800 Subject: [PATCH] =?UTF-8?q?JDK=E5=8D=87=E7=BA=A7=E5=88=B021=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96ClashUtil=E7=9A=84=E4=BB=A3=E7=90=86=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=92=8C=E7=BD=91=E7=BB=9C=E6=A3=80=E6=9F=A5=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 项目的JDK版本从17升级到21。 - ClashUtil的`switchProxyGroup`方法改为同步执行,并增加了对HTTP响应状态码的检查。 - 新增`checkCountryIsUS`方法,用于通过ipinfo.io判断当前IP是否在美国,并在VPN启动后调用此方法进行验证。 - `LoadDeviceWorker`中的`startProxyVpn`方法现在会根据`checkCountryIsUS`的结果来决定是否继续执行后续操作。 - AutoJs脚本 (`main.js`) 更新,使用Promise和async/await来处理并行的HTTP请求,并分别调用ipv4.geojs.io的接口获取国家代码和详细地理位置信息。 --- .idea/compiler.xml | 2 +- .idea/misc.xml | 3 +- .../com/example/studyapp/proxy/ClashUtil.java | 84 ++++++++++++++---- .../studyapp/worker/LoadDeviceWorker.java | 12 +-- main.js | 88 ++++++++++++++++--- 5 files changed, 156 insertions(+), 33 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index b589d56..b86273d 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index c0dbf3b..cb150cf 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,7 @@ + - + diff --git a/app/src/main/java/com/example/studyapp/proxy/ClashUtil.java b/app/src/main/java/com/example/studyapp/proxy/ClashUtil.java index 4123d11..131edab 100644 --- a/app/src/main/java/com/example/studyapp/proxy/ClashUtil.java +++ b/app/src/main/java/com/example/studyapp/proxy/ClashUtil.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; +import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import com.example.studyapp.utils.LogFileUtil; import java.io.IOException; @@ -17,6 +18,7 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import okhttp3.ResponseBody; import org.json.JSONException; import org.json.JSONObject; @@ -116,26 +118,76 @@ public class ClashUtil { .put(requestBody) .build(); - client.newCall(request).enqueue(new Callback() { - @Override - public void onFailure(Call call, IOException e) { - LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Failed to switch proxy", e); - System.out.println("Failed to switch proxy: " + e.getMessage()); + try (Response response = client.newCall(request).execute()) { // 将 enqueue 改为 execute + if (response.isSuccessful()) { // 检查请求是否成功 (HTTP 状态码 200-299) + if (response.body() != null) { + LogFileUtil.logAndWrite(Log.INFO, "ClashUtil", "switchProxyGroup: Switch proxy response", null); + // 如果需要,可以在这里处理响应体 + // 例如: String responseBodyString = response.body().string(); + // Log.d("ClashUtil", "Response body: " + responseBodyString); + } else { + LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Response body is null", null); + } + } else { + // 请求失败,可以获取 HTTP 状态码 + LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Failed to switch proxy. Code: " + response.code(), null); + System.out.println("Failed to switch proxy. Code: " + response.code()); + } + } catch (IOException e) { + // 网络请求过程中发生 I/O 错误 + LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Failed to switch proxy", e); + System.out.println("Failed to switch proxy: " + e.getMessage()); + } + } + + + public static boolean checkCountryIsUS() { + Request request = new Request.Builder() + .url("http://ipinfo.io/json") + .build(); + OkHttpClient client = new OkHttpClient(); + try (Response response = client.newCall(request).execute()) { // Synchronous call + if (!response.isSuccessful()) { + // Server returned an error + Log.e("ClashUtil", "OkHttp request unsuccessful: " + response.code()); + // Consider how to handle this error synchronously. + // Maybe throw an exception or return a specific error indicator. + return false; // Or throw new IOException("Request failed with code " + response.code()); } - @Override - public void onResponse(Call call, Response response) throws IOException { - try { - if (response.body() != null) { - LogFileUtil.logAndWrite(Log.INFO, "ClashUtil", "switchProxyGroup: Switch proxy response", null); - } else { - LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Response body is null", null); - } - } finally { - response.close(); + try (ResponseBody responseBody = response.body()) { + if (responseBody == null) { + Log.e("ClashUtil", "Response body is null"); + return false; // Or throw new IOException("Response body is null"); } + + String jsonData = responseBody.string(); + JSONObject jsonObject = new JSONObject(jsonData); + String country = jsonObject.optString("country"); + boolean isUS = "US".equalsIgnoreCase(country); + + if (isUS) { + Log.i("ClashUtil", "Country is US. Full data: " + jsonData); + } else { + Log.i("ClashUtil", "Country is NOT US. It is: " + (country.isEmpty() ? "未知" : country) + ". Full data: " + jsonData); + } + return isUS; + + } catch (JSONException e) { + Log.e("ClashUtil", "JSON parsing error: ", e); + // Consider re-throwing or returning an error indicator + return false; + } catch (IOException e) { + Log.e("ClashUtil", "IOException reading response body: ", e); + // Consider re-throwing or returning an error indicator + return false; } - }); + } catch (IOException e) { + // Network request failed + Log.e("ClashUtil", "OkHttp request failed: ", e); + // Consider re-throwing or returning an error indicator + return false; + } } } diff --git a/app/src/main/java/com/example/studyapp/worker/LoadDeviceWorker.java b/app/src/main/java/com/example/studyapp/worker/LoadDeviceWorker.java index 9fa2995..32bf14a 100644 --- a/app/src/main/java/com/example/studyapp/worker/LoadDeviceWorker.java +++ b/app/src/main/java/com/example/studyapp/worker/LoadDeviceWorker.java @@ -64,9 +64,9 @@ public class LoadDeviceWorker extends CoroutineWorker { public void executeSingleLogic(Context context) { LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Proxy not active, starting VPN",null); - new Handler(Looper.getMainLooper()).post(() -> { - startProxyVpn(context); - }); + if (!startProxyVpn(context)){ + return; + } LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Changing device info",null); ChangeDeviceInfoUtil.changeDeviceInfo(context.getPackageName(), context); LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Running AutoJs script",null); @@ -74,11 +74,11 @@ public class LoadDeviceWorker extends CoroutineWorker { AutoJsUtil.runAutojsScript(context); } - private void startProxyVpn(Context context) { + private boolean startProxyVpn(Context context) { if (!isNetworkAvailable(context)) { Toast.makeText(context, "Network is not available", Toast.LENGTH_SHORT).show(); LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Network is not available.",null); - return; + return false; } // if (!(context instanceof Activity)) { @@ -90,9 +90,11 @@ public class LoadDeviceWorker extends CoroutineWorker { try { ClashUtil.startProxy(context); // 在主线程中调用 ClashUtil.switchProxyGroup("GLOBAL", "us", "http://127.0.0.1:6170"); + return ClashUtil.checkCountryIsUS(); } catch (Exception e) { LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Failed to start VPN",e); Toast.makeText(context, "Failed to start VPN: " + (e.getMessage() != null ? e.getMessage() : "Unknown error"), Toast.LENGTH_SHORT).show(); + return false; } } } diff --git a/main.js b/main.js index 6f6161f..d1ee63c 100644 --- a/main.js +++ b/main.js @@ -1,13 +1,81 @@ -var message = "任务已启动"; - -function sendMessage(message) { - app.sendBroadcast({ - action: "org.autojs.SCRIPT_FINISHED", // 自定义广播 Action - extras: { - result: message, - package: "org.autojs.autojs6"// 将结果附加到广播中 - } +function promiseHttpLibGet(url) { + return new Promise((resolve, reject) => { + http.get(url, {}, (res, err) => { + if (err) { + reject(err); + } else { + resolve(res); + } + }); }); } -sendMessage(message + "点击开始") \ No newline at end of file +async function processIpApi(url, successCallback, errorMsgPrefix) { + try { + const res = await promiseHttpLibGet(url); // 使用 await等待Promise结果 + + if (res && res.statusCode == 200) { + try { + let data = res.body.json(); + successCallback(data); + } catch (jsonError) { + toast(errorMsgPrefix + "解析JSON失败"); + console.error(errorMsgPrefix + "解析JSON失败: ", jsonError); + if (res.body && typeof res.body.string === 'function') { + console.log("原始响应体: ", res.body.string()); + } + } + } else if (res) { + toast(errorMsgPrefix + "获取失败,状态码: " + res.statusCode); + console.log(errorMsgPrefix + "获取失败,状态码: " + res.statusCode); + if (res.body && typeof res.body.string === 'function') { + console.log("原始响应体: ", res.body.string()); + } + } else { + toast(errorMsgPrefix + "请求没有返回有效响应"); + console.log(errorMsgPrefix + "请求没有返回有效响应"); + } + } catch (requestError) { + console.error(errorMsgPrefix + "请求失败: ", requestError); + toast(errorMsgPrefix + "请求失败,请检查网络"); + } +} + +async function main() { + // 并行发起两个请求 + const countryPromise = processIpApi("https://ipv4.geojs.io/v1/ip/country.json", function(data2){ + toast("国家代码: " + data2.country); + console.log("地理位置信息:"); + console.log("国家代码 (2位): " + data2.country); + console.log("国家代码 (3位): " + data2.country_3); + console.log("IP 地址: " + data2.ip); + console.log("国家名称: " + data2.name); + }, "地理位置"); + + const geoPromise = processIpApi("https://ipv4.geojs.io/v1/ip/geo.json", function(data3){ + console.log("新增接口返回的地理数据:"); + console.log("经度: " + data3.longitude); + console.log("纬度: " + data3.latitude); + console.log("城市: " + data3.city); + console.log("地区: " + data3.region); + console.log("国家: " + data3.country); + console.log("组织名称: " + data3.organization_name); + console.log("IP 地址: " + data3.ip); + console.log("国家代码 (2位): " + data3.country_code); + console.log("国家代码 (3位): " + data3.country_code3); + console.log("时区: " + data3.timezone); + console.log("ASN: " + data3.asn); + console.log("洲: " + data3.continent_code); + }, "详细地理位置"); + + // 等待两个请求完成(或失败) + try { + await Promise.all([countryPromise, geoPromise]); + } catch (error) { + console.error("一个或多个API请求失败:", error); + } +} + + + +main(); // 执行主函数 \ No newline at end of file