Skip to content
This repository was archived by the owner on Oct 20, 2023. It is now read-only.

Commit 0c7330c

Browse files
authored
Merge pull request #53 from w4123/master
Compatibility fix for Android 5.0+
2 parents cb84fc1 + c8b5009 commit 0c7330c

File tree

15 files changed

+122
-68
lines changed

15 files changed

+122
-68
lines changed

app/build.gradle

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2+
13
apply plugin: 'com.android.application'
24
apply plugin: 'kotlin-android'
35
apply plugin: 'kotlin-android-extensions'
46
apply plugin: 'kotlin-kapt'
57
apply plugin: 'kotlinx-serialization'
8+
apply plugin: "com.github.johnrengelman.shadow"
69

710

811
def CORE_VERSION = "2.6-M2"
@@ -11,11 +14,11 @@ def LUAMIRAI_VERSION = "2.0.8"
1114

1215
android {
1316
compileSdkVersion 30
14-
buildToolsVersion "29.0.2"
17+
buildToolsVersion "29.0.3"
1518

1619
defaultConfig {
1720
applicationId "io.github.mzdluo123.mirai.android"
18-
minSdkVersion 26
21+
minSdkVersion 21
1922
targetSdkVersion 30
2023
versionCode 45
2124
versionName "3.1.2-dev"
@@ -28,13 +31,14 @@ android {
2831
dataBinding = true
2932
}
3033

34+
3135
buildTypes {
3236
release {
3337
minifyEnabled false
3438
shrinkResources false
3539
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
3640
}
37-
debug{
41+
debug {
3842
minifyEnabled false
3943
shrinkResources false
4044
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
@@ -44,6 +48,8 @@ android {
4448
// To inline the bytecode built with JVM target 1.8 into
4549
// bytecode that is being built with JVM target 1.6. (e.g. navArgs)
4650
compileOptions {
51+
coreLibraryDesugaringEnabled true
52+
4753
sourceCompatibility JavaVersion.VERSION_1_8
4854
targetCompatibility JavaVersion.VERSION_1_8
4955
}
@@ -74,10 +80,13 @@ android {
7480
}
7581

7682

77-
7883
testOptions {
7984
animationsDisabled = true
8085
}
86+
87+
configurations {
88+
nnio
89+
}
8190
}
8291

8392
kotlin.sourceSets.all {
@@ -87,13 +96,21 @@ kotlin.sourceSets.all {
8796
languageSettings.useExperimentalAnnotation("splitties.experimental.ExperimentalSplittiesApi")
8897
}
8998

99+
task nnioJar (type: ShadowJar) {
100+
getArchiveClassifier().set('nnio')
101+
102+
relocate 'org.lukhnos.nnio.file', 'java.nio.file'
103+
relocate 'org.lukhnos.nnio.channels', 'java.nio.channels'
104+
105+
configurations = [project.configurations.nnio]
106+
}
107+
90108
dependencies {
91109
implementation (fileTree(dir: 'libs', include: ['*.jar']))
92-
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
110+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
93111
implementation 'com.google.android.material:material:1.3.0'
94112

95-
//androidx-core-ktx
96-
implementation 'androidx.core:core-ktx:1.3.2'
113+
implementation 'androidx.core:core-ktx:1.5.0-rc01'
97114

98115
//androidx-appcompat
99116
implementation 'androidx.appcompat:appcompat:1.2.0'
@@ -105,14 +122,14 @@ dependencies {
105122
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
106123

107124
//androidx-navigation
108-
implementation 'androidx.navigation:navigation-fragment:2.3.3'
109-
implementation 'androidx.navigation:navigation-ui:2.3.3'
110-
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.3'
111-
implementation 'androidx.navigation:navigation-ui-ktx:2.3.3'
125+
implementation 'androidx.navigation:navigation-fragment:2.3.5'
126+
implementation 'androidx.navigation:navigation-ui:2.3.5'
127+
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
128+
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
112129

113130
//androidx-lifecycle
114-
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0'
115-
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
131+
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
132+
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
116133
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
117134

118135
//androidx-preference
@@ -170,6 +187,8 @@ dependencies {
170187
// fuck!! 他不能在Android平台工作
171188
// implementation 'org.codehaus.groovy:groovy:2.4.6:grooid'
172189

190+
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
191+
173192

174193
debugImplementation 'androidx.fragment:fragment-testing:1.2.4'
175194

@@ -182,6 +201,9 @@ dependencies {
182201
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
183202

184203
// https://mvnrepository.com/artifact/net.mamoe/mirai-console
185-
implementation group: 'net.mamoe', name: 'mirai-console', version: CONSOLE_VERSION
204+
implementation group: 'net.mamoe', name: 'mirai-console', version: CONSOLE_VERSION
205+
206+
nnio 'com.github.rtm516:nnio:c7b291f4ca'
207+
implementation tasks.nnioJar.outputs.files
186208

187209
}

app/src/main/java/io/github/mzdluo123/mirai/android/NotificationFactory.kt

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.Intent
55
import android.graphics.Bitmap
66
import androidx.core.app.NotificationCompat
77
import androidx.core.app.NotificationManagerCompat
8+
import androidx.core.app.NotificationChannelCompat
89
import androidx.core.app.TaskStackBuilder
910
import io.github.mzdluo123.mirai.android.activity.MainActivity
1011
import io.github.mzdluo123.mirai.android.miraiconsole.AndroidLoginSolver
@@ -22,36 +23,31 @@ object NotificationFactory {
2223

2324

2425
internal fun initNotification() {
25-
val notificationManager =
26-
context.getSystemService(Application.NOTIFICATION_SERVICE) as NotificationManager
27-
28-
val statusChannel = NotificationChannel(
29-
SERVICE_NOTIFICATION, "状态通知",
30-
NotificationManager.IMPORTANCE_MIN
31-
)
32-
33-
statusChannel.description = "Mirai正在运行的通知"
34-
35-
val captchaChannel = NotificationChannel(
36-
CAPTCHA_NOTIFICATION, "验证码通知",
37-
NotificationManager.IMPORTANCE_HIGH
38-
)
39-
captchaChannel.description = "登录需要输入验证码时的通知"
40-
41-
val offlineChannel = NotificationChannel(
42-
OFFLINE_NOTIFICATION, "离线通知",
43-
NotificationManager.IMPORTANCE_HIGH
44-
)
45-
offlineChannel.description = "Mirai因各种原因离线的通知"
46-
47-
if (BuildConfig.DEBUG) {
48-
offlineChannel.importance = NotificationManager.IMPORTANCE_MIN
49-
captchaChannel.importance = NotificationManager.IMPORTANCE_MIN
50-
}
26+
val notificationManager = NotificationManagerCompat.from(context)
27+
28+
val statusChannel =
29+
NotificationChannelCompat.Builder(SERVICE_NOTIFICATION, NotificationManagerCompat.IMPORTANCE_MIN)
30+
.setName("状态通知")
31+
.setDescription("Mirai正在运行的通知")
32+
33+
val captchaChannel =
34+
NotificationChannelCompat.Builder(CAPTCHA_NOTIFICATION, NotificationManagerCompat.IMPORTANCE_HIGH)
35+
.setName("验证码通知")
36+
.setDescription("登录需要输入验证码时的通知")
37+
38+
val offlineChannel =
39+
NotificationChannelCompat.Builder(OFFLINE_NOTIFICATION, NotificationManagerCompat.IMPORTANCE_HIGH)
40+
.setName("离线通知")
41+
.setDescription("Mirai因各种原因离线的通知")
42+
43+
if (BuildConfig.DEBUG) {
44+
offlineChannel.setImportance(NotificationManagerCompat.IMPORTANCE_MIN)
45+
captchaChannel.setImportance(NotificationManagerCompat.IMPORTANCE_MIN)
46+
}
5147

52-
notificationManager.createNotificationChannel(statusChannel)
53-
notificationManager.createNotificationChannel(captchaChannel)
54-
notificationManager.createNotificationChannel(offlineChannel)
48+
notificationManager.createNotificationChannel(statusChannel.build())
49+
notificationManager.createNotificationChannel(captchaChannel.build())
50+
notificationManager.createNotificationChannel(offlineChannel.build())
5551

5652
}
5753

app/src/main/java/io/github/mzdluo123/mirai/android/miraiconsole/AndroidMiraiConsole.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import net.mamoe.mirai.utils.BotConfiguration
4040
import net.mamoe.mirai.utils.LoginSolver
4141
import net.mamoe.mirai.utils.MiraiLogger
4242
import java.nio.file.Path
43+
import java.nio.file.Paths
4344

4445
class AndroidMiraiConsole(
4546
val context: Context,
@@ -65,7 +66,7 @@ class AndroidMiraiConsole(
6566

6667

6768
@ConsoleFrontEndImplementation
68-
override val rootPath: Path = context.getExternalFilesDir("")!!.toPath()
69+
override val rootPath: Path = Paths.get(context.getExternalFilesDir("")!!.absolutePath)
6970

7071
@ConsoleFrontEndImplementation
7172
override fun createLogger(identity: String?): MiraiLogger = MiraiAndroidLogger

app/src/main/java/io/github/mzdluo123/mirai/android/miraiconsole/DexPluginClassloader.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.github.mzdluo123.mirai.android.miraiconsole
22

3-
3+
import android.os.Build
44
import dalvik.system.DexClassLoader
55
import net.mamoe.mirai.console.plugin.jvm.ExportManager
66
import java.io.File
@@ -35,7 +35,9 @@ internal class DexPluginClassLoader(
3535
val loadingLock = ConcurrentHashMap<String, Any>()
3636

3737
init {
38-
ClassLoader.registerAsParallelCapable()
38+
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
39+
ClassLoader.registerAsParallelCapable()
40+
}
3941
}
4042
}
4143

app/src/main/java/io/github/mzdluo123/mirai/android/service/BotService.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import net.mamoe.mirai.console.rootDir
4646
import net.mamoe.mirai.event.GlobalEventChannel
4747
import net.mamoe.mirai.event.events.BotOnlineEvent
4848
import net.mamoe.mirai.message.data.At
49+
import java.nio.file.Paths
4950
import kotlin.system.exitProcess
5051

5152
class BotService : LifecycleService() {
@@ -109,7 +110,7 @@ class BotService : LifecycleService() {
109110
@SuppressLint("InvalidWakeLockTag")
110111
override fun onCreate() {
111112
super.onCreate()
112-
consoleFrontEnd = AndroidMiraiConsole(baseContext, getExternalFilesDir("")!!.toPath())
113+
consoleFrontEnd = AndroidMiraiConsole(baseContext, Paths.get(getExternalFilesDir("")!!.absolutePath))
113114

114115
if (AppSettings.waitingDebugger) {
115116
MiraiAndroidLogger.info("等待调试器链接..... PID:${android.os.Process.myPid()}")

app/src/main/java/io/github/mzdluo123/mirai/android/ui/console/ConsoleFragment.kt

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.app.AlertDialog
66
import android.content.Context
77
import android.content.Intent
88
import android.net.Uri
9+
import android.os.Build
910
import android.os.Bundle
1011
import android.os.DeadObjectException
1112
import android.os.PowerManager
@@ -94,7 +95,11 @@ class ConsoleFragment : Fragment() {
9495
override fun newLog(log: String) {
9596
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
9697
log_text.append("\n")
97-
log_text?.append(Html.fromHtml(log, Html.FROM_HTML_MODE_COMPACT))
98+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
99+
log_text?.append(Html.fromHtml(log, Html.FROM_HTML_MODE_COMPACT))
100+
} else {
101+
log_text?.append(Html.fromHtml(log))
102+
}
98103
if (autoScroll) {
99104
delay(20)
100105
main_scroll.fullScroll(ScrollView.FOCUS_DOWN)
@@ -109,7 +114,11 @@ class ConsoleFragment : Fragment() {
109114
lifecycleScope.launch(Dispatchers.Default) {
110115
val text = conn.botService.log.joinToString(separator = "<br>")
111116
withContext(Dispatchers.Main) {
112-
log_text?.text = Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT)
117+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
118+
log_text?.text = Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT)
119+
} else {
120+
log_text?.text = Html.fromHtml(text)
121+
}
113122
if (autoScroll) {
114123
delay(20)
115124
main_scroll.fullScroll(ScrollView.FOCUS_DOWN)
@@ -162,17 +171,19 @@ class ConsoleFragment : Fragment() {
162171

163172
@SuppressLint("BatteryLife")
164173
private fun ignoreBatteryOptimization(activity: Activity) {
165-
val powerManager =
166-
getSystemService(requireContext(), PowerManager::class.java)
167-
// 判断当前APP是否有加入电池优化的白名单,如果没有,弹出加入电池优化的白名单的设置对话框。
174+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
175+
val powerManager =
176+
getSystemService(requireContext(), PowerManager::class.java)
177+
// 判断当前APP是否有加入电池优化的白名单,如果没有,弹出加入电池优化的白名单的设置对话框。
168178

169-
val hasIgnored = powerManager!!.isIgnoringBatteryOptimizations(activity.packageName)
170-
if (!hasIgnored) {
171-
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
172-
intent.data = Uri.parse("package:" + activity.packageName)
173-
startActivity(intent)
174-
} else {
175-
Toast.makeText(context, "您已授权忽略电池优化", Toast.LENGTH_SHORT).show()
179+
val hasIgnored = powerManager!!.isIgnoringBatteryOptimizations(activity.packageName)
180+
if (!hasIgnored) {
181+
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
182+
intent.data = Uri.parse("package:" + activity.packageName)
183+
startActivity(intent)
184+
} else {
185+
Toast.makeText(context, "您已授权忽略电池优化", Toast.LENGTH_SHORT).show()
186+
}
176187
}
177188
}
178189

@@ -184,7 +195,9 @@ class ConsoleFragment : Fragment() {
184195
}
185196
try {
186197
conn.botService.runCmd(command)
187-
command_input.text.clear()
198+
requireActivity().runOnUiThread {
199+
command_input.text.clear()
200+
}
188201
} catch (e: DeadObjectException) {
189202
toast("服务状态异常,请在菜单内点击快速重启")
190203
}

app/src/main/java/io/github/mzdluo123/mirai/android/utils/DexCompiler.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
import com.android.tools.r8.OutputMode;
77

88
import net.lingala.zip4j.ZipFile;
9+
import net.lingala.zip4j.model.FileHeader;
910
import net.lingala.zip4j.exception.ZipException;
1011

12+
1113
import java.io.File;
1214
import java.io.IOException;
1315
import java.util.ArrayList;
16+
import java.util.List;
17+
import java.nio.file.Paths;
1418

1519

1620
public class DexCompiler {
@@ -32,8 +36,8 @@ public File compile(File jarFile, Boolean desugaring) throws CompilationFailedEx
3236
// outFile.createNewFile();
3337
// }
3438
D8Command.Builder command = D8Command.builder()
35-
.addProgramFiles(jarFile.getAbsoluteFile().toPath())
36-
.setOutput(outFile.toPath(), OutputMode.DexIndexed)
39+
.addProgramFiles(Paths.get(jarFile.getAbsolutePath()))
40+
.setOutput(Paths.get(outFile.getAbsolutePath()), OutputMode.DexIndexed)
3741
.setMinApiLevel(26);
3842

3943
if (!desugaring) {
@@ -53,13 +57,15 @@ public void copyResourcesAndMove(File origin, File newFile) throws IOException {
5357
ZipFile originZip = new ZipFile(origin);
5458
ZipFile newZip = new ZipFile(newFile);
5559
ArrayList<File> resources = new ArrayList<>();
56-
originZip.getFileHeaders().forEach(i -> {
60+
List<FileHeader> fileHeaders = originZip.getFileHeaders();
61+
for(FileHeader i : fileHeaders)
62+
{
5763
try {
5864
originZip.extractFile(i, tempDir.getAbsolutePath());
5965
} catch (ZipException e) {
6066
e.printStackTrace();
6167
}
62-
});
68+
}
6369

6470
for (File file : tempDir.listFiles()) {
6571
if (file.isFile() && !file.getName().equals(newFile.getName())) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package java.lang.management;
2+
3+
public class ManagementFactory {
4+
public static MemoryMXBean getMemoryMXBean()
5+
{
6+
return null;
7+
}
8+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package java.lang.management;
2+
3+
public class MemoryMXBean {
4+
}
364 KB
Binary file not shown.
248 KB
Binary file not shown.

app/src/main/jniLibs/x86/liblame.so

364 KB
Binary file not shown.

app/src/main/jniLibs/x86/libsilk.so

248 KB
Binary file not shown.

0 commit comments

Comments
 (0)