Skip to content

Commit 45692fd

Browse files
author
krxkli
committed
Support arm, arm64, amd64, Android 8
1 parent 5f6ca84 commit 45692fd

18 files changed

+448
-32
lines changed

Diff for: Android/app/build.gradle.kts

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ android {
1111
applicationId = "com.krxkli.scut_router"
1212
minSdk = 24
1313
targetSdk = 34
14-
versionCode = 1
15-
versionName = "1.0"
14+
versionCode = 2
15+
versionName = "1.1.0"
1616

1717
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
1818

1919
// Golang 库为下列架构
2020
ndk {
2121
abiFilters.add("arm64-v8a")
22+
abiFilters.add("armeabi-v7a")
23+
abiFilters.add("x86_64")
24+
// abiFilters.add("x86") // 暂时不支持
2225
}
2326
}
2427

Diff for: Android/app/release/app-release.apk

7.63 MB
Binary file not shown.
18 Bytes
Binary file not shown.
2 Bytes
Binary file not shown.

Diff for: Android/app/release/output-metadata.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
"type": "SINGLE",
1212
"filters": [],
1313
"attributes": [],
14-
"versionCode": 1,
15-
"versionName": "1.0",
14+
"versionCode": 2,
15+
"versionName": "1.1.0",
1616
"outputFile": "app-release.apk"
1717
}
1818
],

Diff for: Android/app/src/main/AndroidManifest.xml

+4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
xmlns:tools="http://schemas.android.com/tools">
44

55
<uses-permission android:name="android.permission.INTERNET" />
6+
<!-- 安卓 11 开始引入-->
67
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
78
tools:ignore="ScopedStorage" />
9+
<!-- 兼容 安卓 10 之前版本-->
10+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
11+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
812

913
<application
1014
android:requestLegacyExternalStorage="true"

Diff for: Android/app/src/main/cpp/CMakeLists.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ cmake_minimum_required(VERSION 3.22.1)
1111
# build script scope).
1212
project("scut_router")
1313

14+
# 输出正在编译的架构
15+
message(STATUS "ANDROID_ABI: ${ANDROID_ABI}")
1416

1517
# Creates and names a library, sets it as either STATIC
1618
# or SHARED, and provides the relative paths to its source code.
@@ -32,10 +34,9 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
3234

3335
# 注意加上 ${CMAKE_SOURCE_DIR} 环境变量,否则会找不到头文件
3436
set(HEADER_PATH ${CMAKE_SOURCE_DIR}/../../../../../Compatibility/out/)
35-
include_directories(${HEADER_PATH}) # 包含 libSSHCommand.h
3637

3738
# 将库添加到 jniLibs 目录下,保证会自动拷贝到 apk 包
38-
set(Compatibility_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/arm64-v8a)
39+
set(Compatibility_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}) # 跨平台编译
3940
add_library(Compatibility SHARED IMPORTED)
4041
set_property(TARGET Compatibility PROPERTY IMPORTED_NO_SONAME 1)
4142
set_target_properties(Compatibility PROPERTIES IMPORTED_LOCATION ${Compatibility_DIR}/libSSHCommand.so)

Diff for: Android/app/src/main/cpp/native-lib.cpp

+35-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
#include <jni.h>
22
#include <string>
3-
#include "libSSHCommand.h"
3+
4+
// 检测 Android 架构
5+
#if defined(__ANDROID__)
6+
#if defined(__x86__)
7+
#define ARCHITECTURE "x86"
8+
#include "../jniLibs/x86/libSSHCommand.h"
9+
#elif defined(__x86_64__)
10+
#define ARCHITECTURE "x86_64"
11+
#include "../jniLibs/x86_64/libSSHCommand.h"
12+
#elif defined(__arm__)
13+
#define ARCHITECTURE "ARM"
14+
#include "../jniLibs/armeabi-v7a/libSSHCommand.h"
15+
#elif defined(__aarch64__)
16+
#define ARCHITECTURE "ARM64"
17+
#include "../jniLibs/arm64-v8a/libSSHCommand.h"
18+
#else
19+
#define ARCHITECTURE "Unknown Architecture"
20+
#endif
21+
#else
22+
#define ARCHITECTURE "Not an Android Platform"
23+
#endif
424

