Refactor VPN service to dynamically load tunnel address.
Replaced hardcoded TUN address with a dynamic loader using `ConfigLoader`. Introduced `ConfigLoader` to parse `tun_address` from the configuration file or fallback to a default value. Improved file handling in `V2rayUtil` for better readability and maintainability.
This commit is contained in:
parent
c852142262
commit
208e977d2f
|
@ -119,5 +119,6 @@
|
||||||
"outboundTag": "direct"
|
"outboundTag": "direct"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"tun_address": "172.19.0.1"
|
||||||
}
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.example.studyapp.config;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
public class ConfigLoader {
|
||||||
|
|
||||||
|
// 从 assets 中读取 JSON 文件并解析
|
||||||
|
public static String getTunnelAddress() {
|
||||||
|
String jsonStr;
|
||||||
|
// 获取应用私有目录的文件路径
|
||||||
|
File configFile = new File("/data/v2ray/config.json");
|
||||||
|
|
||||||
|
// 检查文件是否存在
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
return "172.19.0.1"; // 返回默认地址
|
||||||
|
}
|
||||||
|
|
||||||
|
try (BufferedReader reader = new BufferedReader(
|
||||||
|
new InputStreamReader(new FileInputStream(configFile)))) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
stringBuilder.append(line);
|
||||||
|
}
|
||||||
|
jsonStr = stringBuilder.toString();
|
||||||
|
|
||||||
|
// 解析 JSON
|
||||||
|
JSONObject jsonObject = new JSONObject(jsonStr);
|
||||||
|
return jsonObject.optString("tun_address", "172.19.0.1");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "172.19.0.1";
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "172.19.0.1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import android.net.VpnService;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.example.studyapp.config.ConfigLoader;
|
||||||
import com.example.studyapp.utils.V2rayUtil;
|
import com.example.studyapp.utils.V2rayUtil;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
@ -22,9 +23,8 @@ import java.util.List;
|
||||||
public class CustomVpnService extends VpnService {
|
public class CustomVpnService extends VpnService {
|
||||||
|
|
||||||
|
|
||||||
private static final String TUN_ADDRESS = "172.19.0.1"; // TUN 的 IP 地址
|
private static final String TUN_ADDRESS = ConfigLoader.getTunnelAddress(); // TUN 的 IP 地址
|
||||||
private static final int PREFIX_LENGTH = 28; // 子网掩码
|
private static final int PREFIX_LENGTH = 28; // 子网掩码
|
||||||
private static final int MAX_RETRY = 5;
|
|
||||||
|
|
||||||
private ParcelFileDescriptor vpnInterface; // TUN 接口描述符
|
private ParcelFileDescriptor vpnInterface; // TUN 接口描述符
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class V2rayUtil {
|
public class V2rayUtil {
|
||||||
|
private static File v2rayConfig,v2rayBinary;
|
||||||
|
|
||||||
public static void startV2Ray(Context context) {
|
public static void startV2Ray(Context context) {
|
||||||
try {
|
try {
|
||||||
|
@ -19,10 +20,6 @@ public class V2rayUtil {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取文件路径
|
|
||||||
File v2rayBinary = new File(context.getCodeCacheDir(), "v2ray");
|
|
||||||
File v2rayConfig = new File(context.getCodeCacheDir(), "config.json");
|
|
||||||
|
|
||||||
|
|
||||||
// 构建命令
|
// 构建命令
|
||||||
ProcessBuilder builder = new ProcessBuilder(v2rayBinary.getAbsolutePath(), "-config", v2rayConfig.getAbsolutePath()).redirectErrorStream(true);
|
ProcessBuilder builder = new ProcessBuilder(v2rayBinary.getAbsolutePath(), "-config", v2rayConfig.getAbsolutePath()).redirectErrorStream(true);
|
||||||
|
@ -48,18 +45,18 @@ public class V2rayUtil {
|
||||||
try {
|
try {
|
||||||
// 检查并复制 v2ray 可执行文件
|
// 检查并复制 v2ray 可执行文件
|
||||||
String abi = Build.SUPPORTED_ABIS[0]; // 获取当前设备支持的 ABI 架构
|
String abi = Build.SUPPORTED_ABIS[0]; // 获取当前设备支持的 ABI 架构
|
||||||
File binaryOutputFile = new File(context.getCodeCacheDir(), "v2ray");
|
v2rayBinary = new File(context.getCodeCacheDir(), "v2ray");
|
||||||
|
|
||||||
if (!binaryOutputFile.exists()) {
|
if (!v2rayBinary.exists()) {
|
||||||
InputStream binaryInputStream = context.getAssets().open("v2ray/" + abi + "/v2ray");
|
InputStream binaryInputStream = context.getAssets().open("v2ray/" + abi + "/v2ray");
|
||||||
FileOutputStream binaryOutputStream = new FileOutputStream(binaryOutputFile);
|
FileOutputStream binaryOutputStream = new FileOutputStream(v2rayBinary);
|
||||||
try {
|
try {
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int length;
|
int length;
|
||||||
while ((length = binaryInputStream.read(buffer)) > 0) {
|
while ((length = binaryInputStream.read(buffer)) > 0) {
|
||||||
binaryOutputStream.write(buffer, 0, length);
|
binaryOutputStream.write(buffer, 0, length);
|
||||||
}
|
}
|
||||||
Log.i("V2Ray", "Copied v2ray binary to: " + binaryOutputFile.getAbsolutePath());
|
Log.i("V2Ray", "Copied v2ray binary to: " + v2rayBinary.getAbsolutePath());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("V2rayUtil", "Failed to copy v2ray binary", e);
|
Log.e("V2rayUtil", "Failed to copy v2ray binary", e);
|
||||||
return false;
|
return false;
|
||||||
|
@ -68,12 +65,12 @@ public class V2rayUtil {
|
||||||
binaryOutputStream.close();
|
binaryOutputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binaryOutputFile.setExecutable(true, false);
|
v2rayBinary.setExecutable(true, false);
|
||||||
binaryOutputFile.setReadable(true, false);
|
v2rayBinary.setReadable(true, false);
|
||||||
binaryOutputFile.setWritable(true, false);
|
v2rayBinary.setWritable(true, false);
|
||||||
|
|
||||||
// 检查文件是否已经具有可执行权限
|
// 检查文件是否已经具有可执行权限
|
||||||
if (!binaryOutputFile.canExecute()) {
|
if (!v2rayBinary.canExecute()) {
|
||||||
Log.e("V2rayUtil", "Binary file does not have execute permission. Aborting start.");
|
Log.e("V2rayUtil", "Binary file does not have execute permission. Aborting start.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -81,18 +78,18 @@ public class V2rayUtil {
|
||||||
// 检查并复制 config.json 文件
|
// 检查并复制 config.json 文件
|
||||||
|
|
||||||
|
|
||||||
File configFile = new File(context.getCodeCacheDir(), "config.json");
|
v2rayConfig = new File("/data/v2ray/config.json");
|
||||||
|
|
||||||
if (!configFile.exists()) {
|
if (!v2rayConfig.exists()) {
|
||||||
InputStream configInputStream = context.getAssets().open("v2ray/" + abi + "/config.json");
|
InputStream configInputStream = context.getAssets().open("v2ray/" + abi + "/config.json");
|
||||||
FileOutputStream configOutputStream = new FileOutputStream(configFile);
|
FileOutputStream configOutputStream = new FileOutputStream(v2rayConfig);
|
||||||
try {
|
try {
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int length;
|
int length;
|
||||||
while ((length = configInputStream.read(buffer)) > 0) {
|
while ((length = configInputStream.read(buffer)) > 0) {
|
||||||
configOutputStream.write(buffer, 0, length);
|
configOutputStream.write(buffer, 0, length);
|
||||||
}
|
}
|
||||||
Log.i("V2Ray", "Copied v2ray config.json to: " + configFile.getAbsolutePath());
|
Log.i("V2Ray", "Copied v2ray config.json to: " + v2rayConfig.getAbsolutePath());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("V2rayUtil", "Failed to copy config.json", e);
|
Log.e("V2rayUtil", "Failed to copy config.json", e);
|
||||||
return false;
|
return false;
|
||||||
|
@ -101,8 +98,8 @@ public class V2rayUtil {
|
||||||
configOutputStream.close();
|
configOutputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configFile.setReadable(true, false);
|
v2rayConfig.setReadable(true, false);
|
||||||
configFile.setWritable(true, false);
|
v2rayConfig.setWritable(true, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
Loading…
Reference in New Issue