JDK升级到21,优化ClashUtil的代理切换和网络检查逻辑
- 项目的JDK版本从17升级到21。 - ClashUtil的`switchProxyGroup`方法改为同步执行,并增加了对HTTP响应状态码的检查。 - 新增`checkCountryIsUS`方法,用于通过ipinfo.io判断当前IP是否在美国,并在VPN启动后调用此方法进行验证。 - `LoadDeviceWorker`中的`startProxyVpn`方法现在会根据`checkCountryIsUS`的结果来决定是否继续执行后续操作。 - AutoJs脚本 (`main.js`) 更新,使用Promise和async/await来处理并行的HTTP请求,并分别调用ipv4.geojs.io的接口获取国家代码和详细地理位置信息。
This commit is contained in:
parent
619e39cdc6
commit
431267228f
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="17" />
|
<bytecodeTargetLevel target="21" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -1,6 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import com.example.studyapp.utils.LogFileUtil;
|
import com.example.studyapp.utils.LogFileUtil;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -17,6 +18,7 @@ import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
@ -116,26 +118,76 @@ public class ClashUtil {
|
||||||
.put(requestBody)
|
.put(requestBody)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
client.newCall(request).enqueue(new Callback() {
|
try (Response response = client.newCall(request).execute()) { // 将 enqueue 改为 execute
|
||||||
@Override
|
if (response.isSuccessful()) { // 检查请求是否成功 (HTTP 状态码 200-299)
|
||||||
public void onFailure(Call call, IOException e) {
|
if (response.body() != null) {
|
||||||
LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Failed to switch proxy", e);
|
LogFileUtil.logAndWrite(Log.INFO, "ClashUtil", "switchProxyGroup: Switch proxy response", null);
|
||||||
System.out.println("Failed to switch proxy: " + e.getMessage());
|
// 如果需要,可以在这里处理响应体
|
||||||
|
// 例如: 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
|
try (ResponseBody responseBody = response.body()) {
|
||||||
public void onResponse(Call call, Response response) throws IOException {
|
if (responseBody == null) {
|
||||||
try {
|
Log.e("ClashUtil", "Response body is null");
|
||||||
if (response.body() != null) {
|
return false; // Or throw new IOException("Response body is 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,9 +64,9 @@ public class LoadDeviceWorker extends CoroutineWorker {
|
||||||
|
|
||||||
public void executeSingleLogic(Context context) {
|
public void executeSingleLogic(Context context) {
|
||||||
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Proxy not active, starting VPN",null);
|
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Proxy not active, starting VPN",null);
|
||||||
new Handler(Looper.getMainLooper()).post(() -> {
|
if (!startProxyVpn(context)){
|
||||||
startProxyVpn(context);
|
return;
|
||||||
});
|
}
|
||||||
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Changing device info",null);
|
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Changing device info",null);
|
||||||
ChangeDeviceInfoUtil.changeDeviceInfo(context.getPackageName(), context);
|
ChangeDeviceInfoUtil.changeDeviceInfo(context.getPackageName(), context);
|
||||||
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Running AutoJs script",null);
|
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Running AutoJs script",null);
|
||||||
|
@ -74,11 +74,11 @@ public class LoadDeviceWorker extends CoroutineWorker {
|
||||||
AutoJsUtil.runAutojsScript(context);
|
AutoJsUtil.runAutojsScript(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startProxyVpn(Context context) {
|
private boolean startProxyVpn(Context context) {
|
||||||
if (!isNetworkAvailable(context)) {
|
if (!isNetworkAvailable(context)) {
|
||||||
Toast.makeText(context, "Network is not available", Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, "Network is not available", Toast.LENGTH_SHORT).show();
|
||||||
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Network is not available.",null);
|
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Network is not available.",null);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!(context instanceof Activity)) {
|
// if (!(context instanceof Activity)) {
|
||||||
|
@ -90,9 +90,11 @@ public class LoadDeviceWorker extends CoroutineWorker {
|
||||||
try {
|
try {
|
||||||
ClashUtil.startProxy(context); // 在主线程中调用
|
ClashUtil.startProxy(context); // 在主线程中调用
|
||||||
ClashUtil.switchProxyGroup("GLOBAL", "us", "http://127.0.0.1:6170");
|
ClashUtil.switchProxyGroup("GLOBAL", "us", "http://127.0.0.1:6170");
|
||||||
|
return ClashUtil.checkCountryIsUS();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Failed to start VPN",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();
|
Toast.makeText(context, "Failed to start VPN: " + (e.getMessage() != null ? e.getMessage() : "Unknown error"), Toast.LENGTH_SHORT).show();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
88
main.js
88
main.js
|
@ -1,13 +1,81 @@
|
||||||
var message = "任务已启动";
|
function promiseHttpLibGet(url) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
function sendMessage(message) {
|
http.get(url, {}, (res, err) => {
|
||||||
app.sendBroadcast({
|
if (err) {
|
||||||
action: "org.autojs.SCRIPT_FINISHED", // 自定义广播 Action
|
reject(err);
|
||||||
extras: {
|
} else {
|
||||||
result: message,
|
resolve(res);
|
||||||
package: "org.autojs.autojs6"// 将结果附加到广播中
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(message + "点击开始")
|
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(); // 执行主函数
|
Loading…
Reference in New Issue