525
extern "C"
626
JNIEXPORT void JNICALL
@@ -68,12 +88,8 @@ Java_com_example_scut_1router_InternetActivity_setNetwork(JNIEnv *env, jobject t
6888
env->ReleaseStringUTFChars(gateway, gatewayStr);
6989

7090
}
71-
extern "C"
72-
JNIEXPORT void JNICALL
73-
Java_com_example_scut_1router_MainActivity_00024Companion_initLibSSHCommand(JNIEnv *env,
74-
jobject thiz) {
75-
Init();
76-
}
91+
92+
7793

7894
extern "C"
7995
JNIEXPORT void JNICALL
@@ -92,4 +108,16 @@ extern "C"
92108
JNIEXPORT void JNICALL
93109
Java_com_example_scut_1router_LoginActivity_cancelAutoLogin(JNIEnv *env, jobject thiz) {
94110
CancelAutoLogin();
111+
}
112+
extern "C"
113+
JNIEXPORT void JNICALL
114+
Java_com_example_scut_1router_MainActivity_00024Companion_initLibSSHCommand(JNIEnv *env,
115+
jobject thiz,
116+
jstring download_path) {
117+
118+
const char* download_pathStr = env->GetStringUTFChars(download_path, nullptr);
119+
120+
Init((void *)download_pathStr);
121+
122+
env->ReleaseStringUTFChars(download_path, download_pathStr);
95123
}

Diff for: Android/app/src/main/java/com/example/scut_router/MainActivity.kt

+77-2
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
package com.example.scut_router
22

3+
import android.Manifest
34
import android.content.Intent
5+
import android.content.pm.PackageManager
46
import android.net.Uri
7+
import android.os.Build
58
import android.os.Bundle
9+
import android.os.Environment
10+
import android.provider.Settings
11+
import android.widget.Toast
612
import androidx.appcompat.app.AppCompatActivity
13+
import androidx.core.app.ActivityCompat
14+
import androidx.core.content.ContextCompat
715
import com.example.scut_router.databinding.ActivityMainBinding
816

