Skip to content

Commit a6370c6

Browse files
committed
Xndroid 1.1.0
1 parent a55d416 commit a6370c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2121
-1252
lines changed

LICENSE.txt

+674
Large diffs are not rendered by default.

README.md

+15-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
# Xndroid
2-
XX-Net的Android深度适配版本.
2+
A proxy software for Android based on XX-Net and fqrouter.
3+
4+
基于XX-Net与fqrouter的Android端代理软件, 完美结合XX-Net与fqrouter, 并支持teredo.
35

46
## 特性
5-
* 集成XX-Net 3.6.7(版本号会自动更新)
6-
* 集成LightningBrowser 4.5.1, 默认使用 localhost:8087 代理, 关闭证书警告, 无需任何配置即可直接使用
7-
* 将XX-Net目录放到应用数据目录(/data/data/net.xndroid), 避免误删, 卸载自动删除
8-
* 使用前台服务, 避免意外退出(部分机型可能仍然强制结束进程,需要根据各机型的特点设置.如MIUI在最近应用列表中锁定)
7+
* 集成XX-Net 3.7.16(版本号可自动更新)
8+
* 集成fqrouter, 实现真正的全局代理
9+
* 为fqrouter添加teredo支持, XX-Net + IPV6 自由浏览无障碍
10+
* 为fqrouter添加sock5支持, 方便使用 X_tunnel
11+
* 调用证书安装器安装证书, 确认即可一键安装(如果已经设置过图案解锁,却要求输入凭证,先清除屏幕锁即可)
912
* 监听电量, 网络, 休眠状态, 自动调整最大扫描线程数
10-
* 将语言地区信息添加到环境变量, 避免XX-Net启动时显示为英文
11-
* 调用证书管理器安装证书, 确认即可一键安装(如果已经设置过图案解锁,却要求输入凭证,先清除屏幕锁即可)
13+
* 集成LightningBrowser 4.5.1, 默认使用 localhost:8087 代理, 关闭证书警告
14+
* 将XX-Net目录放到应用数据目录(/data/data/net.xndroid), 避免误删, 卸载自动删除
15+
1216

