├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── compiler.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── kotlinc.xml
├── misc.xml
└── vcs.xml
├── app
├── .gitignore
├── build.gradle.kts
├── libs
│ └── fastjson-1.2.9.jar
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── wx.png
│ └── zfb.jpg
│ ├── ic_launcher_xplan-playstore.png
│ ├── java
│ └── com
│ │ └── itos
│ │ └── xplanforhyper
│ │ ├── CardWidget.kt
│ │ ├── XPlanForHyper.kt
│ │ ├── datatype
│ │ ├── AppInfo.kt
│ │ ├── ConfigData.kt
│ │ └── OriginCardItem.kt
│ │ ├── ui
│ │ ├── Pages
│ │ │ ├── AboutPage.kt
│ │ │ ├── OptPage.kt
│ │ │ └── subassemblies
│ │ │ │ ├── About
│ │ │ │ ├── DiscussWidget.kt
│ │ │ │ ├── DonateWidget.kt
│ │ │ │ ├── OpenSourceWidget.kt
│ │ │ │ └── StatusWidget.kt
│ │ │ │ └── Opt
│ │ │ │ ├── ControlSystemUpdateButton.kt
│ │ │ │ ├── HDButton.kt
│ │ │ │ ├── OptButton.kt
│ │ │ │ ├── ProcessLimitButton.kt
│ │ │ │ └── SettingsOptButton.kt
│ │ └── theme
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ │ └── utils
│ │ ├── NetUtils.java
│ │ ├── OData.kt
│ │ ├── OLog.kt
│ │ ├── OPackage.kt
│ │ ├── OShizuku.kt
│ │ ├── OTarget.kt
│ │ ├── OUI.kt
│ │ └── SpUtils.java
│ └── res
│ ├── drawable
│ ├── ic_alipay.xml
│ ├── ic_baseline_info.xml
│ ├── ic_baseline_terminal.xml
│ ├── ic_bilibili.xml
│ ├── ic_launcher_background.xml
│ ├── ic_launcher_foreground.xml
│ ├── ic_outline_code.xml
│ ├── ic_outline_coolapk.xml
│ ├── ic_outline_giftcard.xml
│ ├── ic_outline_info.xml
│ ├── ic_outline_lisence.xml
│ ├── ic_outline_qq.xml
│ └── ic_wechatpay.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher_xplan.xml
│ └── ic_launcher_xplan_round.xml
│ ├── mipmap-anydpi
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_round.webp
│ ├── ic_launcher_xplan.png
│ ├── ic_launcher_xplan_foreground.png
│ └── ic_launcher_xplan_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_round.webp
│ ├── ic_launcher_xplan.png
│ ├── ic_launcher_xplan_foreground.png
│ └── ic_launcher_xplan_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_round.webp
│ ├── ic_launcher_xplan.png
│ ├── ic_launcher_xplan_foreground.png
│ └── ic_launcher_xplan_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_round.webp
│ ├── ic_launcher_xplan.png
│ ├── ic_launcher_xplan_foreground.png
│ └── ic_launcher_xplan_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_round.webp
│ ├── ic_launcher_xplan.png
│ ├── ic_launcher_xplan_foreground.png
│ └── ic_launcher_xplan_round.png
│ ├── raw
│ ├── licenses
│ ├── moreapp
│ ├── optlist
│ └── pkglist
│ ├── values
│ ├── colors.xml
│ ├── ic_launcher_xplan_background.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── app_config.json
├── app_update.json
├── build.gradle.kts
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # 默认忽略的文件
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | xmlns:android
19 |
20 | ^$
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | xmlns:.*
30 |
31 | ^$
32 |
33 |
34 | BY_NAME
35 |
36 |
37 |
38 |
39 |
40 |
41 | .*:id
42 |
43 | http://schemas.android.com/apk/res/android
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | .*:name
53 |
54 | http://schemas.android.com/apk/res/android
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | name
64 |
65 | ^$
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | style
75 |
76 | ^$
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | .*
86 |
87 | ^$
88 |
89 |
90 | BY_NAME
91 |
92 |
93 |
94 |
95 |
96 |
97 | .*
98 |
99 | http://schemas.android.com/apk/res/android
100 |
101 |
102 | ANDROID_ATTRIBUTE_ORDER
103 |
104 |
105 |
106 |
107 |
108 |
109 | .*
110 |
111 | .*
112 |
113 |
114 | BY_NAME
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | id("org.jetbrains.kotlin.android")
4 | }
5 |
6 | android {
7 | namespace = "com.itos.xplanforhyper"
8 | compileSdk = 34
9 | applicationVariants.all {
10 | outputs.all {
11 | val ver = defaultConfig.versionName+"(${defaultConfig.versionCode})"
12 |
13 | (this as com.android.build.gradle.internal.api.BaseVariantOutputImpl).outputFileName =
14 | "XHpyer_$ver.apk"
15 | }
16 | }
17 | defaultConfig {
18 | applicationId = "com.itos.xplanforhyper"
19 | minSdk = 26
20 | targetSdk = 34
21 | versionCode = 5
22 | versionName = "1.1"
23 |
24 | // testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
25 | vectorDrawables {
26 | useSupportLibrary = true
27 | }
28 |
29 | buildTypes {
30 | release {
31 | isMinifyEnabled = true
32 | proguardFiles(
33 | getDefaultProguardFile("proguard-android-optimize.txt"),
34 | "proguard-rules.pro"
35 | )
36 | }
37 | }
38 | compileOptions {
39 | sourceCompatibility = JavaVersion.VERSION_1_8
40 | targetCompatibility = JavaVersion.VERSION_1_8
41 | }
42 | kotlinOptions {
43 | jvmTarget = "1.8"
44 | }
45 | buildFeatures {
46 | compose = true
47 | aidl=true
48 | buildConfig=true
49 | }
50 | composeOptions {
51 | kotlinCompilerExtensionVersion = "1.4.3"
52 | }
53 | packaging {
54 | resources {
55 | excludes += "/META-INF/{AL2.0,LGPL2.1}"
56 | }
57 | }
58 |
59 | }
60 | buildTypes {
61 | getByName("release") {
62 | isMinifyEnabled = true
63 | }
64 | }
65 | }
66 |
67 | dependencies {
68 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
69 |
70 | implementation("dev.rikka.shizuku:api:13.1.0")
71 | implementation("dev.rikka.shizuku:provider:13.1.0")
72 | implementation("androidx.compose.material3:material3")
73 | implementation("androidx.core:core-ktx:1.12.0")
74 | implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
75 | implementation("androidx.activity:activity-compose:1.8.2")
76 | implementation(platform("androidx.compose:compose-bom:2023.03.00"))
77 | implementation("androidx.compose.ui:ui")
78 | implementation("androidx.compose.ui:ui-graphics")
79 | implementation("androidx.compose.ui:ui-tooling-preview")
80 | implementation("androidx.navigation:navigation-compose:2.7.6")
81 | implementation("androidx.compose.material:material:1.6.0")
82 | implementation("com.google.accompanist:accompanist-drawablepainter:0.20.0")
83 | implementation(files("libs/fastjson-1.2.9.jar"))
84 | implementation("org.lsposed.hiddenapibypass:hiddenapibypass:4.3")
85 | implementation("com.google.android.material:material:1.11.0")
86 | implementation("com.google.accompanist:accompanist-systemuicontroller:0.27.0")
87 | // testImplementation("junit:junit:4.13.2")
88 | // androidTestImplementation("androidx.test.ext:junit:1.1.5")
89 | // androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
90 | // androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
91 | // androidTestImplementation("androidx.compose.ui:ui-test-junit4")
92 | debugImplementation("androidx.compose.ui:ui-tooling")
93 | debugImplementation("androidx.compose.ui:ui-test-manifest")
94 | }
--------------------------------------------------------------------------------
/app/libs/fastjson-1.2.9.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/libs/fastjson-1.2.9.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 | # 指定代码的压缩级别
23 | -optimizationpasses 5
24 |
25 | # 不忽略库中的非public的类成员
26 | -dontskipnonpubliclibraryclassmembers
27 |
28 | # google推荐算法
29 | -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
30 |
31 | # 避免混淆Annotation、内部类、泛型、匿名类
32 | -keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod
33 |
34 | # 抛出异常时保留代码行号
35 | -keepattributes SourceFile,LineNumberTable
36 | -keep class android.content.pm.IPackageManager {
37 | *;
38 | }
39 | -dontwarn java.awt.Color
40 | -dontwarn java.awt.Font
41 | -dontwarn java.awt.Point
42 | -dontwarn java.awt.Rectangle
43 |
44 | # 保持四大组件
45 | -keep public class * extends android.app.Activity
46 | -keep public class * extends android.app.Application
47 | -keep public class * extends android.app.Service
48 | -keep public class * extends android.content.BroadcastReceiver
49 | -keep public class * extends android.content.ContentProvider
50 | -keep public class * extends android.app.backup.BackupAgentHelper
51 | -keep public class * extends android.preference.Preference
52 | -keep public class * extends android.view.View
53 | -keep public class com.android.vending.licensing.ILicensingService
54 |
55 | # 保持support下的所有类及其内部类
56 | -keep class android.support.** {*;}
57 |
58 | # 保留继承的
59 | -keep public class * extends android.support.v4.**
60 | -keep public class * extends android.support.v7.**
61 | -keep public class * extends android.support.annotation.**
62 |
63 | # 保持自定义控件
64 | -keep public class * extends android.view.View{
65 | *** get*();
66 | void set*(***);
67 | public (android.content.Context);
68 | public (android.content.Context, android.util.AttributeSet);
69 | public (android.content.Context, android.util.AttributeSet, int);
70 | }
71 |
72 | # 保持所有实现 Serializable 接口的类成员
73 | -keepclassmembers class * implements java.io.Serializable {
74 | static final long serialVersionUID;
75 | private static final java.io.ObjectStreamField[] serialPersistentFields;
76 | private void writeObject(java.io.ObjectOutputStream);
77 | private void readObject(java.io.ObjectInputStream);
78 | java.lang.Object writeReplace();
79 | java.lang.Object readResolve();
80 | }
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/assets/wx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/assets/wx.png
--------------------------------------------------------------------------------
/app/src/main/assets/zfb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/assets/zfb.jpg
--------------------------------------------------------------------------------
/app/src/main/ic_launcher_xplan-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/ic_launcher_xplan-playstore.png
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/CardWidget.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.foundation.clickable
2 | import androidx.compose.foundation.layout.Arrangement
3 | import androidx.compose.foundation.layout.Box
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.Row
6 | import androidx.compose.foundation.layout.Spacer
7 | import androidx.compose.foundation.layout.fillMaxWidth
8 | import androidx.compose.foundation.layout.padding
9 | import androidx.compose.foundation.layout.size
10 | import androidx.compose.material3.CardColors
11 | import androidx.compose.material3.CardDefaults
12 | import androidx.compose.material3.ElevatedCard
13 | import androidx.compose.material3.Icon
14 | import androidx.compose.material3.LocalContentColor
15 | import androidx.compose.material3.MaterialTheme
16 | import androidx.compose.material3.ProvideTextStyle
17 | import androidx.compose.material3.Text
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.runtime.CompositionLocalProvider
20 | import androidx.compose.ui.Alignment
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.unit.dp
23 | import com.itos.xplanforhyper.datatype.OriginCardItem
24 |
25 | @Composable
26 | fun ItemsCardWidget(
27 | colors: CardColors = CardDefaults.elevatedCardColors(),
28 | onClick: (() -> Unit)? = null,
29 | showItemIcon: Boolean = false,
30 | icon: (@Composable () -> Unit)? = null,
31 | title: (@Composable () -> Unit)? = null,
32 | items: List,
33 | buttons: (@Composable () -> Unit)? = null
34 | ) {
35 | CardWidget(
36 | colors = colors,
37 | onClick = onClick,
38 | icon = icon,
39 | title = title,
40 | content = {
41 | @Composable
42 | fun ItemWidget(item: OriginCardItem) {
43 | Row(
44 | modifier = Modifier
45 | .clickable(enabled = item.onClick != null, onClick = item.onClick ?: {})
46 | .padding(horizontal = 24.dp, vertical = 12.dp),
47 | horizontalArrangement = Arrangement.spacedBy(24.dp)
48 | ) {
49 | if (showItemIcon) {
50 | if (item.icon != null) {
51 | Icon(imageVector = item.icon, contentDescription = item.label)
52 | } else {
53 | Spacer(modifier = Modifier.size(32.dp))
54 | }
55 | }
56 | Column(
57 | modifier = Modifier
58 | .weight(1f)
59 | ) {
60 | Text(text = item.label, style = MaterialTheme.typography.bodyLarge)
61 | if (item.content != null) {
62 | Text(
63 | text = item.content,
64 | style = MaterialTheme.typography.bodyMedium
65 | )
66 | }
67 | }
68 | }
69 | }
70 | Column {
71 | items.forEach {
72 | ItemWidget(it)
73 | }
74 | }
75 | },
76 | buttons = buttons
77 | )
78 | }
79 |
80 | @Composable
81 | fun CardWidget(
82 | colors: CardColors = CardDefaults.elevatedCardColors(),
83 | onClick: (() -> Unit)? = null,
84 | icon: (@Composable () -> Unit)? = null,
85 | title: (@Composable () -> Unit)? = null,
86 | content: (@Composable () -> Unit)? = null,
87 | buttons: (@Composable () -> Unit)? = null
88 | ) {
89 | ElevatedCard(
90 | colors = colors,
91 | elevation = CardDefaults.elevatedCardElevation(defaultElevation = 5.dp)
92 | ) {
93 | Column(
94 | modifier = Modifier
95 | .fillMaxWidth()
96 | .clickable(enabled = onClick != null, onClick = onClick ?: {})
97 | .padding(vertical = 24.dp),
98 | verticalArrangement = Arrangement.spacedBy(4.dp)
99 | ) {
100 | if (icon != null) {
101 | CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.secondary) {
102 | Box(modifier = Modifier.align(Alignment.CenterHorizontally)) {
103 | icon()
104 | }
105 | }
106 | }
107 | if (title != null) {
108 | ProvideTextStyle(value = MaterialTheme.typography.titleLarge) {
109 | Box(modifier = Modifier.align(Alignment.CenterHorizontally)) {
110 | title()
111 | }
112 | }
113 | }
114 | if (content != null) {
115 | Box {
116 | content()
117 | }
118 | }
119 | if (buttons != null) {
120 | Box {
121 | buttons()
122 | }
123 | }
124 | }
125 | }
126 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/XPlanForHyper.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper
2 |
3 | import AboutPage
4 | import android.annotation.SuppressLint
5 | import android.content.ClipData
6 | import android.content.ClipboardManager
7 | import android.content.Context
8 | import android.content.Intent
9 | import android.content.pm.ApplicationInfo
10 | import android.content.pm.PackageManager
11 | import android.content.res.Configuration
12 | import android.net.Uri
13 | import android.os.Build
14 | import android.os.Bundle
15 | import android.text.InputType
16 | import android.widget.EditText
17 | import android.widget.Toast
18 | import androidx.activity.compose.setContent
19 | import androidx.appcompat.app.AppCompatActivity
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.background
22 | import androidx.compose.foundation.layout.Arrangement
23 | import androidx.compose.foundation.layout.Column
24 | import androidx.compose.foundation.layout.Row
25 | import androidx.compose.foundation.layout.fillMaxSize
26 | import androidx.compose.foundation.layout.fillMaxWidth
27 | import androidx.compose.foundation.layout.padding
28 | import androidx.compose.foundation.layout.size
29 | import androidx.compose.foundation.lazy.LazyColumn
30 | import androidx.compose.foundation.lazy.items
31 | import androidx.compose.material.icons.Icons
32 | import androidx.compose.material.icons.filled.Check
33 | import androidx.compose.material.icons.filled.Close
34 | import androidx.compose.material.icons.filled.Create
35 | import androidx.compose.material.icons.filled.Delete
36 | import androidx.compose.material.icons.filled.Info
37 | import androidx.compose.material.icons.filled.MoreVert
38 | import androidx.compose.material.icons.filled.Refresh
39 | import androidx.compose.material.icons.filled.Settings
40 | import androidx.compose.material.icons.filled.Warning
41 | import androidx.compose.material.icons.outlined.Create
42 | import androidx.compose.material.icons.outlined.Info
43 | import androidx.compose.material.icons.outlined.Settings
44 | import androidx.compose.material3.DropdownMenu
45 | import androidx.compose.material3.DropdownMenuItem
46 | import androidx.compose.material3.ExperimentalMaterial3Api
47 | import androidx.compose.material3.Icon
48 | import androidx.compose.material3.IconButton
49 | import androidx.compose.material3.LocalContentColor
50 | import androidx.compose.material3.MaterialTheme
51 | import androidx.compose.material3.NavigationBar
52 | import androidx.compose.material3.NavigationBarItem
53 | import androidx.compose.material3.Scaffold
54 | import androidx.compose.material3.Surface
55 | import androidx.compose.material3.Text
56 | import androidx.compose.material3.TopAppBar
57 | import androidx.compose.runtime.Composable
58 | import androidx.compose.runtime.MutableState
59 | import androidx.compose.runtime.RecomposeScope
60 | import androidx.compose.runtime.currentRecomposeScope
61 | import androidx.compose.runtime.getValue
62 | import androidx.compose.runtime.mutableStateOf
63 | import androidx.compose.runtime.remember
64 | import androidx.compose.runtime.setValue
65 | import androidx.compose.ui.Alignment
66 | import androidx.compose.ui.Modifier
67 | import androidx.compose.ui.graphics.Color
68 | import androidx.compose.ui.graphics.vector.ImageVector
69 | import androidx.compose.ui.platform.LocalContext
70 | import androidx.compose.ui.res.vectorResource
71 | import androidx.compose.ui.tooling.preview.Preview
72 | import androidx.compose.ui.unit.dp
73 | import androidx.core.content.getSystemService
74 | import androidx.lifecycle.lifecycleScope
75 | import androidx.navigation.compose.NavHost
76 | import androidx.navigation.compose.composable
77 | import androidx.navigation.compose.currentBackStackEntryAsState
78 | import androidx.navigation.compose.rememberNavController
79 | import com.alibaba.fastjson.JSONObject
80 | import com.google.accompanist.drawablepainter.rememberDrawablePainter
81 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
82 | import com.google.android.material.textview.MaterialTextView
83 | import com.itos.xplanforhyper.datatype.AppInfo
84 | import com.itos.xplanforhyper.ui.theme.OriginPlanTheme
85 | import com.itos.xplanforhyper.utils.NetUtils
86 | import com.itos.xplanforhyper.utils.OData
87 | import com.itos.xplanforhyper.utils.OLog
88 | import com.itos.xplanforhyper.utils.OPackage
89 | import com.itos.xplanforhyper.utils.OPackage.getAppIconByPackageName
90 | import com.itos.xplanforhyper.utils.OShizuku
91 | import com.itos.xplanforhyper.utils.OShizuku.checkShizuku
92 | import com.itos.xplanforhyper.utils.OUI
93 | import com.itos.xplanforhyper.utils.SpUtils
94 | import kotlinx.coroutines.CoroutineExceptionHandler
95 | import kotlinx.coroutines.Dispatchers
96 | import kotlinx.coroutines.launch
97 | import kotlinx.coroutines.withContext
98 | import rikka.shizuku.Shizuku
99 | import rikka.shizuku.Shizuku.OnBinderReceivedListener
100 | import rikka.shizuku.ShizukuRemoteProcess
101 | import java.io.BufferedReader
102 | import java.io.InputStreamReader
103 | import java.io.OutputStream
104 |
105 | // TODO 拆Details页面
106 |
107 | class XPlanForHyper : AppCompatActivity() {
108 | val context: Context = this
109 | var ReturnValue = 0
110 | var br = false
111 | var h2: Thread? = null
112 | var h3: Thread? = null
113 | var b = true
114 | var c = false
115 | var show_notice: String = "暂无公告"
116 |
117 | // private var FirstTime_pf: SharedPreferences? = null
118 | private val pkglist = mutableListOf()
119 | val optlist = mutableListOf()
120 |
121 | private val requestPermissionResultListener =
122 | Shizuku.OnRequestPermissionResultListener { requestCode: Int, grantResult: Int ->
123 | this.onRequestPermissionsResult()
124 | }
125 | private val BINDER_RECEVIED_LISTENER =
126 | OnBinderReceivedListener {
127 | checkShizuku()
128 | }
129 | private val BINDER_DEAD_LISTENER: Shizuku.OnBinderDeadListener =
130 | Shizuku.OnBinderDeadListener {
131 | checkShizuku()
132 | }
133 |
134 | override fun onCreate(savedInstanceState: Bundle?) {
135 | super.onCreate(savedInstanceState)
136 | setContent {
137 | OriginPlanTheme {
138 | // A surface container using the 'background' color from the theme
139 | Surface(
140 | modifier = Modifier.fillMaxSize(),
141 | color = MaterialTheme.colorScheme.background
142 | ) {
143 | AppListContent()
144 | }
145 | }
146 | }
147 | load_applist()
148 | app = this
149 |
150 | Shizuku.addRequestPermissionResultListener(requestPermissionResultListener)
151 | // 3是a13,2是a12(service call),1是pm增强,0是pm
152 | when (Build.VERSION.SDK_INT) {
153 | Build.VERSION_CODES.TIRAMISU -> {
154 | SpUtils.setParam(context, "method", 3)
155 | }
156 |
157 | Build.VERSION_CODES.S, Build.VERSION_CODES.S_V2 -> {
158 | SpUtils.setParam(context, "method", 2)
159 | }
160 |
161 | else -> {
162 | SpUtils.setParam(context, "method", 1)
163 | }
164 | }
165 | checkShizuku()
166 | OUI.check_secure_premission()
167 | Shizuku.addBinderReceivedListenerSticky(BINDER_RECEVIED_LISTENER)
168 | Shizuku.addBinderDeadListener(BINDER_DEAD_LISTENER)
169 | guide()
170 | generateAppList(context)
171 | update_notice()
172 | }
173 |
174 | private fun load_applist() {
175 | lifecycleScope.launch(Dispatchers.IO) {
176 | try {
177 | // 打开 pkglistfile 文件输入流
178 | val inputStream_pkg = resources.openRawResource(R.raw.pkglist)
179 | val reader_pkg = BufferedReader(InputStreamReader(inputStream_pkg))
180 | val inputStream_opt = resources.openRawResource(R.raw.optlist)
181 | val reader_opt = BufferedReader(InputStreamReader(inputStream_opt))
182 |
183 | // 逐行读取文件内容
184 | var line_pkg: String?
185 | var line_opt: String?
186 | while (reader_pkg.readLine().also { line_pkg = it } != null) {
187 | val packageName = line_pkg!!.trim()
188 | // 创建 AppInfo 对象,并添加到列表
189 | val appInfo = AppInfo(appName = "", appPkg = packageName)
190 | pkglist.add(appInfo)
191 | }
192 | while (reader_opt.readLine().also { line_opt = it } != null) {
193 | val packageName = line_opt!!.trim()
194 | // 创建 AppInfo 对象,并添加到列表
195 | val appInfo = AppInfo(appName = "", appPkg = packageName)
196 | optlist.add(appInfo)
197 | }
198 | } catch (_: Exception) {
199 | }
200 | }
201 |
202 | }
203 |
204 | private fun guide() {
205 | if (SpUtils.getParam(context, "if_first_time", true) as Boolean) {
206 | MaterialAlertDialogBuilder(context)
207 | .setTitle("帮助")
208 | .setMessage("您需要Shiuzku激活教程吗")
209 | .setPositiveButton("好的") { dialog, which ->
210 | SpUtils.setParam(context, "if_first_time", false)
211 | OUI.openLink("https://www.bilibili.com/video/BV1o94y1u7Kq")
212 | }
213 | .setNegativeButton("我会") { dialog, which ->
214 | SpUtils.setParam(context, "if_first_time", false)
215 | dialog.dismiss()
216 | }
217 | .show()
218 | .setCancelable(false)
219 | }
220 | }
221 |
222 | private fun update_notice() {
223 | val handler = CoroutineExceptionHandler { _, exception ->
224 | // 在这里处理异常,例如打印日志、上报异常等
225 | OLog.e("Update Notice Exception:", exception)
226 | MaterialAlertDialogBuilder(context)
227 | .setTitle("错误")
228 | .setMessage("连接服务器失败\n请检查网络连接")
229 | .setPositiveButton("了解", null)
230 | .show()
231 | }
232 | lifecycleScope.launch(Dispatchers.IO + handler) {
233 | // 后台工作
234 | val update = NetUtils.Get(OData.updataUrl)
235 | // 切换到主线程进行 UI 操作
236 | withContext(Dispatchers.Main) {
237 | // UI 操作,例如显示 Toast
238 | val jsonObject = JSONObject.parseObject(update)
239 | val version = jsonObject.getString("version")
240 | val url = jsonObject.getString("url")
241 | val version_name = jsonObject.getString("version_name")
242 | val log = jsonObject.getString("log")
243 | val isShowNotice = jsonObject.getBoolean("isShowNotice")
244 | val notice = jsonObject.getString("notice")
245 | show_notice = notice
246 | OLog.i(
247 | "更新",
248 | update + "\n" + version + "\n" + url + "\n" + version_name + "\n" + log + "\n" + isShowNotice + "\n" + notice
249 | )
250 | if (BuildConfig.VERSION_CODE < version.toInt()) {
251 | OLog.i("更新", "有新版本")
252 | MaterialAlertDialogBuilder(context)
253 | .setTitle("有新版本")
254 | .setMessage("最新版本:$version_name($version)\n\n更新日志:\n$log")
255 | .setPositiveButton("前往更新") { dialog, which ->
256 | OUI.openLink(url)
257 | finish()
258 | }
259 | .setCancelable(false)
260 | .show()
261 | } else {
262 | if (isShowNotice) {
263 | OLog.i("公告", "显示")
264 | MaterialAlertDialogBuilder(context)
265 | .setTitle("公告")
266 | .setMessage(notice)
267 | .setPositiveButton("我知道了") { dialog, which ->
268 | dialog.dismiss()
269 | }
270 | .show()
271 | }
272 | }
273 |
274 | }
275 | }
276 | }
277 |
278 |
279 | private fun onRequestPermissionsResult() {
280 | checkShizuku()
281 | }
282 |
283 | override fun onDestroy() {
284 | super.onDestroy()
285 | Shizuku.removeBinderReceivedListener(BINDER_RECEVIED_LISTENER)
286 | Shizuku.removeBinderDeadListener(BINDER_DEAD_LISTENER)
287 | Shizuku.removeRequestPermissionResultListener(requestPermissionResultListener)
288 | }
289 |
290 | private fun uninstall(appInfo: AppInfo, a: RecomposeScope) {
291 |
292 | MaterialAlertDialogBuilder(context)
293 | .setTitle("尝试卸载")
294 | .setMessage("您将卸载 ${appInfo.appName}(${appInfo.appPkg})")
295 | .setPositiveButton("确定") { _, _ ->
296 | val t: String? = when (SpUtils.getParam(context, "method", 1)) {
297 | 3 -> {
298 | ShizukuExec("service call package 131 s16 ${appInfo.appPkg} i32 0 i32 0".toByteArray())
299 | }
300 |
301 | 2 -> {
302 | ShizukuExec("service call package 134 s16 ${appInfo.appPkg} i32 0 i32 0".toByteArray())
303 | }
304 |
305 | 1 -> {
306 | ShizukuExec("pm uninstall --user 0 ${appInfo.appPkg}".toByteArray())
307 | }
308 |
309 | else -> {
310 | ShizukuExec("pm uninstall ${appInfo.appPkg}".toByteArray())
311 | }
312 | }
313 | MaterialAlertDialogBuilder(context)
314 | .setTitle("结果")
315 | .setMessage(t)
316 | .setPositiveButton("ok") { _, _ ->
317 | appInfo.isExist =
318 | OPackage.isInstalled(appInfo.appPkg, context.packageManager)
319 | appInfo.appName = getAppNameByPackageName(context, appInfo.appPkg)
320 | appInfo.appIcon =
321 | getAppIconByPackageName(appInfo.appPkg, context.packageManager)
322 | a.invalidate()
323 | }
324 | .show()
325 | }
326 | .setNegativeButton("取消") { _, _ -> }
327 | .show()
328 | }
329 |
330 | private fun reinstall(appInfo: AppInfo, a: RecomposeScope) {
331 | MaterialAlertDialogBuilder(context)
332 | .setTitle("尝试重装")
333 | .setMessage("您将尝试重装 ${appInfo.appPkg} ,此操作仅系统自带核心app可用")
334 | .setPositiveButton("确定") { _, _ ->
335 | Toast.makeText(context, "请稍等...", Toast.LENGTH_LONG).show()
336 | val t: String? = when (SpUtils.getParam(context, "method", 1)) {
337 | 3 -> {
338 | ShizukuExec("service call package 131 s16 ${appInfo.appPkg} i32 1 i32 0".toByteArray())
339 | }
340 |
341 | 2 -> {
342 | ShizukuExec("service call package 134 s16 ${appInfo.appPkg} i32 1 i32 0".toByteArray())
343 | }
344 |
345 | else -> {
346 | ShizukuExec("pm install-existing ${appInfo.appPkg}".toByteArray())
347 | }
348 | }
349 | MaterialAlertDialogBuilder(context)
350 | .setTitle("结果")
351 | .setMessage(t)
352 | .setPositiveButton("ok") { _, _ ->
353 | //重载页面
354 | appInfo.isExist =
355 | OPackage.isInstalled(appInfo.appPkg, context.packageManager)
356 | if (appInfo.isExist) {
357 | appInfo.isDisabled = isAppDisabled(appInfo.appPkg)
358 | appInfo.appName = getAppNameByPackageName(context, appInfo.appPkg)
359 | appInfo.appIcon =
360 | getAppIconByPackageName(appInfo.appPkg, context.packageManager)
361 | a.invalidate()
362 | }
363 | }
364 | .show()
365 | }
366 | .setNegativeButton("取消") { _, _ -> }
367 | .show()
368 |
369 | }
370 |
371 | fun patchProcessLimit() {
372 | MaterialAlertDialogBuilder(app)
373 | .setTitle("关闭缓存进程和虚进程数量限制")
374 | .setMessage("该操作可能导致卡米,您确定要进行吗?")
375 | .setPositiveButton("确定") { _, _ ->
376 | Toast.makeText(context, "请稍等...", Toast.LENGTH_LONG).show()
377 | ShizukuExec("device_config set_sync_disabled_for_tests persistent;device_config put activity_manager max_cached_processes 2007;device_config put activity_manager max_phantom_processes 2007;echo success".toByteArray())
378 | MaterialAlertDialogBuilder(context)
379 | .setTitle("关闭缓存进程和虚进程数量限制")
380 | .setMessage("调整完成,是否立即重启")
381 | .setPositiveButton("立即重启") { _, _ ->
382 | ShizukuExec("reboot".toByteArray())
383 | }
384 | .setNegativeButton("暂不重启") { _, _ -> }
385 | .show()
386 | }
387 | .setNegativeButton("取消",null)
388 | .show()
389 | }
390 |
391 | fun unpatchProcessLimit() {
392 | Toast.makeText(context, "请稍等...", Toast.LENGTH_LONG).show()
393 | ShizukuExec("device_config set_sync_disabled_for_tests none;device_config put activity_manager max_cached_processes 32;device_config put activity_manager max_phantom_processes 32".toByteArray())
394 | MaterialAlertDialogBuilder(context)
395 | .setTitle("还原缓存进程和虚进程数量限制")
396 | .setMessage("还原完成,是否立即重启")
397 | .setPositiveButton("立即重启") { _, _ ->
398 | ShizukuExec("reboot".toByteArray())
399 | }
400 | .setNegativeButton("暂不重启") { _, _ -> }
401 | .show()
402 | }
403 |
404 | fun ShizukuExec(cmd: ByteArray): String? {
405 | if (br) {
406 | return "正在执行其他操作"
407 | }
408 | if (!b || !c) {
409 | Toast.makeText(context, "Shizuku 状态异常", Toast.LENGTH_SHORT).show()
410 | return "Shizuku 状态异常"
411 | }
412 | br = true
413 |
414 | val p: ShizukuRemoteProcess
415 | val op = arrayOfNulls(1)
416 | try {
417 | OLog.i("运行shell", "开始运行$cmd")
418 | p = Shizuku.newProcess(arrayOf("sh"), null, null)
419 | val out: OutputStream = p.outputStream
420 | out.write(cmd)
421 | out.flush()
422 | out.close()
423 | h2 = Thread {
424 | try {
425 | val outText = StringBuilder()
426 | val reader = BufferedReader(InputStreamReader(p.inputStream))
427 | var line: String?
428 | while (reader.readLine().also { line = it } != null) {
429 | outText.append(line).append("\n")
430 | }
431 | reader.close()
432 | val output = outText.toString()
433 | OLog.i("运行shell", "Output_Normal:\n$output")
434 | op[0] = output
435 | } catch (ignored: java.lang.Exception) {
436 | }
437 | }
438 | h2!!.start()
439 | h3 = Thread {
440 | try {
441 | val outText = StringBuilder()
442 | val reader = BufferedReader(InputStreamReader(p.getErrorStream()))
443 | var line: String?
444 | while (reader.readLine().also { line = it } != null) {
445 | outText.append(line).append("\n")
446 | }
447 | reader.close()
448 | val output = outText.toString()
449 | op[0] += output
450 | OLog.i("运行shell", "Output_Error:\n$output")
451 | } catch (ignored: java.lang.Exception) {
452 | }
453 | }
454 | h3!!.start()
455 |
456 | p.waitFor()
457 | h2!!.join()
458 | ReturnValue = p.exitValue()
459 | OLog.i("运行shell", "跑完了")
460 | p.destroyForcibly()
461 | br = false
462 |
463 | return op[0]
464 | } catch (ignored: java.lang.Exception) {
465 | }
466 | return "null"
467 | }
468 |
469 | fun SetAppDisabled(
470 | isDisabled: MutableState,
471 | packagename: String,
472 | isExist: Boolean,
473 | isShowToast: Boolean = true,
474 | appinfolist: MutableState? = null
475 | ): Boolean? {
476 | if (isExist) {
477 | OShizuku.setAppDisabled(packagename, !isDisabled.value)
478 | val c = isAppDisabled(packagename)
479 | if (c != isDisabled.value) {
480 | if (appinfolist != null) appinfolist.value.isDisabled = c
481 | isDisabled.value = c
482 | return true
483 | } else {
484 | if (isShowToast) {
485 | Toast.makeText(this, "设置失败", Toast.LENGTH_SHORT).show()
486 | }
487 | return false
488 | }
489 | } else {
490 | Toast.makeText(this, "应用未安装", Toast.LENGTH_SHORT).show()
491 | return null
492 | }
493 | }
494 |
495 |
496 | private fun getAppNameByPackageName(context: Context, packageName: String): String {
497 | val packageManager: PackageManager = context.packageManager
498 | val applicationInfo: ApplicationInfo? = try {
499 | packageManager.getApplicationInfo(packageName, 0)
500 | } catch (e: PackageManager.NameNotFoundException) {
501 | null
502 | }
503 |
504 | return applicationInfo?.let {
505 | packageManager.getApplicationLabel(it).toString()
506 | } ?: "未安装"
507 | }
508 |
509 |
510 | /****************
511 | *
512 | * 发起添加群流程。群号:IQOO⭐️交流群(262040855) 的 key 为: SqLJvDGqjKNDvc_O5dx6A164eLSo4QBG
513 | * 调用 joinQQGroup(SqLJvDGqjKNDvc_O5dx6A164eLSo4QBG) 即可发起手Q客户端申请加群 IQOO⭐️交流群(262040855)
514 | *
515 | * @param key 由官网生成的key
516 | * @return 返回true表示呼起手Q成功,返回false表示呼起失败
517 | */
518 | private fun joinQQGroup(key: String): Boolean {
519 | val intent = Intent()
520 | intent.data =
521 | Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26jump_from%3Dwebapi%26k%3D$key")
522 | // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面
523 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
524 | return try {
525 | startActivity(intent)
526 | true
527 | } catch (e: java.lang.Exception) {
528 | // 未安装手Q或安装的版本不支持
529 | false
530 | }
531 | }
532 |
533 | private fun join_qq() {
534 | val is_join_succeed = joinQQGroup("SqLJvDGqjKNDvc_O5dx6A164eLSo4QBG")
535 | if (!is_join_succeed) {
536 | Toast.makeText(
537 | this,
538 | "未安装手Q或安装的版本不支持, 请手动加群262040855",
539 | Toast.LENGTH_LONG
540 | ).show()
541 | }
542 | }
543 |
544 | fun isAppDisabled(appPackageName: String): Boolean {
545 | val packageManager: PackageManager = context.packageManager
546 |
547 | val packageInfo = packageManager.getPackageInfo(appPackageName, 0)
548 | // 应用被停用或者处于默认状态(未设置启用状态),返回 true;其他状态返回 false
549 | return !packageInfo.applicationInfo.enabled
550 | }
551 |
552 |
553 | @Composable
554 | fun AppListItem(appinfo: AppInfo) {
555 | //让 compose监听这个的变化
556 | var appInfo = remember { mutableStateOf(appinfo) }
557 | val isDisabled = remember { mutableStateOf(appInfo.value.isDisabled) }
558 | // val appinfo_remember=remember{ mutableStateOf(appInfo) }
559 | // val refreshing = remember { mutableStateOf(false) }
560 | var isMenuVisible by remember { mutableStateOf(false) }
561 | val recompose = currentRecomposeScope
562 |
563 | Row(
564 | modifier = Modifier
565 | .fillMaxWidth()
566 | .padding(16.dp),
567 | horizontalArrangement = Arrangement.spacedBy(16.dp),
568 | verticalAlignment = Alignment.CenterVertically
569 | ) {
570 | // OLog.i("重绘", "触发重绘")
571 |
572 | if (appInfo.value.appIcon != null) {
573 | Image(
574 | painter = rememberDrawablePainter(appInfo.value.appIcon),
575 | modifier = Modifier
576 | .size(40.dp)
577 | .align(Alignment.CenterVertically),
578 | contentDescription = null
579 | )
580 | }
581 | // 左边显示应用名称
582 | Column(modifier = Modifier.weight(0.5f)) {
583 | Text(
584 | text = appInfo.value.appName,
585 | style = MaterialTheme.typography.bodyMedium,
586 | color = if (!appInfo.value.isExist) Color(0xFFFF6E40) else LocalContentColor.current
587 | )
588 | Text(text = appInfo.value.appPkg, style = MaterialTheme.typography.bodySmall)
589 | }
590 |
591 | // 中间显示禁用状态文本
592 | Text(
593 | text = if (!appInfo.value.isExist) "Unknown" else if (isDisabled.value) "Disable" else "Enable",
594 | color = if (!appInfo.value.isExist) Color(0xFFFF6E40)
595 | else if (isDisabled.value) Color(0xFFFF5252)
596 | else Color(0xFF59F0A6),
597 | style = MaterialTheme.typography.bodyMedium,
598 | modifier = Modifier.padding(end = 16.dp)
599 | )
600 | // 右边是一个按钮
601 | IconButton(
602 | onClick = {
603 | SetAppDisabled(
604 | isDisabled,
605 | appInfo.value.appPkg,
606 | appInfo.value.isExist,
607 | true,
608 | appInfo
609 | )
610 | }
611 | ) {
612 |
613 | val icon: ImageVector = if (appInfo.value.isExist && isDisabled.value) {
614 | Icons.Default.Check
615 | } else if (appInfo.value.isExist) {
616 | Icons.Default.Close
617 | } else {
618 | Icons.Default.Warning
619 | }
620 | Icon(
621 | imageVector = icon,
622 |
623 | contentDescription = if (!appInfo.value.isExist) "Unknown" else if (isDisabled.value) "Disable" else "Enable"
624 | )
625 | }
626 | IconButton(
627 | onClick = { isMenuVisible = true }
628 | ) {
629 |
630 | Icon(
631 | imageVector = Icons.Default.MoreVert,
632 | contentDescription = "More"
633 | )
634 | DropdownMenu(
635 | expanded = isMenuVisible,
636 | onDismissRequest = { isMenuVisible = false },
637 | modifier = Modifier.background(MaterialTheme.colorScheme.surface)
638 | ) {
639 | DropdownMenuItem(
640 | leadingIcon = {
641 | Icon(
642 | imageVector = Icons.Default.Delete,
643 | contentDescription = "uninstall"
644 | )
645 | },
646 | text = { Text(text = "尝试卸载") },
647 | onClick = {
648 | isMenuVisible = false;uninstall(
649 | appInfo.value,
650 | recompose
651 | )
652 | }
653 | // 处理菜单项点击事件,这里可以添加卸载逻辑
654 | )
655 | DropdownMenuItem(
656 | leadingIcon = {
657 | Icon(
658 | imageVector = Icons.Default.Refresh,
659 | contentDescription = "uninstall"
660 | )
661 | }, text = { Text(text = "尝试重装") }, onClick = {
662 | // ...
663 | isMenuVisible = false
664 | reinstall(appInfo.value, recompose)
665 | })
666 | }
667 | }
668 |
669 | }
670 |
671 | }
672 |
673 |
674 | @Composable
675 | fun AppList(appList: List) {
676 | LazyColumn(
677 | verticalArrangement = Arrangement.spacedBy(8.dp),
678 | modifier = Modifier.fillMaxSize()
679 | ) {
680 | items(optlist + appList) { appInfo ->
681 | AppListItem(appInfo)
682 | }
683 | }
684 |
685 | }
686 |
687 | private fun copyText(text: String) = getSystemService()
688 | ?.setPrimaryClip(ClipData.newPlainText(getString(R.string.app_name), text))
689 |
690 | private suspend fun onTerminalResult(exitValue: Int, msg: String?) =
691 | withContext(Dispatchers.Main) {
692 | if (exitValue == 0 && msg.isNullOrBlank()) return@withContext
693 | MaterialAlertDialogBuilder(context).apply {
694 | if (!msg.isNullOrBlank()) {
695 | if (exitValue != 0) {
696 | setTitle(getString(R.string.operation_failed, exitValue.toString()))
697 | } else {
698 | setTitle("结果")
699 | }
700 | setMessage(msg)
701 | setNeutralButton(android.R.string.copy) { _, _ -> copyText(msg) }
702 | } else if (exitValue != 0) {
703 | setMessage(getString(R.string.operation_failed, exitValue.toString()))
704 | }
705 | }.setPositiveButton(android.R.string.ok, null).show()
706 | .findViewById(android.R.id.message)
707 | ?.setTextIsSelectable(true)
708 | }
709 |
710 | @OptIn(ExperimentalMaterial3Api::class)
711 | @Composable
712 | fun Details() {
713 | generateAppList(context)
714 |
715 | Column {
716 | //val appList = remember { generateAppList(context) }
717 | // TopAppBar
718 | TopAppBar(title = { Text(text = "XHyper") },
719 | actions = {
720 | IconButton(onClick = {
721 | val inputEditText = EditText(context)
722 | inputEditText.hint = "Terminal"
723 | inputEditText.inputType = InputType.TYPE_CLASS_TEXT
724 |
725 | MaterialAlertDialogBuilder(context)
726 | .setTitle("终端")
727 | .setView(inputEditText)
728 | .setPositiveButton(android.R.string.ok) { _, _ ->
729 | lifecycleScope.launch {
730 | val result =
731 | ShizukuExec(inputEditText.text.toString().toByteArray())
732 | OLog.i("终端结果:", result!!)
733 | onTerminalResult(ReturnValue, result)
734 | }
735 | }
736 | .setNegativeButton(android.R.string.cancel, null)
737 | .show()
738 |
739 | }) {
740 | Icon(
741 | imageVector = ImageVector.Companion.vectorResource(R.drawable.ic_baseline_terminal),
742 | contentDescription = "terminal"
743 | )
744 | }
745 | IconButton(
746 | onClick = {
747 | val options = arrayOf(
748 | "pm命令",
749 | "pm命令(增强)",
750 | "service call(Android 12)",
751 | "service call(Android 13)"
752 | )
753 | var selectedItem = SpUtils.getParam(context, "method", 1) as Int
754 | Toast.makeText(
755 | context,
756 | "设置卸载、重装操作的实现方案\nservice call一般可以卸载更多app",
757 | Toast.LENGTH_SHORT
758 | ).show()
759 | MaterialAlertDialogBuilder(context)
760 | .setTitle("设置方案")
761 | .setSingleChoiceItems(options, selectedItem) { _, which ->
762 | // 设置选中状态
763 | selectedItem = which
764 | }
765 | .setPositiveButton("确定") { _, _ ->
766 | // 处理确定按钮点击事件,可以根据 selectedItem 执行相应逻辑
767 | if (selectedItem != -1) {
768 | when (selectedItem) {
769 | 0 -> {
770 | // 选择了 "pm命令"
771 | SpUtils.setParam(context, "method", 0)
772 | }
773 |
774 | 1 -> {
775 | // 选择了 "pm命令"
776 | SpUtils.setParam(context, "method", 1)
777 | }
778 |
779 | 2 -> {
780 | // 选择了 "service call(Android 12)"
781 | SpUtils.setParam(context, "method", 2)
782 | }
783 |
784 | 3 -> {
785 | // 选择了 "service call(Android 13)"
786 | SpUtils.setParam(context, "method", 3)
787 | }
788 | }
789 | }
790 | }
791 | .setNegativeButton("取消") { dialog, _ ->
792 | // 处理取消按钮点击事件
793 | dialog.dismiss()
794 | }
795 | .show()
796 | }
797 | ) {
798 | Icon(
799 | imageVector = Icons.Outlined.Settings,
800 | contentDescription = "settings"
801 | )
802 | }
803 | })
804 | // AppList
805 | AppList(appList = pkglist)
806 | }
807 | }
808 |
809 | @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
810 | @OptIn(ExperimentalMaterial3Api::class)
811 | @Composable
812 | fun AppListScreen(context: Context) {
813 | val navController = rememberNavController()
814 | Scaffold(
815 | //设置底部导航栏
816 | bottomBar = {
817 | NavigationBar {
818 | val navBackStackEntry by navController.currentBackStackEntryAsState()
819 | val currentDestination = navBackStackEntry?.destination
820 | NavigationBarItem(
821 |
822 | icon = {
823 | when (currentDestination?.route) {
824 | "1" -> {
825 | // 选中时的图标
826 | Icon(Icons.Filled.Settings, contentDescription = null)
827 | }
828 |
829 | else -> {
830 | // 未选中时的图标
831 | Icon(Icons.Outlined.Settings, contentDescription = null)
832 | }
833 | }
834 | },
835 | label = {
836 | Text(
837 | text = "Optimization"
838 | // modifier = Modifier.alpha(if (currentDestination?.route == "Details") 1f else 0f)
839 | )
840 | },
841 | selected = currentDestination?.route == "1",
842 | alwaysShowLabel = false,
843 | onClick = {
844 | navController.navigate("1") {
845 | popUpTo(navController.graph.startDestinationId) {
846 | saveState = true
847 | }
848 | launchSingleTop = true
849 | restoreState = true
850 | }
851 | }
852 | )
853 | NavigationBarItem(
854 | icon = {
855 | when (currentDestination?.route) {
856 | "2" -> {
857 | // 选中时的图标
858 | Icon(Icons.Filled.Create, contentDescription = null)
859 | }
860 |
861 | else -> {
862 | // 未选中时的图标
863 | Icon(Icons.Outlined.Create, contentDescription = null)
864 | }
865 | }
866 | },
867 | label = {
868 | Text(
869 | text = "Details",
870 | // modifier = Modifier.alpha(if (currentDestination?.route == "Details") 1f else 0f)
871 | )
872 | },
873 | selected = currentDestination?.route == "2",
874 | alwaysShowLabel = false,
875 | onClick = {
876 | navController.navigate("2") {
877 | popUpTo(navController.graph.startDestinationId) {
878 | saveState = true
879 | }
880 | launchSingleTop = true
881 | restoreState = true
882 | }
883 | }
884 | )
885 | NavigationBarItem(
886 | icon = {
887 | when (currentDestination?.route) {
888 | "3" -> {
889 | // 选中时的图标
890 | Icon(Icons.Filled.Info, contentDescription = null)
891 | }
892 |
893 | else -> {
894 | // 未选中时的图标
895 | Icon(Icons.Outlined.Info, contentDescription = null)
896 | }
897 | }
898 | },
899 | label = {
900 | Text(
901 | text = "About",
902 | // modifier = Modifier.alpha(if (currentDestination?.route == "About") 1f else 0f)
903 | )
904 | },
905 | selected = currentDestination?.route == "3",
906 | alwaysShowLabel = false,
907 | onClick = {
908 | navController.navigate("3") {
909 | popUpTo(navController.graph.startDestinationId) {
910 | saveState = true
911 | }
912 | launchSingleTop = true
913 | restoreState = true
914 | }
915 | }
916 | )
917 | }
918 |
919 |
920 | }
921 |
922 | ) {
923 | Column(
924 | modifier = Modifier
925 | .fillMaxSize()
926 | .padding(bottom = it.calculateBottomPadding()) // 添加 padding,防止遮挡内容
927 | ) {
928 | NavHost(
929 | navController = navController,
930 | startDestination = "1"
931 | ) {
932 | OLog.i("界面", "绘制横屏开始")
933 | composable("2") { Details() }
934 | composable("3") { AboutPage() }
935 | composable("1") { OptPage() }
936 | // 添加其他页面的 composable 函数,类似上面的示例
937 | }
938 | }
939 | }
940 |
941 | }
942 |
943 |
944 | @Composable
945 | fun AppListContent() {
946 | AppListScreen(LocalContext.current)
947 | }
948 |
949 | fun generateAppList(context: Context): List {
950 | var a: Boolean
951 | // 这里添加你的应用信息
952 | for (appinfo in pkglist) {
953 | if (OPackage.isInstalled(appinfo.appPkg, context.packageManager)) {
954 | appinfo.appName = getAppNameByPackageName(context, appinfo.appPkg)
955 | a = isAppDisabled(appinfo.appPkg)
956 | appinfo.isDisabled = a
957 | } else {
958 | appinfo.isExist = false
959 | appinfo.appName = "未安装"
960 | }
961 | appinfo.appIcon = getAppIconByPackageName(appinfo.appPkg, context.packageManager)
962 | }
963 | for (appinfo in optlist) {
964 | if (OPackage.isInstalled(appinfo.appPkg, context.packageManager)) {
965 | appinfo.appName = getAppNameByPackageName(context, appinfo.appPkg)
966 | a = isAppDisabled(appinfo.appPkg)
967 | appinfo.isDisabled = a
968 | } else {
969 | appinfo.isExist = false
970 | appinfo.appName = "未安装"
971 | }
972 | appinfo.appIcon = getAppIconByPackageName(appinfo.appPkg, context.packageManager)
973 | }
974 | OLog.i("列表项", pkglist.toString())
975 | return pkglist
976 | }
977 |
978 | @Preview(showBackground = true)
979 | @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
980 | @Composable
981 | fun GreetingPreview() {
982 | OriginPlanTheme {
983 | // A surface container using the 'background' color from the theme
984 | Surface(
985 | modifier = Modifier.fillMaxSize(),
986 | color = MaterialTheme.colorScheme.background
987 | ) {
988 | OptPage()
989 | }
990 | }
991 | }
992 |
993 | companion object {
994 | @SuppressLint("StaticFieldLeak")
995 | lateinit var app: XPlanForHyper private set
996 | }
997 | }
998 |
999 |
1000 |
1001 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/datatype/AppInfo.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.datatype
2 |
3 | import android.graphics.drawable.Drawable
4 |
5 | data class AppInfo(
6 | var appName: String,
7 | val appPkg: String,
8 | var appIcon: Drawable?=null,
9 | var isDisabled: Boolean = false,
10 | var isExist: Boolean = true
11 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/datatype/ConfigData.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.datatype
2 |
3 | private val dataList: List> = emptyList()
4 |
5 | data class ConfigData(
6 | var data: List> = dataList,
7 | var shell: String = "",
8 | var restore :String="",
9 | var debug: String = ""
10 | )
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/datatype/OriginCardItem.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.datatype
2 |
3 | import androidx.compose.ui.graphics.vector.ImageVector
4 |
5 | data class OriginCardItem(
6 | val icon: ImageVector? = null,
7 | val label: String,
8 | val content: String? = null,
9 | val onClick: (() -> Unit)? = null
10 | )
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/AboutPage.kt:
--------------------------------------------------------------------------------
1 | import android.content.Context
2 | import androidx.compose.foundation.layout.Arrangement
3 | import androidx.compose.foundation.layout.PaddingValues
4 | import androidx.compose.foundation.layout.fillMaxSize
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.foundation.layout.windowInsetsPadding
7 | import androidx.compose.foundation.lazy.LazyColumn
8 | import androidx.compose.material3.ExperimentalMaterial3Api
9 | import androidx.compose.material3.Scaffold
10 | import androidx.compose.material3.Text
11 | import androidx.compose.material3.TopAppBar
12 | import androidx.compose.material3.TopAppBarDefaults
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.ui.Modifier
15 | import androidx.compose.ui.unit.dp
16 |
17 | @OptIn(ExperimentalMaterial3Api::class)
18 | @Composable
19 | fun AboutPage() {
20 | Scaffold(
21 | modifier = Modifier
22 | .windowInsetsPadding(TopAppBarDefaults.windowInsets)
23 | .fillMaxSize(),
24 | topBar = {
25 | TopAppBar(
26 | title = {
27 | Text(text = "关于")
28 | },
29 | )
30 | },
31 | ) {
32 | LazyColumn(
33 | contentPadding = PaddingValues(16.dp),
34 | modifier = Modifier
35 | .fillMaxSize()
36 | .padding(it),
37 | verticalArrangement = Arrangement.spacedBy(16.dp),
38 | ) {
39 | item {
40 | StatusWidget()
41 | }
42 | item {
43 | DonateWidget()
44 | }
45 | item {
46 | DiscussWidget()
47 | }
48 | item {
49 | OpenSourceWidget()
50 | }
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/OptPage.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.content.res.Configuration
6 | import androidx.compose.foundation.layout.Arrangement
7 | import androidx.compose.foundation.layout.Column
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.fillMaxSize
10 | import androidx.compose.foundation.layout.fillMaxWidth
11 | import androidx.compose.foundation.layout.statusBarsPadding
12 | import androidx.compose.foundation.rememberScrollState
13 | import androidx.compose.material.icons.Icons
14 | import androidx.compose.material.icons.outlined.Notifications
15 | import androidx.compose.material3.ExperimentalMaterial3Api
16 | import androidx.compose.material3.Icon
17 | import androidx.compose.material3.IconButton
18 | import androidx.compose.material3.MaterialTheme
19 | import androidx.compose.material3.Scaffold
20 | import androidx.compose.material3.Surface
21 | import androidx.compose.material3.Text
22 | import androidx.compose.material3.TopAppBar
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Alignment
25 | import androidx.compose.ui.Modifier
26 | import androidx.compose.ui.tooling.preview.Preview
27 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
28 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
29 | import com.itos.xplanforhyper.ui.Pages.subassemblies.Opt.ControlSystemUpdateButton
30 | import com.itos.xplanforhyper.ui.Pages.subassemblies.Opt.HDButton
31 | import com.itos.xplanforhyper.ui.Pages.subassemblies.Opt.OptButton
32 | import com.itos.xplanforhyper.ui.Pages.subassemblies.Opt.ProcessLimitButton
33 | import com.itos.xplanforhyper.ui.theme.OriginPlanTheme
34 | import com.itos.xplanforhyper.utils.OData
35 |
36 |
37 | fun SettingsDebug() {
38 | MaterialAlertDialogBuilder(app)
39 | .setTitle("调试")
40 | .setMessage("这是调试功能,您确定要使用吗?")
41 | .setPositiveButton("OK") { _, _ ->
42 | val temp = app.ShizukuExec(OData.configdata.debug.toByteArray())
43 | MaterialAlertDialogBuilder(app)
44 | .setTitle("调试信息")
45 | .setMessage(temp)
46 | .setPositiveButton("OK", null)
47 | .show()
48 | }
49 | .show()
50 | }
51 |
52 | @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
53 | @OptIn(ExperimentalMaterial3Api::class)
54 | @Composable
55 | fun OptPage() {
56 | Scaffold(modifier = Modifier
57 | .fillMaxSize()
58 | .statusBarsPadding(),
59 | topBar = {
60 | TopAppBar(
61 | title = {
62 | Text(text = "优化")
63 | },
64 | actions = {
65 | // IconButton(
66 | // onClick = {
67 | //// SettingsDebug()
68 | //
69 | // }
70 | // ) {
71 | // Icon(
72 | // imageVector = Icons.Outlined.Build,
73 | // contentDescription = "Debug"
74 | // )
75 | // }
76 | IconButton(
77 | onClick = {
78 | MaterialAlertDialogBuilder(app)
79 | .setTitle("公告")
80 | .setMessage(app.show_notice)
81 | .setPositiveButton("了解") { dialog, which ->
82 | dialog.dismiss()
83 | }
84 | .show()
85 | }
86 | ) {
87 | Icon(
88 | imageVector = Icons.Outlined.Notifications,
89 | contentDescription = "help"
90 | )
91 | }
92 | }
93 | )
94 | }) {
95 | if (isLandscape(app)) {
96 |
97 | val scrollState = rememberScrollState()
98 | // 执行横屏时的操作
99 | Column(
100 | modifier = Modifier
101 | .fillMaxSize(),
102 | // .verticalScroll(scrollState)
103 | // .padding(top = getStatusBarHeight().dp),
104 | horizontalAlignment = Alignment.CenterHorizontally,
105 | verticalArrangement = Arrangement.Center // 将子项垂直居中
106 | ) {
107 | Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
108 | OptButton()
109 | ProcessLimitButton()
110 | }
111 |
112 | Row (modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly){
113 | HDButton()
114 | ControlSystemUpdateButton()
115 | }
116 | // Settings_opt()
117 |
118 | }
119 | } else {
120 | // 执行竖屏时的操作
121 | Column(
122 | modifier = Modifier
123 | .fillMaxSize()
124 | .statusBarsPadding(),
125 | horizontalAlignment = Alignment.CenterHorizontally,
126 | verticalArrangement = Arrangement.Center // 将子项垂直居中
127 | ) {
128 | OptButton()
129 | ProcessLimitButton()
130 | // Settings_opt()
131 | HDButton()
132 | ControlSystemUpdateButton()
133 | }
134 | }
135 |
136 | }
137 | }
138 |
139 | fun isLandscape(context: Context): Boolean {
140 | val configuration = context.resources.configuration
141 | return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
142 | }
143 |
144 | fun getStatusBarHeight(): Int {
145 | var result = 0
146 | val resourceId: Int = app.resources.getIdentifier("status_bar_height", "dimen", "android")
147 | if (resourceId > 0) {
148 | result = app.resources.getDimensionPixelSize(resourceId)
149 | }
150 |
151 | return result
152 | }
153 |
154 | @OptIn(ExperimentalMaterial3Api::class)
155 | @Preview(showBackground = true)
156 | @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
157 | @Composable
158 | fun a() {
159 | OriginPlanTheme {
160 | // A surface container using the 'background' color from the theme
161 | Surface(
162 | modifier = Modifier.fillMaxSize(),
163 | color = MaterialTheme.colorScheme.background
164 | ) {
165 | OptPage()
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/About/DiscussWidget.kt:
--------------------------------------------------------------------------------
1 |
2 | import android.content.Intent
3 | import android.net.Uri
4 | import android.text.util.Linkify
5 | import android.widget.Toast
6 | import androidx.compose.material3.Text
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.ui.graphics.vector.ImageVector
9 | import androidx.compose.ui.res.vectorResource
10 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
11 | import com.google.android.material.textview.MaterialTextView
12 | import com.itos.xplanforhyper.R
13 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
14 | import com.itos.xplanforhyper.datatype.OriginCardItem
15 | import com.itos.xplanforhyper.utils.OUI
16 |
17 | fun show_author() {
18 | try {
19 | val intent = Intent(Intent.ACTION_VIEW)
20 | intent.data = Uri.parse("coolmarket://u/3287595")
21 | app.startActivity(intent)
22 | app.finish()
23 | } catch (e: java.lang.Exception) {
24 | Toast.makeText(app, "打开酷安失败,已为您打开作者B站", Toast.LENGTH_SHORT).show()
25 | OUI.openLink("https://space.bilibili.com/329223542")
26 | }
27 | }
28 |
29 | fun moreapp() {
30 | MaterialAlertDialogBuilder(app)
31 | .setTitle("更多软件")
32 | .setMessage(app.resources.openRawResource(R.raw.moreapp).bufferedReader().readText())
33 | .setPositiveButton("了解", null)
34 | .show()
35 | .findViewById(android.R.id.message)?.apply {
36 | setTextIsSelectable(true)
37 | Linkify.addLinks(this, Linkify.EMAIL_ADDRESSES or Linkify.WEB_URLS)
38 | // The first time the link is clicked the background does not change color and
39 | // the view needs to get focus once.
40 | requestFocus()
41 | }
42 |
43 | }
44 | @Composable
45 | fun DiscussWidget() {
46 | val items = listOf(
47 | OriginCardItem(
48 | icon = ImageVector.vectorResource(R.drawable.ic_bilibili),
49 | label = "BiliBili(开发者)",
50 | onClick = {
51 | OUI.openLink("https://space.bilibili.com/329223542")
52 | }),
53 | OriginCardItem(
54 | icon = ImageVector.vectorResource(R.drawable.ic_bilibili),
55 | label = "BiliBili(合作伙伴)",
56 | onClick = {
57 | OUI.openLink("https://space.bilibili.com/1289434708")
58 | }
59 | ),
60 | OriginCardItem(
61 | icon = ImageVector.vectorResource(R.drawable.ic_outline_coolapk),
62 | label = "酷安(开发者)",
63 | onClick = {
64 | show_author()
65 | }
66 | ),
67 | OriginCardItem(
68 | icon = ImageVector.vectorResource(R.drawable.ic_outline_qq),
69 | label = "QQ频道",
70 | onClick = {
71 | OUI.openLink("https://pd.qq.com/s/8vadinclc")
72 | }
73 | ),
74 | // OriginCardItem(
75 | // icon = Icons.Default.Share,
76 | // label = "更多软件",
77 | // onClick = {
78 | // moreapp()
79 | // }
80 | // ),
81 | )
82 | ItemsCardWidget(
83 | title = {
84 | Text(text = "讨论&反馈&联系我们")
85 | },
86 | items = items,
87 | showItemIcon = true
88 | )
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/About/DonateWidget.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.material3.Text
2 | import androidx.compose.runtime.Composable
3 | import androidx.compose.ui.graphics.vector.ImageVector
4 | import androidx.compose.ui.platform.LocalContext
5 | import androidx.compose.ui.res.vectorResource
6 | import com.itos.xplanforhyper.R
7 | import com.itos.xplanforhyper.datatype.OriginCardItem
8 | import com.itos.xplanforhyper.utils.OUI
9 |
10 | @Composable
11 | fun DonateWidget() {
12 | LocalContext.current
13 |
14 | val items = listOf(
15 | OriginCardItem(
16 | icon = ImageVector.vectorResource(R.drawable.ic_alipay),
17 | label = "支付宝",
18 | onClick = {
19 | OUI.showImageDialog("zfb.jpg")
20 | }
21 | ),
22 | OriginCardItem(
23 | icon = ImageVector.vectorResource(R.drawable.ic_wechatpay),
24 | label = "微信",
25 | onClick = {
26 | OUI.showImageDialog("wx.png")
27 | }
28 | ),
29 |
30 | )
31 | ItemsCardWidget(
32 | title = {
33 | Text(text = "捐赠")
34 | },
35 | items = items,
36 | showItemIcon = true
37 | )
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/About/OpenSourceWidget.kt:
--------------------------------------------------------------------------------
1 |
2 | import android.text.util.Linkify
3 | import androidx.compose.material3.Text
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.ui.graphics.vector.ImageVector
6 | import androidx.compose.ui.res.vectorResource
7 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
8 | import com.google.android.material.textview.MaterialTextView
9 | import com.itos.xplanforhyper.R
10 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
11 | import com.itos.xplanforhyper.datatype.OriginCardItem
12 | import com.itos.xplanforhyper.utils.OUI
13 |
14 | fun showLicenses() {
15 | MaterialAlertDialogBuilder(app)
16 | .setTitle(R.string.action_licenses)
17 | .setMessage(
18 | app.resources.openRawResource(R.raw.licenses).bufferedReader().readText()
19 | )
20 | .setPositiveButton(android.R.string.ok, null)
21 | .show()
22 | .findViewById(android.R.id.message)?.apply {
23 | setTextIsSelectable(true)
24 | Linkify.addLinks(this, Linkify.EMAIL_ADDRESSES or Linkify.WEB_URLS)
25 | requestFocus()
26 | }
27 | }
28 |
29 | @Composable
30 | fun OpenSourceWidget() {
31 | val items = listOf(
32 | OriginCardItem(
33 | icon = ImageVector.vectorResource(R.drawable.ic_outline_code),
34 |
35 | label = "Github",
36 | onClick = {
37 | OUI.openLink("https://github.com/ItosEO/XPlanForHyper")
38 | }
39 | ),
40 | OriginCardItem(
41 | icon = ImageVector.vectorResource(R.drawable.ic_outline_lisence),
42 |
43 | label = "许可证",
44 | onClick = {
45 | showLicenses()
46 | }
47 | ),
48 |
49 | )
50 | ItemsCardWidget(
51 | title = {
52 | Text(text = "开源")
53 | },
54 | items = items,
55 | showItemIcon = true
56 | )
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/About/StatusWidget.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.foundation.Image
2 | import androidx.compose.foundation.layout.Box
3 | import androidx.compose.foundation.layout.fillMaxWidth
4 | import androidx.compose.foundation.layout.size
5 | import androidx.compose.material3.CardDefaults
6 | import androidx.compose.material3.MaterialTheme
7 | import androidx.compose.material3.Text
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Alignment
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.platform.LocalContext
12 | import androidx.compose.ui.res.stringResource
13 | import androidx.compose.ui.unit.dp
14 | import androidx.core.content.ContextCompat
15 | import com.google.accompanist.drawablepainter.rememberDrawablePainter
16 | import com.itos.xplanforhyper.BuildConfig
17 | import com.itos.xplanforhyper.R
18 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
19 |
20 | @Composable
21 | fun StatusWidget() {
22 | val containerColor = MaterialTheme.colorScheme.primaryContainer
23 | val onContainerColor = MaterialTheme.colorScheme.onPrimaryContainer
24 |
25 | val level = app.getString(R.string.build_type)
26 |
27 | CardWidget(
28 | colors = CardDefaults.elevatedCardColors(
29 | containerColor = containerColor,
30 | contentColor = onContainerColor
31 | ),
32 | icon = {
33 | Image(
34 | modifier = Modifier
35 | .size(56.dp),
36 | painter = rememberDrawablePainter(
37 | drawable = ContextCompat.getDrawable(
38 | LocalContext.current,
39 | R.mipmap.ic_launcher_xplan
40 | )
41 | ),
42 | contentDescription = stringResource(id = R.string.app_name)
43 | )
44 | },
45 | title = {
46 | Text(
47 | modifier = Modifier,
48 | text = stringResource(id = R.string.app_name),
49 | style = MaterialTheme.typography.titleMedium,
50 | )
51 | },
52 | content = {
53 | Box(modifier = Modifier.fillMaxWidth()) {
54 | Text(
55 | modifier = Modifier.align(Alignment.Center),
56 | text = "$level [${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})]",
57 | style = MaterialTheme.typography.bodyMedium,
58 | )
59 | }
60 | }
61 | )
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/Opt/ControlSystemUpdateButton.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.Pages.subassemblies.Opt
2 |
3 | import androidx.compose.foundation.layout.Row
4 | import androidx.compose.foundation.layout.Spacer
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.foundation.layout.size
7 | import androidx.compose.foundation.layout.width
8 | import androidx.compose.foundation.shape.RoundedCornerShape
9 | import androidx.compose.material3.FilledTonalButton
10 | import androidx.compose.material3.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.ui.Modifier
13 | import androidx.compose.ui.text.style.TextAlign
14 | import androidx.compose.ui.unit.dp
15 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
16 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
17 | import com.itos.xplanforhyper.utils.OShizuku
18 | import com.itos.xplanforhyper.utils.SpUtils
19 |
20 | @Composable
21 | fun ControlSystemUpdateButton(){
22 | Row(
23 | modifier = Modifier
24 | .padding(vertical = 45.dp)
25 | ) {
26 | FilledTonalButton(
27 | modifier = Modifier
28 | .size(width = 130.dp, height = 70.dp),
29 | shape = RoundedCornerShape(30),
30 | onClick = { DisableSystemUpdate() }
31 | ) {
32 | Text("禁用\n系统更新", textAlign = TextAlign.Center)
33 | }
34 | Spacer(modifier = Modifier.width(25.dp))
35 | FilledTonalButton(
36 | modifier = Modifier
37 | .size(width = 130.dp, height = 70.dp),
38 | shape = RoundedCornerShape(30),
39 | onClick = { EnableSystemUpdate() }
40 | ) {
41 | Text("恢复\n系统更新", textAlign = TextAlign.Center)
42 | }
43 | }
44 | }
45 |
46 | private fun DisableSystemUpdate(){
47 | if (app.b && app.c) {
48 | // val isExist=OPackage.isInstalled("com.android.updater",XPlanForHyper.app.packageManager)
49 | // XPlanForHyper.app.SetAppDisabled(mutableStateOf(true), "com.android.updater", isExist, false)
50 | MaterialAlertDialogBuilder(app)
51 | .setTitle("禁用系统更新")
52 | .setMessage("该操作可能导致卡米,您确定要进行吗?")
53 | .setPositiveButton("确定") { _, _ ->
54 | uninstall("com.android.updater")
55 | MaterialAlertDialogBuilder(app)
56 | .setTitle("完成")
57 | .setMessage("禁用系统更新完成")
58 | .setPositiveButton(android.R.string.ok, null)
59 | .show()
60 | app.generateAppList(app)
61 | }
62 | .setNegativeButton("取消",null)
63 | .show()
64 | } else {
65 | OShizuku.checkShizuku()
66 | }
67 | }
68 |
69 | private fun EnableSystemUpdate(){
70 | if (app.b && app.c) {
71 | // val isExist=OPackage.isInstalled("com.android.updater", app.packageManager)
72 | // app.SetAppDisabled(mutableStateOf(false), "com.android.updater", isExist, false)
73 | reinstall("com.android.updater")
74 | MaterialAlertDialogBuilder(app)
75 | .setTitle("完成")
76 | .setMessage("已恢复系统更新")
77 | .setPositiveButton(android.R.string.ok, null)
78 | .show()
79 | app.generateAppList(app)
80 | } else {
81 | OShizuku.checkShizuku()
82 | }
83 | }
84 |
85 | private fun uninstall(packagename: String) {
86 | when (SpUtils.getParam(app.context, "method", 1)) {
87 | 3 -> {
88 | app.ShizukuExec("service call package 131 s16 $packagename i32 0 i32 0".toByteArray())
89 | }
90 |
91 | 2 -> {
92 | app.ShizukuExec("service call package 134 s16 $packagename i32 0 i32 0".toByteArray())
93 | }
94 |
95 | 1 -> {
96 | app.ShizukuExec("pm uninstall --user 0 $packagename".toByteArray())
97 | }
98 | else -> {
99 | app.ShizukuExec("pm uninstall $packagename".toByteArray())
100 | }
101 |
102 | }
103 | }
104 |
105 | private fun reinstall(packagename: String) {
106 | when (SpUtils.getParam(app, "method", 1)) {
107 | 3 -> {
108 | app.ShizukuExec("service call package 131 s16 $packagename i32 1 i32 0".toByteArray())
109 | }
110 |
111 | 2 -> {
112 | app.ShizukuExec("service call package 134 s16 $packagename i32 1 i32 0".toByteArray())
113 | }
114 |
115 | else -> {
116 | app.ShizukuExec("pm install-existing $packagename".toByteArray())
117 | }
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/Opt/HDButton.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.Pages.subassemblies.Opt
2 |
3 | import androidx.compose.foundation.layout.Row
4 | import androidx.compose.foundation.layout.Spacer
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.foundation.layout.size
7 | import androidx.compose.foundation.layout.width
8 | import androidx.compose.foundation.shape.RoundedCornerShape
9 | import androidx.compose.material3.FilledTonalButton
10 | import androidx.compose.material3.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.ui.Modifier
13 | import androidx.compose.ui.unit.dp
14 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
15 | import com.itos.xplanforhyper.utils.OLog
16 |
17 | @Composable
18 | fun HDButton() {
19 | Row(
20 | modifier = Modifier
21 | .padding(vertical = 45.dp)
22 | ) {
23 | FilledTonalButton(
24 | modifier = Modifier
25 | .size(width = 130.dp, height = 70.dp),
26 | shape = RoundedCornerShape(30),
27 | onClick = { HideHD() }
28 | ) {
29 | Text("隐藏HD")
30 | }
31 | Spacer(modifier = Modifier.width(25.dp))
32 | FilledTonalButton(
33 | modifier = Modifier
34 | .size(width = 130.dp, height = 70.dp),
35 | shape = RoundedCornerShape(30),
36 | onClick = { UnHideHD() }
37 | ) {
38 | Text("还原HD")
39 | }
40 | }
41 | }
42 |
43 | fun HideHD() {
44 | OLog.i("隐藏HD", "Shizuku方案")
45 |
46 | var data = app.ShizukuExec("settings get secure icon_blacklist".toByteArray())
47 | OLog.i("隐藏HD", "当前黑名单列表: $data")
48 | data = data!!.trimEnd()
49 | data = data.replace(Regex(",+"), ",")
50 | data = data.replace(Regex("(,rotate,hd)+"), ",rotate,hd")
51 | data = "$data,rotate,hd"
52 | OLog.i("隐藏HD", "处理后黑名单列表: $data")
53 | app.ShizukuExec("settings put secure icon_blacklist $data,rotate,hd".toByteArray())
54 | // if (OData.is_have_premissipn) {
55 | // OLog.i("隐藏HD", "Java方案")
56 | //
57 | // var data = Settings.Secure.getString(app.contentResolver, "icon_blacklist")
58 | // OLog.i("隐藏HD", "当前黑名单列表: $data")
59 | // data = data!!.trimEnd()
60 | // data = data.replace(Regex(",+"), ",")
61 | // data = "$data,rotate,hd"
62 | // data = data.replace(Regex("(,rotate,hd)+"), ",rotate,hd")
63 | // OLog.i("隐藏HD", "处理后黑名单列表: $data")
64 | // Settings.Secure.putString(app.contentResolver, "icon_blacklist", data)
65 | // } else {
66 | // OLog.i("隐藏HD", "Shizuku方案")
67 | //
68 | // var data = app.ShizukuExec("settings get secure icon_blacklist".toByteArray())
69 | // OLog.i("隐藏HD", "当前黑名单列表: $data")
70 | // data = data!!.trimEnd()
71 | // data = data.replace(Regex(",+"), ",")
72 | // data = data.replace(Regex("(,rotate,hd)+"), ",rotate,hd")
73 | // data = "$data,rotate,hd"
74 | // OLog.i("隐藏HD", "处理后黑名单列表: $data")
75 | // app.ShizukuExec("settings put secure icon_blacklist $data,rotate,hd".toByteArray())
76 | //
77 | // }
78 | }
79 |
80 | fun UnHideHD() {
81 |
82 | OLog.i("还原HD", "Shizuku方案")
83 |
84 | var data = app.ShizukuExec("settings get secure icon_blacklist".toByteArray())
85 | data = data!!.trimEnd()
86 |
87 | OLog.i("还原HD", "待处理数据: $data")
88 | val targets = listOf("hd")
89 | // 构建正则表达式,使用 joinToString 将多个子串连接起来
90 | val regex = targets.joinToString(separator = "|").toRegex()
91 | // 使用正则表达式替换为""
92 | var resultString = regex.replace(data, "")
93 | resultString = resultString.replace(Regex("(,rotate)+"), ",rotate")
94 | resultString = resultString.replace(Regex(",+"), ",")
95 | OLog.i("还原HD", "处理结果: $resultString")
96 |
97 | app.ShizukuExec("settings put secure icon_blacklist $resultString".toByteArray())// if (OData.is_have_premissipn) {
98 | // OLog.i("还原HD", "Java方案")
99 | //
100 | // var data = Settings.Secure.getString(app.contentResolver, "icon_blacklist")
101 | // data = data!!.trimEnd()
102 | //
103 | // OLog.i("还原HD", "待处理数据: $data")
104 | // val targets = listOf("hd")
105 | // // 构建正则表达式,使用 joinToString 将多个子串连接起来
106 | // val regex = targets.joinToString(separator = "|").toRegex()
107 | // // 使用正则表达式替换为""
108 | // var resultString = regex.replace(data, "")
109 | // resultString = resultString.replace(Regex("(,rotate)+"), ",rotate")
110 | // resultString = resultString.replace(Regex(",+"), ",")
111 | // OLog.i("还原HD", "处理结果: $resultString")
112 | //
113 | // Settings.Secure.putString(app.contentResolver, "icon_blacklist", resultString)
114 | // } else {
115 | // OLog.i("还原HD", "Shizuku方案")
116 | //
117 | // var data = app.ShizukuExec("settings get secure icon_blacklist".toByteArray())
118 | // data = data!!.trimEnd()
119 | //
120 | // OLog.i("还原HD", "待处理数据: $data")
121 | // val targets = listOf("hd")
122 | // // 构建正则表达式,使用 joinToString 将多个子串连接起来
123 | // val regex = targets.joinToString(separator = "|").toRegex()
124 | // // 使用正则表达式替换为""
125 | // var resultString = regex.replace(data, "")
126 | // resultString = resultString.replace(Regex("(,rotate)+"), ",rotate")
127 | // resultString = resultString.replace(Regex(",+"), ",")
128 | // OLog.i("还原HD", "处理结果: $resultString")
129 | //
130 | // app.ShizukuExec("settings put secure icon_blacklist $resultString".toByteArray())
131 | // }
132 | }
133 |
134 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/Opt/OptButton.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.Pages.subassemblies.Opt
2 |
3 | import androidx.compose.foundation.layout.Row
4 | import androidx.compose.foundation.layout.Spacer
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.foundation.layout.size
7 | import androidx.compose.foundation.layout.width
8 | import androidx.compose.foundation.shape.RoundedCornerShape
9 | import androidx.compose.material3.FilledTonalButton
10 | import androidx.compose.material3.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.mutableStateOf
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.unit.dp
15 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
16 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
17 | import com.itos.xplanforhyper.utils.OShizuku
18 |
19 | @Composable
20 | fun OptButton(){
21 | Row(
22 | modifier = Modifier
23 | .padding(vertical = 45.dp)
24 | ) {
25 | FilledTonalButton(
26 | modifier = Modifier
27 | .size(width = 130.dp, height = 70.dp),
28 | shape = RoundedCornerShape(30),
29 | onClick = { opt_setappstauts(false) }
30 | ) {
31 | Text("一键优化")
32 | }
33 | Spacer(modifier = Modifier.width(25.dp))
34 | FilledTonalButton(
35 | modifier = Modifier
36 | .size(width = 130.dp, height = 70.dp),
37 | shape = RoundedCornerShape(30),
38 | onClick = { opt_setappstauts(true) }
39 | ) {
40 | Text("还原")
41 | }
42 | }
43 | }
44 |
45 | fun opt_setappstauts(status: Boolean) {
46 | if (app.b && app.c) {
47 | app.generateAppList(app)
48 | // 遍历app list
49 | for (appInfo in app.optlist) {
50 | if (appInfo.isExist) {
51 | app.SetAppDisabled(mutableStateOf(status), appInfo.appPkg, appInfo.isExist, false)
52 | appInfo.isDisabled = app.isAppDisabled(appInfo.appPkg)
53 | }
54 | }
55 | if (!status) {
56 | MaterialAlertDialogBuilder(app)
57 | .setTitle("完成")
58 | .setMessage("一键优化完成")
59 | .setPositiveButton(android.R.string.ok, null)
60 | .show()
61 | } else {
62 | MaterialAlertDialogBuilder(app)
63 | .setTitle("完成")
64 | .setMessage("还原完成")
65 | .setPositiveButton(android.R.string.ok, null)
66 | .show()
67 | }
68 | app.generateAppList(app)
69 | } else {
70 | OShizuku.checkShizuku()
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/Opt/ProcessLimitButton.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.Pages.subassemblies.Opt
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.compose.foundation.layout.Row
5 | import androidx.compose.foundation.layout.Spacer
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.foundation.layout.size
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.foundation.shape.RoundedCornerShape
10 | import androidx.compose.material3.FilledTonalButton
11 | import androidx.compose.material3.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.text.style.TextAlign
15 | import androidx.compose.ui.unit.dp
16 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
17 |
18 | @SuppressLint("StaticFieldLeak")
19 |
20 | @Composable
21 | fun ProcessLimitButton(){
22 | Row(
23 | modifier = Modifier
24 | .padding(vertical = 45.dp)
25 | ) {
26 | FilledTonalButton(
27 | modifier = Modifier
28 | .size(width = 130.dp, height = 70.dp),
29 | shape = RoundedCornerShape(30),
30 | onClick = {
31 | app.patchProcessLimit()
32 | }
33 | ) {
34 | Text("调整后台进程设置", textAlign = TextAlign.Center)
35 | }
36 | Spacer(modifier = Modifier.width(25.dp))
37 | FilledTonalButton(
38 | modifier = Modifier
39 | .size(width = 130.dp, height = 70.dp),
40 | shape = RoundedCornerShape(30),
41 | onClick = {
42 | app.unpatchProcessLimit()
43 | }
44 | ) {
45 | Text("还原\n进程设置", textAlign = TextAlign.Center)
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/Pages/subassemblies/Opt/SettingsOptButton.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.Pages.subassemblies.Opt
2 |
3 | import android.widget.Toast
4 | import androidx.compose.foundation.layout.Row
5 | import androidx.compose.foundation.layout.Spacer
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.foundation.layout.size
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.foundation.shape.RoundedCornerShape
10 | import androidx.compose.material3.FilledTonalButton
11 | import androidx.compose.material3.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.text.style.TextAlign
15 | import androidx.compose.ui.unit.dp
16 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
17 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
18 | import com.itos.xplanforhyper.utils.OData
19 |
20 | fun SettingsOpt(){
21 | // if (OData.is_have_premissipn){
22 | // OData.configdata.data.forEach { innerList ->
23 | //// Settings.System.putString(app.contentResolver, innerList[0], Integer.valueOf(innerList[1]))
24 | // SpUtils.putSettingsParam(app, innerList[2], innerList[0], innerList[1])
25 | // OLog.i("系统参数调优",innerList.toString())
26 | // }
27 | // }else{
28 | // Toast.makeText(app,"权限不足",Toast.LENGTH_SHORT).show()
29 | // }
30 | app.ShizukuExec(OData.configdata.shell.toByteArray())
31 | MaterialAlertDialogBuilder(app)
32 | .setTitle("完成")
33 | .setMessage("调整完成")
34 | .setPositiveButton("OK",null)
35 | .show()
36 | }
37 | fun SettingsRestore (){
38 | // if (OData.is_have_premissipn){
39 | // OData.configdata.data.forEach { innerList ->
40 | //// Settings.System.putString(app.contentResolver, innerList[0], Integer.valueOf(innerList[1]))
41 | // SpUtils.putSettingsParam(app, innerList[2], innerList[0], innerList[1])
42 | // OLog.i("系统参数调优",innerList.toString())
43 | // }
44 | // }else{
45 | // Toast.makeText(app,"权限不足",Toast.LENGTH_SHORT).show()
46 | // }
47 | app.ShizukuExec(OData.configdata.restore.toByteArray())
48 | MaterialAlertDialogBuilder(app)
49 | .setTitle("完成")
50 | .setMessage("还原完成")
51 | .setPositiveButton("OK",null)
52 | .show()
53 | }
54 |
55 | @Composable
56 | fun Settings_opt() {
57 | Row(
58 | modifier = Modifier
59 | .padding(vertical = 45.dp)
60 | ) {
61 | FilledTonalButton(
62 | modifier = Modifier
63 | .size(width = 130.dp, height = 70.dp),
64 | shape = RoundedCornerShape(30),
65 | onClick = {
66 | SettingsOpt()
67 | Toast.makeText(app, "开发中...", Toast.LENGTH_SHORT).show()
68 | }
69 | ) {
70 | Text("系统参数\n调优", textAlign = TextAlign.Center)
71 | }
72 | Spacer(modifier = Modifier.width(25.dp))
73 | FilledTonalButton(
74 | modifier = Modifier
75 | .size(width = 130.dp, height = 70.dp),
76 | shape = RoundedCornerShape(30),
77 | onClick = {
78 | SettingsRestore()
79 | Toast.makeText(app, "开发中...", Toast.LENGTH_SHORT).show()
80 | }
81 | ) {
82 | Text("还原\n系统参数", textAlign = TextAlign.Center)
83 | }
84 | // Spacer(modifier = Modifier.width(15.dp))
85 | // FilledTonalButton(
86 | // modifier = Modifier
87 | // .size(width = 80.dp, height = 70.dp),
88 | // shape = RoundedCornerShape(30),
89 | // onClick = {
90 | // SettingsDebug()
91 | // Toast.makeText(app, "开发中...", Toast.LENGTH_SHORT).show()
92 | // }
93 | // ) {
94 | // Text("调试", textAlign = TextAlign.Center)
95 | // }
96 | }
97 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val Purple80 = Color(0xFFD0BCFF)
6 | val PurpleGrey80 = Color(0xFFCCC2DC)
7 | val Pink80 = Color(0xFFEFB8C8)
8 |
9 | val Purple40 = Color(0xC86650A4)
10 | val PurpleGrey40 = Color(0xDD625B71)
11 | val Pink40 = Color(0xDD7D5260)
12 |
13 | val LightPrimary = Color(0xFF4A672D)
14 | val LightOnPrimary = Color(0xFF0E2000)
15 | val LightPrimaryContainer = Color(0xFFCBEEA5)
16 | val LightSecondary = Color(0xFF57624A)
17 | val LightTertiary = Color(0xFF386664)
18 | val LightError = Color(0xFFB3261E)
19 |
20 | val DarkPrimary = Color(0xFFAFD18C)
21 | val DarkPrimaryContainer = Color(0xFF334E17)
22 | val DarkSecondary = Color(0xFFBFCBAD)
23 | val DarkTertiary = Color(0xFFA0CFCC)
24 | val DarkError = Color(0xFFF2B8B5)
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.theme
2 |
3 | import android.app.Activity
4 | import android.os.Build
5 | import android.view.WindowManager
6 | import androidx.compose.foundation.isSystemInDarkTheme
7 | import androidx.compose.material3.MaterialTheme
8 | import androidx.compose.material3.darkColorScheme
9 | import androidx.compose.material3.dynamicDarkColorScheme
10 | import androidx.compose.material3.dynamicLightColorScheme
11 | import androidx.compose.material3.lightColorScheme
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.runtime.SideEffect
14 | import androidx.compose.ui.graphics.Color
15 | import androidx.compose.ui.graphics.toArgb
16 | import androidx.compose.ui.platform.LocalContext
17 | import androidx.compose.ui.platform.LocalView
18 | import androidx.core.view.WindowCompat
19 | import com.google.accompanist.systemuicontroller.rememberSystemUiController
20 |
21 | private val DarkColorScheme = darkColorScheme(
22 | // primary = Purple80,
23 | // secondary = PurpleGrey80,
24 | // tertiary = Pink80
25 | primary = DarkPrimary,
26 | primaryContainer = DarkPrimaryContainer,
27 | secondary = DarkSecondary,
28 | tertiary = DarkTertiary,
29 | error = DarkError
30 | )
31 |
32 | private val LightColorScheme = lightColorScheme(
33 | // primary = Purple40,
34 | // secondary = PurpleGrey40,
35 | // tertiary = Pink40
36 | primary = LightPrimary,
37 | primaryContainer = LightPrimaryContainer,
38 | secondary = LightSecondary,
39 | tertiary = LightTertiary
40 |
41 | /* Other default colors to override
42 | background = Color(0xFFFFFBFE),
43 | surface = Color(0xFFFFFBFE),
44 | onPrimary = Color.White,
45 | onSecondary = Color.White,
46 | onTertiary = Color.White,
47 | onBackground = Color(0xFF1C1B1F),
48 | onSurface = Color(0xFF1C1B1F),
49 | */
50 | )
51 |
52 | @Suppress("NAME_SHADOWING")
53 | @Composable
54 | fun OriginPlanTheme(
55 | // 是否处于暗色模式
56 | darkTheme: Boolean = isSystemInDarkTheme(),
57 |
58 | // Dynamic color is available on Android 12+
59 | // 是否支持动态颜色
60 | dynamicColor: Boolean = true,
61 | // 内容
62 | content: @Composable () -> Unit
63 | ) {
64 | // 根据是否支持动态颜色,以及当前系统版本,确定颜色方案
65 | val colorScheme = when {
66 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
67 | val context = LocalContext.current
68 | // 如果是暗色模式,则使用动态暗色方案,否则使用动态亮色方案
69 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
70 | }
71 |
72 | darkTheme -> DarkColorScheme
73 | else -> LightColorScheme
74 | }
75 | // 获取当前视图
76 | val view = LocalView.current
77 | // 如果不是编辑模式
78 | if (!view.isInEditMode) {
79 | val systemUiController = rememberSystemUiController()
80 | val context = LocalContext.current
81 | val view = LocalView.current
82 | // 添加一个副作用,设置状态栏颜色和外观
83 | SideEffect {
84 | val window = (view.context as Activity).window
85 |
86 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
87 | window.attributes.layoutInDisplayCutoutMode =
88 | WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
89 | }
90 |
91 | WindowCompat.setDecorFitsSystemWindows(window, false)
92 |
93 | window.statusBarColor = Color.Transparent.toArgb()
94 | WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars =
95 | !darkTheme
96 | }
97 | }
98 |
99 | // 设置颜色方案、类型方案和内容
100 | MaterialTheme(
101 | colorScheme = colorScheme,
102 | typography = Typography,
103 | content = content
104 | )
105 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.ui.theme
2 |
3 | import androidx.compose.material3.Typography
4 | import androidx.compose.ui.text.TextStyle
5 | import androidx.compose.ui.text.font.FontFamily
6 | import androidx.compose.ui.text.font.FontWeight
7 | import androidx.compose.ui.unit.sp
8 |
9 | // Set of Material typography styles to start with
10 | val Typography = Typography(
11 | bodyLarge = TextStyle(
12 | fontFamily = FontFamily.Default,
13 | fontWeight = FontWeight.Normal,
14 | fontSize = 16.sp,
15 | lineHeight = 24.sp,
16 | letterSpacing = 0.5.sp
17 | )
18 | /* Other default text styles to override
19 | titleLarge = TextStyle(
20 | fontFamily = FontFamily.Default,
21 | fontWeight = FontWeight.Normal,
22 | fontSize = 22.sp,
23 | lineHeight = 28.sp,
24 | letterSpacing = 0.sp
25 | ),
26 | labelSmall = TextStyle(
27 | fontFamily = FontFamily.Default,
28 | fontWeight = FontWeight.Medium,
29 | fontSize = 11.sp,
30 | lineHeight = 16.sp,
31 | letterSpacing = 0.5.sp
32 | )
33 | */
34 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/NetUtils.java:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils;
2 |
3 | import android.util.Log;
4 |
5 | import java.io.BufferedReader;
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 | import java.io.OutputStream;
9 | import java.net.HttpURLConnection;
10 | import java.net.URL;
11 |
12 |
13 | public class NetUtils {
14 |
15 | //Post请求1,参数俩
16 | public static String Post(String ur, String byteString) {
17 | String fh = "";
18 | try {
19 | URL url = new URL(ur);
20 | HttpURLConnection HttpURLConnection = (HttpURLConnection) url.openConnection();
21 | HttpURLConnection.setReadTimeout(5000);
22 | HttpURLConnection.setRequestMethod("POST");
23 | OutputStream outputStream = HttpURLConnection.getOutputStream();
24 | outputStream.write(byteString.getBytes());
25 | BufferedReader BufferedReader = new BufferedReader(new InputStreamReader(HttpURLConnection.getInputStream()));
26 | String String = "";
27 | StringBuffer StringBuffer = new StringBuffer();
28 | while ((String = BufferedReader.readLine()) != null) {
29 | StringBuffer.append(String);
30 | }
31 | fh = StringBuffer.toString();
32 |
33 | } catch (IOException e) {
34 | Log.d("post", String.valueOf(e));
35 | fh="666";
36 | }
37 | return fh;
38 | }
39 |
40 | //Post请求1,无参数
41 | public static String Post(String string) {
42 | String a="";
43 | try {
44 | URL url = new URL(string);
45 | HttpURLConnection HttpURLConnection = (HttpURLConnection) url.openConnection();
46 | HttpURLConnection.setReadTimeout(5000);
47 | HttpURLConnection.setRequestMethod("POST");
48 | BufferedReader BufferedReader = new BufferedReader(new InputStreamReader(HttpURLConnection.getInputStream()));
49 | String String = "";
50 | StringBuffer StringBuffer = new StringBuffer();
51 | while ((String = BufferedReader.readLine()) != null) {
52 | StringBuffer.append(String);
53 | }
54 | a = StringBuffer.toString();
55 | }catch (Exception ignored){}
56 | return a;
57 | }
58 |
59 | public static String Get(String string) throws IOException {
60 | URL url = new URL(string);
61 | HttpURLConnection HttpURLConnection = (HttpURLConnection) url.openConnection();
62 | HttpURLConnection.setReadTimeout(5000);
63 | HttpURLConnection.setRequestMethod("GET");
64 | BufferedReader BufferedReader = new BufferedReader(new InputStreamReader(HttpURLConnection.getInputStream()));
65 | String String = "";
66 | StringBuffer StringBuffer = new StringBuffer();
67 | while ((String = BufferedReader.readLine()) != null) {
68 | StringBuffer.append(String);
69 | }
70 | return StringBuffer.toString();
71 | }
72 |
73 |
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/OData.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils
2 |
3 | import com.itos.xplanforhyper.datatype.ConfigData
4 |
5 | object OData {
6 | var configdata = ConfigData()
7 | var is_have_premissipn = false
8 | val updataUrl = "https://itos.codegang.top/share/XPlan/Hpyer/app_update.json"
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/OLog.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils
2 |
3 | import android.util.Log
4 | import com.itos.xplanforhyper.BuildConfig
5 |
6 | object OLog {
7 | fun i(tag: String, msg: String) {
8 | if (BuildConfig.DEBUG) Log.i("[调试信息]$tag", msg)
9 | }
10 | fun e(tag:String, t: Throwable) = Log.e("[错误]$tag", t.stackTraceToString())
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/OPackage.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils
2 |
3 | import android.content.pm.PackageManager
4 | import android.graphics.drawable.Drawable
5 |
6 | object OPackage {
7 | fun isInstalled(packageName: String, packageManager: PackageManager): Boolean {
8 | try {
9 | val packageInfo = packageManager.getPackageInfo(packageName, 0)
10 | OLog.i("应用安装判断", "$packageName 已安装")
11 | return packageInfo != null
12 | } catch (ep: Throwable) {
13 | OLog.i("应用安装判断", "$packageName 未安装")
14 | }
15 | return false
16 | }
17 |
18 | fun getAppIconByPackageName(packageName: String, packageManager: PackageManager): Drawable? {
19 | return try {
20 | val applicationInfo = packageManager.getApplicationInfo(packageName, 0)
21 | packageManager.getApplicationIcon(applicationInfo)
22 | } catch (e: PackageManager.NameNotFoundException) {
23 | e.printStackTrace()
24 | null
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/OShizuku.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils
2 |
3 | import android.content.pm.PackageManager
4 | import android.os.Build
5 | import android.os.IBinder
6 | import android.os.ParcelFileDescriptor
7 | import android.os.SystemClock
8 | import android.view.InputEvent
9 | import android.view.KeyEvent
10 | import android.widget.Toast
11 | import com.itos.xplanforhyper.BuildConfig
12 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
13 | import org.lsposed.hiddenapibypass.HiddenApiBypass
14 | import rikka.shizuku.Shizuku
15 | import rikka.shizuku.ShizukuBinderWrapper
16 | import rikka.shizuku.SystemServiceHelper
17 |
18 | object OShizuku {
19 | private val myUserId = android.os.Process.myUserHandle().hashCode()
20 | private val isRoot get() = Shizuku.getUid() == 0
21 | private val userId get() = if (isRoot) myUserId else 0
22 | private val callerPackage get() = if (isRoot) BuildConfig.APPLICATION_ID else "com.android.shell"
23 |
24 | private fun asInterface(className: String, serviceName: String): Any =
25 | ShizukuBinderWrapper(SystemServiceHelper.getSystemService(serviceName)).let {
26 | Class.forName("$className\$Stub").run {
27 | if (target(Build.VERSION_CODES.P)) HiddenApiBypass.invoke(
28 | this,
29 | null,
30 | "asInterface",
31 | it
32 | )
33 | else getMethod("asInterface", IBinder::class.java).invoke(null, it)
34 | }
35 | }
36 |
37 | private fun target(api: Int): Boolean = Build.VERSION.SDK_INT >= api
38 | val lockScreen
39 | get() = runCatching {
40 | val input = asInterface("android.hardware.input.IInputManager", "input")
41 | val inject = input::class.java.getMethod(
42 | "injectInputEvent", InputEvent::class.java, Int::class.java
43 | )
44 | val now = SystemClock.uptimeMillis()
45 | inject.invoke(
46 | input, KeyEvent(now, now, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER, 0), 0
47 | )
48 | inject.invoke(
49 | input, KeyEvent(now, now, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_POWER, 0), 0
50 | )
51 | true
52 | }.getOrElse {
53 | false
54 | }
55 |
56 | private fun forceStopApp(packageName: String) = runCatching {
57 | asInterface("android.app.IActivityManager", "activity").let {
58 | if (target(Build.VERSION_CODES.P)) HiddenApiBypass.invoke(
59 | it::class.java, it, "forceStopPackage", packageName, userId
60 | ) else it::class.java.getMethod(
61 | "forceStopPackage", String::class.java, Int::class.java
62 | ).invoke(
63 | it, packageName, userId
64 | )
65 | }
66 | true
67 | }.getOrElse {
68 | false
69 | }
70 |
71 | fun setAppDisabled(packageName: String, disabled: Boolean){
72 |
73 | if (disabled) forceStopApp(packageName)
74 | runCatching {
75 | val pm = asInterface("android.content.pm.IPackageManager", "package")
76 | val newState = when {
77 | !disabled -> PackageManager.COMPONENT_ENABLED_STATE_ENABLED
78 | isRoot -> PackageManager.COMPONENT_ENABLED_STATE_DISABLED
79 | else -> PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
80 | }
81 | pm::class.java.getMethod(
82 | "setApplicationEnabledSetting",
83 | String::class.java,
84 | Int::class.java,
85 | Int::class.java,
86 | Int::class.java,
87 | String::class.java
88 | ).invoke(pm, packageName, newState, 0, myUserId, BuildConfig.APPLICATION_ID)
89 | }.onFailure {
90 | }
91 |
92 | }
93 |
94 | fun setAppHidden(packageName: String, hidden: Boolean): Boolean {
95 | if (hidden) forceStopApp(packageName)
96 | return runCatching {
97 | val pm = asInterface("android.content.pm.IPackageManager", "package")
98 | pm::class.java.getMethod(
99 | "setApplicationHiddenSettingAsUser",
100 | String::class.java,
101 | Boolean::class.java,
102 | Int::class.java
103 | ).invoke(pm, packageName, hidden, userId) as Boolean
104 | }.getOrElse {
105 | false
106 | }
107 | }
108 |
109 | fun checkShizuku() {
110 | try {
111 | if (Shizuku.checkSelfPermission() != PackageManager.PERMISSION_GRANTED) Shizuku.requestPermission(
112 | 0
113 | ) else app.c = true
114 | } catch (e: java.lang.Exception) {
115 | if (app.checkSelfPermission("moe.shizuku.manager.permission.API_V23") == PackageManager.PERMISSION_GRANTED) app.c =
116 | true
117 | if (e.javaClass == IllegalStateException::class.java) {
118 | app.b = false
119 | }
120 | }
121 | if (!app.b || !app.c) {
122 | Toast.makeText(
123 | app,
124 | "Shizuku " + (if (app.b) "已运行" else "未运行") + if (app.c) " 已授权" else " 未授权",
125 | Toast.LENGTH_LONG
126 | ).show()
127 | }
128 | }
129 | private val ParcelFileDescriptor.text
130 | get() = ParcelFileDescriptor.AutoCloseInputStream(this)
131 | .use { it.bufferedReader().readText() }
132 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/OTarget.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils
2 |
3 | import android.os.Build
4 |
5 | object OTarget {
6 | private fun target(api: Int): Boolean = Build.VERSION.SDK_INT >= api
7 |
8 | val N = target(Build.VERSION_CODES.N)
9 | val O = target(Build.VERSION_CODES.O)
10 | val P = target(Build.VERSION_CODES.P)
11 | val Q = target(Build.VERSION_CODES.Q)
12 | val T = target(Build.VERSION_CODES.TIRAMISU)
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/OUI.kt:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils
2 |
3 | import android.content.Intent
4 | import android.graphics.BitmapFactory
5 | import android.net.Uri
6 | import android.provider.Settings
7 | import android.widget.ImageView
8 | import androidx.appcompat.app.AlertDialog
9 | import com.google.android.material.dialog.MaterialAlertDialogBuilder
10 | import com.itos.xplanforhyper.XPlanForHyper.Companion.app
11 | import java.io.IOException
12 |
13 |
14 | object OUI {
15 |
16 | fun check_secure_premission() {
17 | try {
18 | Settings.Secure.putString(app.contentResolver, "xplan", "test")
19 | OData.is_have_premissipn = true
20 | } catch (e: Exception) {
21 | OLog.e("写入安全设置权限异常", e)
22 | OLog.i("写入安全设置权限异常", "$app.b $app.c")
23 | if (app.b && app.c) {
24 | val temp = app.ShizukuExec("pm grant com.itos.xplan android.permission.WRITE_SECURE_SETTINGS".toByteArray())
25 | if (temp == "") {
26 | OData.is_have_premissipn = true
27 | } else {
28 | OData.is_have_premissipn = false
29 | OLog.i("设置 写入安全设置权限异常", temp!!)
30 | }
31 | } else {
32 | OShizuku.checkShizuku()
33 | }
34 |
35 | }
36 | }
37 |
38 | fun openLink(url: String) {
39 | app.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
40 | }
41 |
42 | fun showImageDialog(imageName: String) {
43 | val builder: AlertDialog.Builder = MaterialAlertDialogBuilder(app)
44 |
45 | // 创建一个 ImageView 并添加到对话框中
46 | val imageView = ImageView(app)
47 | try {
48 | val `is` = app.assets.open(imageName)
49 | val bitmap = BitmapFactory.decodeStream(`is`)
50 | imageView.setImageBitmap(bitmap)
51 | imageView.scaleType = ImageView.ScaleType.FIT_CENTER
52 | } catch (e: IOException) {
53 | e.printStackTrace()
54 | }
55 | builder.setView(imageView) // 将 ImageView 加到对话框中
56 | builder.setNegativeButton("OK") { dialog, which ->
57 | // 点击 OK 按钮后的操作
58 | dialog.dismiss()
59 | }
60 | builder.show() // 显示对话框
61 | }
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/xplanforhyper/utils/SpUtils.java:
--------------------------------------------------------------------------------
1 | package com.itos.xplanforhyper.utils;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.provider.Settings;
6 |
7 | public class SpUtils {
8 |
9 | /**
10 | * 保存在手机里面的文件名
11 | */
12 | private static final String FILE_NAME = "share_date";
13 |
14 |
15 | /**
16 | * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
17 | * @param context
18 | * @param key
19 | * @param object
20 | */
21 | public static void setParam(Context context , String key, Object object){
22 |
23 | String type = object.getClass().getSimpleName();
24 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
25 | SharedPreferences.Editor editor = sp.edit();
26 |
27 | switch (type) {
28 | case "String":
29 | editor.putString(key, (String) object);
30 | break;
31 | case "Integer":
32 | editor.putInt(key, (Integer) object);
33 | break;
34 | case "Boolean":
35 | editor.putBoolean(key, (Boolean) object);
36 | break;
37 | case "Float":
38 | editor.putFloat(key, (Float) object);
39 | break;
40 | case "Long":
41 | editor.putLong(key, (Long) object);
42 | break;
43 | }
44 |
45 | editor.apply();
46 | }
47 |
48 |
49 | /**
50 | * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
51 | * @param context
52 | * @param key
53 | * @param defaultObject
54 | * @return
55 | */
56 | public static Object getParam(Context context , String key, Object defaultObject){
57 | String type = defaultObject.getClass().getSimpleName();
58 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
59 |
60 | switch (type) {
61 | case "String":
62 | return sp.getString(key, (String) defaultObject);
63 | case "Integer":
64 | return sp.getInt(key, (Integer) defaultObject);
65 | case "Boolean":
66 | return sp.getBoolean(key, (Boolean) defaultObject);
67 | case "Float":
68 | return sp.getFloat(key, (Float) defaultObject);
69 | case "Long":
70 | return sp.getLong(key, (Long) defaultObject);
71 | }
72 |
73 | return null;
74 | }
75 |
76 | public static void putSettingsParam(Context context , String fenqu,String key, Object object){
77 | String type = object.getClass().getSimpleName();
78 | switch (fenqu) {
79 | case "system":
80 | switch (type) {
81 | case "String":
82 | case "Boolean":
83 | Settings.System.putString(context.getContentResolver(), key, (String) object);
84 | break;
85 | case "Integer":
86 | Settings.System.putInt(context.getContentResolver(), key, (Integer) object);
87 | break;
88 | case "Float":
89 | Settings.System.putFloat(context.getContentResolver(), key, (Float) object);
90 | break;
91 | case "Long":
92 | Settings.System.putLong(context.getContentResolver(), key, (Long) object);
93 | break;
94 | }
95 | case "global":
96 | switch (type) {
97 | case "String":
98 | case "Boolean":
99 | Settings.Global.putString(context.getContentResolver(), key, (String) object);
100 | break;
101 | case "Integer":
102 | Settings.Global.putInt(context.getContentResolver(), key, (Integer) object);
103 | break;
104 | case "Float":
105 | Settings.Global.putFloat(context.getContentResolver(), key, (Float) object);
106 | break;
107 | case "Long":
108 | Settings.Global.putLong(context.getContentResolver(), key, (Long) object);
109 | break;
110 | }
111 | case "secure":
112 | switch (type) {
113 | case "String":
114 | case "Boolean":
115 | Settings.Secure.putString(context.getContentResolver(), key, (String) object);
116 | break;
117 | case "Integer":
118 | Settings.Secure.putInt(context.getContentResolver(), key, (Integer) object);
119 | break;
120 | case "Float":
121 | Settings.Secure.putFloat(context.getContentResolver(), key, (Float) object);
122 | break;
123 | case "Long":
124 | Settings.Secure.putLong(context.getContentResolver(), key, (Long) object);
125 | break;
126 | }
127 | }
128 | }
129 | public static String getSettingsParam(Context context , String fenqu,String key){
130 | switch (fenqu) {
131 | case "system":
132 | return Settings.System.getString(context.getContentResolver(), key);
133 | case "global":
134 | return Settings.Global.getString(context.getContentResolver(), key);
135 | case "secure":
136 | return Settings.Secure.getString(context.getContentResolver(), key);
137 | default:
138 | return "null";
139 | }
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_alipay.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_info.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_terminal.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_bilibili.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_outline_code.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_outline_coolapk.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_outline_giftcard.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_outline_info.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_outline_lisence.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_outline_qq.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_wechatpay.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_xplan.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_xplan_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_xplan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-hdpi/ic_launcher_xplan.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_xplan_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-hdpi/ic_launcher_xplan_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_xplan_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-hdpi/ic_launcher_xplan_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_xplan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-mdpi/ic_launcher_xplan.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_xplan_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-mdpi/ic_launcher_xplan_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_xplan_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-mdpi/ic_launcher_xplan_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_xplan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xhdpi/ic_launcher_xplan.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_xplan_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xhdpi/ic_launcher_xplan_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_xplan_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xhdpi/ic_launcher_xplan_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_xplan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxhdpi/ic_launcher_xplan.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_xplan_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxhdpi/ic_launcher_xplan_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_xplan_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxhdpi/ic_launcher_xplan_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xplan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xplan.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xplan_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xplan_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xplan_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xplan_round.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/licenses:
--------------------------------------------------------------------------------
1 | Android Jetpack (Apache 2.0): https://developer.android.com/jetpack
2 |
3 | Material Components for Android (Apache 2.0): https://github.com/material-components/material-components-android
4 |
5 | Shizuku (Apache 2.0): https://github.com/RikkaApps/Shizuku
6 |
7 | Shizuku-API (MIT): https://github.com/RikkaApps/Shizuku-API
8 |
9 | Kotlin (Apache 2.0): https://kotlinlang.org
10 |
11 | AndroidHiddenApiBypass (Apache 2.0): https://github.com/LSPosed/AndroidHiddenApiBypass
12 |
13 | Hail (GPL 3.0): https://github.com/aistra0528/Hail
14 |
15 | InstallerX (GPL 3.0): https://github.com/iamr0s/InstallerX
--------------------------------------------------------------------------------
/app/src/main/res/raw/moreapp:
--------------------------------------------------------------------------------
1 | vivo免root去温控: https://www.123pan.com/s/vYnqVv-b9hKd.html
2 |
3 | 系统优化APP:https://www.123pan.com/s/vYnqVv-PZhKd.html
4 |
5 | 蓝厂工具盒:https://www.123pan.com/s/vYnqVv-GZhKd.html
6 |
7 | DPM操作:https://codegang.lanzouq.com/i775411t1ucf?password=aii7
8 |
9 | PS:请下载网盘中最新版本号的apk安装
--------------------------------------------------------------------------------
/app/src/main/res/raw/optlist:
--------------------------------------------------------------------------------
1 | com.miui.video
2 | com.miui.player
3 | com.android.quicksearchbox
4 | com.miui.touchassistant
5 | com.miui.nextpay
6 | com.miui.newhome
7 | com.xiaomi.payment
8 | com.miui.yellowpage
9 | com.miui.hybrid.accessory
10 | com.xiaomi.vipaccount
11 | com.miui.hybrid
12 | com.xiaomi.scanner
13 | com.xiaomi.mibrain.speech
14 | com.miui.personalassistant
15 | com.miui.mishare.connectivity
16 | com.mipay.wallet
17 | com.miui.virtualsim
--------------------------------------------------------------------------------
/app/src/main/res/raw/pkglist:
--------------------------------------------------------------------------------
1 | com.xiaomi.joyose
2 | com.miui.voiceassist
3 | com.xiaomi.aiasst.vision
4 | com.android.browser
5 | com.miui.notes
6 | com.miui.contentextension
7 | com.android.email
8 | com.miui.voicetrigger
9 | com.android.updater
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
11 | #00000000
12 | @color/error_color_material_light
13 |
14 |
15 | #FF4A672D
16 | #FF0E2000
17 | #FFCBEEA5
18 | #FF57624A
19 | #FF386664
20 | #FFB3261E
21 |
22 | #FFAFD18C
23 | #FF334E17
24 | #FFBFCBAD
25 | #FFA0CFCC
26 | #FFF2B8B5
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_xplan_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #36374C
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | XHyper
3 | 许可证
4 | Beta
5 | 操作失败:%s
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [["test1", "1", "global"],["test2","2","system"],["test3","3","secure"]],
3 | "shell": "echo test",
4 | "restore ":"echo restore",
5 | "debug": "echo debug"
6 | }
7 |
--------------------------------------------------------------------------------
/app_update.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "22",
3 | "version_name": "Alpha-2.2",
4 | "url": "https://www.123pan.com/s/vYnqVv-vLhKd.html",
5 | "log": "加入 终端 功能\n优化部分实现方法",
6 | "isShowNotice": "true",
7 | "notice": "OS4不要用进程调整\nOS4可能效果不明显\n毕竟是新系统,没有什么负优化\n可以等后续推送一些实用小功能\n\n横屏显示有问题,可能不会修了"
8 | }
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | mavenCentral()
6 | maven { url =uri("https://dl.bintray.com/rikkaw/Shizuku") }
7 | maven { url = uri("https://jitpack.io") }
8 |
9 | }
10 | }
11 | plugins {
12 | id("com.android.application") version "8.1.1" apply false
13 | id("org.jetbrains.kotlin.android") version "1.8.10" apply false
14 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## For more details on how to configure your build environment visit
2 | # http://www.gradle.org/docs/current/userguide/build_environment.html
3 | #
4 | # Specifies the JVM arguments used for the daemon process.
5 | # The setting is particularly useful for tweaking memory settings.
6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8 | #
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #Sat Dec 30 21:06:08 CST 2023
14 | android.defaults.buildfeatures.buildconfig=true
15 | android.enableR8.fullMode=true
16 | android.nonTransitiveRClass=true
17 | android.useAndroidX=true
18 | kotlin.code.style=official
19 | org.gradle.jvmargs=-Xmx3072M -Dkotlin.daemon.jvm.options\="-Xmx2048M" -XX\:MaxPermSize\=512m -XX\:+HeapDumpOnOutOfMemoryError -Dfile.encoding\=UTF-8
20 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/XPlanForHyper/df9b94a67356b7a20de29126c1bbdab7ea19f28c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Nov 29 09:58:34 CST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | maven { url = uri("https://jitpack.io") }
7 | maven { url =uri("https://dl.bintray.com/rikkaw/Shizuku") }
8 |
9 | }
10 | }
11 | dependencyResolutionManagement {
12 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | }
18 |
19 | rootProject.name = "XPlanForHyper"
20 | include(":app")
21 |
--------------------------------------------------------------------------------