917
class MainActivity : AppCompatActivity() {
1018

1119
private lateinit var binding: ActivityMainBinding
20+
val REQUEST_CODE: Int = 100
1221

1322
override fun onCreate(savedInstanceState: Bundle?) {
1423
super.onCreate(savedInstanceState)
1524

25+
requestPermissions() // 请求文件管理权限
26+
1627
binding = ActivityMainBinding.inflate(layoutInflater)
1728
setContentView(binding.root)
1829

@@ -62,13 +73,77 @@ class MainActivity : AppCompatActivity() {
6273
private external fun destroyLibSSHCommand()
6374

6475
companion object {
65-
private external fun initLibSSHCommand()
76+
private external fun initLibSSHCommand(downloadPath: String)
6677
// Used to load the 'scut_router' library on application startup.
6778
init {
6879
System.loadLibrary("scut_router")
6980
// 初始化 SSH 库
70-
initLibSSHCommand()
81+
val downloadPath : String = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath
82+
initLibSSHCommand(downloadPath)
7183
}
7284

7385
}
86+
87+
/**
88+
* 请求文件读写权限
89+
*/
90+
private fun requestPermissions() {
91+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
92+
// Android 11 及更高版本,检查 MANAGE_EXTERNAL_STORAGE 权限
93+
if (Environment.isExternalStorageManager()) {
94+
// 权限已被授予,可以进行文件操作
95+
Toast.makeText(this, "权限已成功获取,若首次授予请重启应用以正常运行", Toast.LENGTH_SHORT).show()
96+
} else {
97+
// 权限未被授予,提示用户去设置中开启
98+
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
99+
val uri = Uri.fromParts("package", packageName, null)
100+
intent.data = uri
101+
startActivity(intent)
102+
}
103+
} else {
104+
// Android 10 及更低版本,检查 READ 和 WRITE 权限
105+
if (ContextCompat.checkSelfPermission(
106+
this,
107+
Manifest.permission.READ_EXTERNAL_STORAGE
108+
) != PackageManager.PERMISSION_GRANTED ||
109+
ContextCompat.checkSelfPermission(
110+
this,
111+
Manifest.permission.WRITE_EXTERNAL_STORAGE
112+
) != PackageManager.PERMISSION_GRANTED
113+
) {
114+
ActivityCompat.requestPermissions(
115+
this, arrayOf<String>(
116+
Manifest.permission.READ_EXTERNAL_STORAGE,
117+
Manifest.permission.WRITE_EXTERNAL_STORAGE
118+
), REQUEST_CODE
119+
)
120+
}
121+
}
122+
}
123+
124+
override fun onRequestPermissionsResult(requestCode: Int,
125+
permissions: Array<String>, grantResults: IntArray) {
126+
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
127+
when (requestCode) {
128+
REQUEST_CODE -> {
129+
// If request is cancelled, the result arrays are empty.
130+
if ((grantResults.isNotEmpty() &&
131+
grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
132+
// Permission is granted. Continue the action or workflow
133+
// in your app.
134+
Toast.makeText(this, "权限已成功获取,若首次授予请重启应用以正常运行", Toast.LENGTH_SHORT).show()
135+
136+
} else {
137+
Toast.makeText(this, "权限被拒绝,无法正常工作,请重启", Toast.LENGTH_SHORT).show()
138+
}
139+
return
140+
}
141+
142+
// Add other 'when' lines to check for other
143+
// permissions this app might request.
144+
else -> {
145+
// Ignore all other requests.
146+
}
147+
}
148+
}
74149
}
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* Code generated by cmd/cgo; DO NOT EDIT. */
2+
3+
/* package command-line-arguments */
4+
5+
6+
#line 1 "cgo-builtin-export-prolog"
7+
8+
#include <stddef.h>
9+
10+
#ifndef GO_CGO_EXPORT_PROLOGUE_H
11+
#define GO_CGO_EXPORT_PROLOGUE_H
12+
13+
#ifndef GO_CGO_GOSTRING_TYPEDEF
14+
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
15+
#endif
16+
17+
#endif
18+
19+
/* Start of preamble from import "C" comments. */
20+
21+
22+
23+
24+
/* End of preamble from import "C" comments. */
25+
26+
27+
/* Start of boilerplate cgo prologue. */
28+
#line 1 "cgo-gcc-export-header-prolog"
29+
30+
#ifndef GO_CGO_PROLOGUE_H
31+
#define GO_CGO_PROLOGUE_H
32+
33+
typedef signed char GoInt8;
34+
typedef unsigned char GoUint8;
35+
typedef short GoInt16;
36+
typedef unsigned short GoUint16;
37+
typedef int GoInt32;
38+
typedef unsigned int GoUint32;
39+
typedef long long GoInt64;
40+
typedef unsigned long long GoUint64;
41+
typedef GoInt64 GoInt;
42+
typedef GoUint64 GoUint;
43+
typedef size_t GoUintptr;
44+
typedef float GoFloat32;
45+
typedef double GoFloat64;
46+
#ifdef _MSC_VER
47+
#include <complex.h>
48+
typedef _Fcomplex GoComplex64;
49+
typedef _Dcomplex GoComplex128;
50+
#else
51+
typedef float _Complex GoComplex64;
52+
typedef double _Complex GoComplex128;
53+
#endif
54+
55+
/*
56+
static assertion to make sure the file is being used on architecture
57+
at least with matching size of GoInt.
58+
*/
59+
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
60+
61+
#ifndef GO_CGO_GOSTRING_TYPEDEF
62+
typedef _GoString_ GoString;
63+
#endif
64+
typedef void *GoMap;
65+
typedef void *GoChan;
66+
typedef struct { void *t; void *v; } GoInterface;
67+
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
68+
69+
#endif
70+
71+
/* End of boilerplate cgo prologue. */
72+
73+
#ifdef __cplusplus
74+
extern "C" {
75+
#endif
76+
77+
extern void Init(void* downloadPath);
78+
extern void Destroy();
79+
extern void Reboot();
80+
extern void WiredLogin();
81+
extern void WirelessLogin();
82+
extern void SyncTime();
83+
extern void AutoLogin();
84+
extern void CancelAutoLogin();
85+
extern void SetScutInfo(void* username, void* password);
86+
extern void SetAcInfo(void* acIP, void* acName);
87+
extern void SetNetwork(void* ip, void* dnsArr, void* netmask, void* gateway);
88+
89+
#ifdef __cplusplus
90+
}
91+
#endif
80 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)