13-
## 感谢以下项目
17+
## 感谢以下开源项目
1418
* [XX-Net](https://github.com/XX-net/XX-Net)
19+
* [fqrouter (GPL v3.0)](https://github.com/fqrouter/fqrouter)
20+
* [fqsocks](https://github.com/fqrouter/fqsocks)
21+
* [fqdns](https://github.com/fqrouter/fqdns)
1522
* [LightningBrowser](https://github.com/anthonycr/Lightning-Browser)

android_start.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ def load_xxnet():
183183
def setup_logging():
184184
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG if os.getenv('DEBUG') else logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
185185
handler = logging.handlers.RotatingFileHandler(
186-
current_path + "/xxnet_start.log", maxBytes=1024 * 256, backupCount=0)
186+
current_path + "/../log/xxnet_start.log", maxBytes=1024 * 256, backupCount=0)
187187
handler.setFormatter(logging.Formatter('%(asctime)s [android_start]%(levelname)s %(message)s'))
188188
logging.getLogger('xxnet_start').addHandler(handler)
189189

app/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ android {
77
applicationId "net.xndroid"
88
minSdkVersion 14
99
targetSdkVersion 26
10-
versionCode 9
11-
versionName "1.0.5"
10+
versionCode 10
11+
versionName "1.1.0"
1212
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1313
}
1414
buildTypes {

app/src/main/java/net/xndroid/AboutFragment.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@ public class AboutFragment extends Fragment {
2020
@Override
2121
public void onResume() {
2222
super.onResume();
23-
mXXnetVersion.setText("XX-net " + XXnetManager.sXXversion);
23+
mXXnetVersion.setText("XX-Net " + XXnetManager.sXXversion);
2424
}
2525

2626
@Override
2727
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
2828
if(mRootView !=null )
2929
return mRootView;
30-
mRootView = inflater.inflate(net.xndroid.R.layout.fragment_about, container, false);
31-
mVersionView = mRootView.findViewById(net.xndroid.R.id.xndroid_version);
32-
mVersionView.setText("Xndroid " + AppModel.sVersionName);
33-
mXXnetVersion = mRootView.findViewById(net.xndroid.R.id.xndroid_xxnet_version);
34-
mUpdateView = mRootView.findViewById(net.xndroid.R.id.xndroid_check_update);
30+
mRootView = inflater.inflate(R.layout.fragment_about, container, false);
31+
mVersionView = mRootView.findViewById(R.id.xndroid_version);
32+
mVersionView.setText("Xndroid " + AppModel.sVersionName);
33+
mXXnetVersion = mRootView.findViewById(R.id.xndroid_xxnet_version);
34+
mUpdateView = mRootView.findViewById(R.id.xndroid_check_update);
3535
mUpdateView.setOnClickListener(new View.OnClickListener() {
3636
@Override
3737
public void onClick(View v) {
3838
new Thread(new Runnable() {
3939
@Override
4040
public void run() {
41-
AppModel.showToast(getString(net.xndroid.R.string.getting_version));
41+
AppModel.showToast(getString(R.string.getting_version));
4242
UpdateManager.checkUpdate(true);
4343
}
4444
}).start();

app/src/main/java/net/xndroid/AppModel.java

+103-65
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
import net.xndroid.utils.LogUtils;
1919
import net.xndroid.utils.ShellUtils;
2020

21+
import java.io.OutputStreamWriter;
22+
2123
public class AppModel {
2224
public static String sAppPath;
25+
/*use sActivity carefully, it may be null!*/
2326
public static MainActivity sActivity;
2427
public static LaunchService sService;
2528
public static String sFilePath;
@@ -30,6 +33,7 @@ public class AppModel {
3033
public static int sVersionCode;
3134
public static int sLastVersion;
3235
public static String sVersionName;
36+
public static Context sContext;
3337

3438
public static boolean sDebug = false;
3539
public static boolean sLastFail = false;
@@ -41,65 +45,92 @@ public class AppModel {
4145
public static final String PER_LAST_FAIL = "XNDROID_LAST_FAIL";
4246

4347
public static void showToast(final String msg) {
44-
if(sActivity != null) {
45-
sActivity.runOnUiThread(new Runnable() {
46-
@Override
47-
public void run() {
48-
Toast.makeText(sActivity, msg, Toast.LENGTH_LONG).show();
49-
}
50-
});
51-
return;
52-
}
53-
if(sService != null){
54-
Looper.prepare();
55-
Toast.makeText(sService.getApplicationContext(), msg, Toast.LENGTH_LONG).show();
56-
Looper.loop();
48+
try {
49+
if(sActivity != null) {
50+
sActivity.runOnUiThread(new Runnable() {
51+
@Override
52+
public void run() {
53+
Toast.makeText(sActivity, msg, Toast.LENGTH_LONG).show();
54+
}
55+
});
56+
return;
57+
}
58+
if(sService != null){
59+
Looper.prepare();
60+
Toast.makeText(sService.getApplicationContext(), msg, Toast.LENGTH_LONG).show();
61+
Looper.loop();
62+
}
63+
}catch (Exception e){
64+
e.printStackTrace();
5765
}
66+
5867
}
5968

6069
public static void exportLogs(){
61-
ShellUtils.execBusybox("tar -czf /sdcard/xndroid-logs.tar.gz log/ fqrouter/log/");
70+
ShellUtils.execBusybox("tar -czf /sdcard/xndroid-logs.tar.gz -C " + sXndroidFile + " log/ fqrouter/log/");
71+
showToast(sContext.getString(R.string.log_exported));
6272
}
6373

6474
public static void forceStop(){
65-
// android.os.Process.killProcess(android.os.Process.myPid());
66-
6775
String cmd = "busybox ps |busybox grep net.xndroid | busybox cut -c 1-6 |busybox xargs kill -9";
68-
cmd = cmd.replace("busybox", ShellUtils.sBusyBox );
69-
ShellUtils.exec(cmd);
76+
cmd = cmd.replace("busybox", sXndroidFile + "/busybox");
77+
try {
78+
ShellUtils.exec(cmd);
79+
}catch (Exception e){
80+
e.printStackTrace();
81+
try {
82+
Process process = Runtime.getRuntime().exec(sXndroidFile + "/busybox sh");
83+
OutputStreamWriter sInStream = new OutputStreamWriter(process.getOutputStream());
84+
sInStream.write(cmd);
85+
sInStream.write('\n');
86+
sInStream.flush();
87+
process.waitFor();
88+
}catch (Exception ee){
89+
ee.printStackTrace();
90+
android.os.Process.killProcess(android.os.Process.myPid());
91+
}
92+
}
93+
7094
}
7195

7296

7397
public static void fatalError(final String msg){
74-
LogUtils.e("FatalError: " + msg);
75-
exportLogs();
76-
77-
if(sActivity != null) {
78-
sActivity.runOnUiThread(new Runnable() {
79-
@Override
80-
public void run() {
81-
new AlertDialog.Builder(AppModel.sActivity)
82-
.setTitle("FatalError")
83-
.setMessage(msg + "\n\nlogs will be exported to /sdcard/xndroid-logs.tar.gz")
84-
.setNegativeButton("exit", new DialogInterface.OnClickListener() {
85-
@Override
86-
public void onClick(DialogInterface dialog, int which) {
87-
forceStop();
88-
}
89-
}).create().show();
98+
try {
99+
LogUtils.e("FatalError: " + msg);
100+
exportLogs();
101+
102+
if (sActivity != null) {
103+
sActivity.runOnUiThread(new Runnable() {
104+
@Override
105+
public void run() {
106+
new AlertDialog.Builder(AppModel.sActivity)
107+
.setTitle(R.string.fatalerror)
108+
.setMessage(msg)
109+
.setCancelable(false)
110+
.setNegativeButton(R.string.exit, new DialogInterface.OnClickListener() {
111+
@Override
112+
public void onClick(DialogInterface dialog, int which) {
113+
forceStop();
114+
}
115+
}).create().show();
116+
}
117+
});
118+
} else {
119+
showToast(sContext.getString(R.string.fatalerror) + ": " + msg);
120+
forceStop();
121+
}
122+
while (true) {
123+
try {
124+
Thread.sleep(1000);
125+
} catch (InterruptedException e) {
126+
e.printStackTrace();
90127
}
91-
});
92-
}else{
93-
showToast("FatalError: " + msg + " logs will be exported to /sdcard/xndroid-logs.tar.gz");
94-
forceStop();
95-
}
96-
while (true){
97-
try {
98-
Thread.sleep(1000);
99-
} catch (InterruptedException e) {
100-
e.printStackTrace();
101128
}
129+
}catch (Exception e){
130+
e.printStackTrace();
131+
forceStop();
102132
}
133+
103134
}
104135

105136

@@ -109,6 +140,7 @@ private static boolean isApkInDebug(Context context) {
109140
ApplicationInfo info = context.getApplicationInfo();
110141
return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
111142
} catch (Exception e) {
143+
e.printStackTrace();
112144
return false;
113145
}
114146
}
@@ -119,27 +151,30 @@ public static void appStop(){
119151
if(sAppStoped)
120152
return;
121153
sAppStoped = true;
122-
sPreferences.edit().putBoolean(PER_LAST_FAIL, false).commit();
123-
if(sActivity != null) {
124-
sActivity.runOnUiThread(new Runnable() {
154+
try {
155+
sPreferences.edit().putBoolean(PER_LAST_FAIL, false).commit();
156+
if(sActivity != null) {
157+
sActivity.runOnUiThread(new Runnable() {
158+
@Override
159+
public void run() {
160+
sActivity.postStop();
161+
}
162+
});
163+
}
164+
165+
new Thread(new Runnable() {
125166
@Override
126167
public void run() {
127-
sActivity.postStop();
168+
LogUtils.i("appStop");
169+
LaunchService.postStop();
170+
forceStop();
128171
}
129-
});
172+
}).start();
173+
}catch (Exception e){
174+
e.printStackTrace();
175+
forceStop();
130176
}
131177

132-
new Thread(new Runnable() {
133-
@Override
134-
public void run() {
135-
// XXnetService service = XXnetService.getDefaultService();
136-
// if(service != null)
137-
// service.postStop();
138-
LogUtils.i("appStop");
139-
LaunchService.postStop();
140-
forceStop();
141-
}
142-
}).start();
143178

144179
}
145180

@@ -149,17 +184,19 @@ public void run() {
149184
public static boolean sDevScreenOff = false;
150185
public static boolean sIsForeground = true;
151186

152-
public static void checkNetwork(){
187+
private static ConnectivityManager sConnectivityManager;
188+
public static void getNetworkState(){
189+
if(sConnectivityManager == null){
190+
sConnectivityManager = (ConnectivityManager)sContext.getSystemService(Context.CONNECTIVITY_SERVICE);
191+
}
153192
sDevMobileWork = false;
154-
ConnectivityManager connectivityManager = (ConnectivityManager)AppModel
155-
.sActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
156-
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
193+
NetworkInfo activeNetworkInfo = sConnectivityManager.getActiveNetworkInfo();
157194
if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
158195
if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_MOBILE)) {
159196
sDevMobileWork = true;
160197
}
161198
}
162-
LogUtils.i("network change, use_mobile_network=" + AppModel.sDevMobileWork);
199+
LogUtils.i("network change, use_mobile_network=" + sDevMobileWork);
163200
}
164201

165202
private static void updataEnv(int lastVersion){
@@ -172,6 +209,7 @@ public static void appInit(final MainActivity activity){
172209
return;
173210
sAppStoped = false;
174211
sActivity = activity;
212+
sContext = activity.getApplicationContext();
175213
sFilePath = activity.getFilesDir().getAbsolutePath();
176214
sAppPath = activity.getFilesDir().getParent();
177215
sXndroidFile = sFilePath + "/xndroid_files";

0 commit comments

Comments
 (0)