Repository: HuanCheng65/MIUILevelChecker Branch: master Commit: ee29d3e2628b Files: 52 Total size: 81.2 KB Directory structure: gitextract_6b_kueyn/ ├── .github/ │ └── workflows/ │ └── android.yml ├── .gitignore ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── huanchengfly/ │ │ └── miui/ │ │ └── checker/ │ │ └── ExampleInstrumentedTest.kt │ └── main/ │ ├── AndroidManifest.xml │ ├── assets/ │ │ └── xposed_init │ ├── java/ │ │ └── com/ │ │ └── huanchengfly/ │ │ └── miui/ │ │ └── checker/ │ │ ├── Extensions.kt │ │ ├── MainActivity.kt │ │ ├── utils/ │ │ │ ├── DeviceUtil.kt │ │ │ ├── OSUtil.kt │ │ │ ├── VersionUtil.kt │ │ │ └── XposedUtil.kt │ │ └── xposed/ │ │ └── FullDeviceLevelModule.kt │ └── res/ │ ├── animator/ │ │ └── appbar_elevation.xml │ ├── drawable/ │ │ ├── emoji_confused_face.xml │ │ ├── emoji_expressionless_face.xml │ │ ├── emoji_grinning_squinting_face.xml │ │ ├── emoji_thinking_face.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_logo_github.xml │ │ ├── ic_round_developer_board.xml │ │ ├── ic_round_exit_to_app.xml │ │ ├── ic_round_help.xml │ │ ├── ic_round_memory.xml │ │ ├── ic_round_offline_bolt.xml │ │ ├── ic_round_phone_android.xml │ │ ├── ic_round_score.xml │ │ ├── ic_round_settings.xml │ │ ├── ic_round_smartphone.xml │ │ └── ic_round_storage.xml │ ├── layout/ │ │ ├── activity_main.xml │ │ └── dialog_about.xml │ ├── menu/ │ │ └── menu_main.xml │ ├── mipmap-anydpi-v26/ │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ ├── values/ │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── themes.xml │ ├── values-en/ │ │ └── strings.xml │ └── values-es/ │ └── strings.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/android.yml ================================================ name: Android CI on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: set up JDK 1.8 uses: actions/setup-java@v1 with: java-version: 1.8 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle run: ./gradlew assembleRelease - name: Upload APK uses: actions/upload-artifact@v2 with: name: app-release path: app/build/outputs/apk/release/ ================================================ FILE: .gitignore ================================================ .DS_Store .cxx # Built application files *.apk *.ap_ app/release/ # Files for the ART/Dalvik VM *.dex # Java class files *.class # Generated files bin/ gen/ out/ output.json # Gradle files .gradle/ build/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ app/lint.xml # app/proguard-project.txt # Log Files *.log # Android Studio Navigation editor temp files .navigation/ # Android Studio captures folder captures/ # IntelliJ *.iml .idea/ # Keystore files # Uncomment the following line if you do not want to check your keystore files in. *.jks keystore.properties # External native build folder generated in Android Studio 2.2 and later .externalNativeBuild # Google Services (e.g. APIs or Firebase) google-services.json # Freeline freeline.py freeline/ freeline_project_description.json # fastlane fastlane/report.xml fastlane/Preview.html fastlane/screenshots fastlane/test_output fastlane/readme.md ================================================ FILE: README.md ================================================ # MIUILevelChecker 帮助你查看自己的机型在 MIUI 12.5 上的分级 ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ plugins { id 'com.android.application' id 'kotlin-android' } android { compileSdkVersion 29 defaultConfig { applicationId "com.huanchengfly.miui.checker" minSdkVersion 28 targetSdkVersion 29 versionCode 1001 versionName "1.0.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildFeatures { viewBinding = true } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) compileOnly 'de.robv.android.xposed:api:82' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.0' testImplementation 'junit:junit:4.13.1' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: app/src/androidTest/java/com/huanchengfly/miui/checker/ExampleInstrumentedTest.kt ================================================ package com.huanchengfly.miui.checker import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith /** * Instrumented test, which will execute on an Android device. * * See [testing documentation](http://d.android.com/tools/testing). */ @RunWith(AndroidJUnit4::class) class ExampleInstrumentedTest { @Test fun useAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.miui.fuck", appContext.packageName) } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/assets/xposed_init ================================================ com.huanchengfly.miui.checker.xposed.FullDeviceLevelModule ================================================ FILE: app/src/main/java/com/huanchengfly/miui/checker/Extensions.kt ================================================ package com.huanchengfly.miui.checker import android.app.Activity import android.content.Context import android.content.Intent import android.net.Uri import android.provider.Browser import android.view.LayoutInflater import android.widget.Toast import androidx.viewbinding.ViewBinding inline fun Activity.bindView(): Binding { val clazz = Binding::class.java val inflateMethod = clazz.getDeclaredMethod("inflate", LayoutInflater::class.java) val binding: Binding = inflateMethod.invoke(null, layoutInflater) as Binding setContentView(binding.root) return binding } fun Context.toastShort(text: String) { Toast.makeText(this, text, Toast.LENGTH_SHORT).show() } fun Context.toastShort(resId: Int, vararg args: Any) { Toast.makeText(this, getString(resId, *args), Toast.LENGTH_SHORT).show() } inline fun Context.goToActivity() { startActivity(Intent(this, T::class.java)) } inline fun Context.goToActivity(pre: Intent.() -> Unit) { startActivity(Intent(this, T::class.java).apply(pre)) } fun Context.startApp(packageName: String) { startActivity(packageManager.getLaunchIntentForPackage(packageName)) } fun Context.startURL(uri: Uri) { startActivity(Intent(Intent.ACTION_VIEW, uri).apply { putExtra(Browser.EXTRA_APPLICATION_ID, packageName) }) } fun Context.startURL(url: String) { startURL(Uri.parse(url)) } ================================================ FILE: app/src/main/java/com/huanchengfly/miui/checker/MainActivity.kt ================================================ package com.huanchengfly.miui.checker import android.annotation.SuppressLint import android.os.Build import android.os.Bundle import android.text.Html import android.view.Menu import android.view.MenuItem import android.view.View import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import com.huanchengfly.miui.checker.databinding.ActivityMainBinding import com.huanchengfly.miui.checker.databinding.DialogAboutBinding import com.huanchengfly.miui.checker.utils.DeviceUtil import com.huanchengfly.miui.checker.utils.OSUtil import com.huanchengfly.miui.checker.utils.VersionUtil import com.huanchengfly.miui.checker.utils.XposedUtil class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = bindView() setSupportActionBar(binding.toolbar) if (OSUtil.isMIUI()) { load() } else { AlertDialog.Builder(this) .setTitle(R.string.title_dialog_not_miui) .setMessage(R.string.text_dialog_not_miui) .setPositiveButton(R.string.btn_ok, null) .show() } } private fun load() { binding.contentContainer.visibility = View.VISIBLE var manufacturer = Character.toUpperCase(Build.MANUFACTURER[0]).toString() + Build.MANUFACTURER.substring(1) if (Build.BRAND != Build.MANUFACTURER) { manufacturer += " " + Character.toUpperCase(Build.BRAND[0]) + Build.BRAND.substring(1) } manufacturer += " " + Build.MODEL binding.phoneInfo.text = manufacturer binding.socInfo.text = DeviceUtil.getHardwareInfo() binding.ramInfo.text = getString(R.string.text_ram_info, DeviceUtil.getTotalRam()) when (DeviceUtil.getDeviceLevel()) { DeviceUtil.DEVICE_HIGH_END -> { binding.statusIcon.setImageResource(R.drawable.emoji_grinning_squinting_face) binding.statusTitle.setText(R.string.status_title_full) binding.statusText.setText(R.string.status_text_full) binding.deviceLevelInfo.setText(R.string.level_text_high_end) } DeviceUtil.DEVICE_MIDDLE -> { binding.statusIcon.setImageResource(R.drawable.emoji_expressionless_face) binding.statusTitle.setText(R.string.status_title_basic) binding.statusText.setText(R.string.status_text_basic) binding.deviceLevelInfo.setText(R.string.level_text_middle) } DeviceUtil.DEVICE_PRIMARY -> { binding.statusIcon.setImageResource(R.drawable.emoji_confused_face) binding.statusTitle.setText(R.string.status_title_none) binding.statusText.setText(R.string.status_text_none) binding.deviceLevelInfo.setText(R.string.level_text_primary) } DeviceUtil.DEVICE_UNKNOWN -> { binding.statusIcon.setImageResource(R.drawable.emoji_thinking_face) binding.statusTitle.setText(R.string.status_title_unknown) binding.statusText.setText(R.string.status_text_unknown) binding.deviceLevelInfo.setText(R.string.level_text_unknown) } } if (DeviceUtil.isMiuiLite()) { binding.miuiLiteInfo.setText(R.string.miui_lite_yes) } else { binding.miuiLiteInfo.setText(R.string.miui_lite_no) } binding.miuiLiteHelpBtn.setOnClickListener { AlertDialog.Builder(this) .setTitle(R.string.title_dialog_whats_this) .setMessage(R.string.text_dialog_miui_lite_help) .setPositiveButton(R.string.btn_ok, null) .show() } if (XposedUtil.isModuleEnabled) { binding.xposedModuleStatusCard.setCardBackgroundColor(getColor(R.color.green_400)) binding.xposedModuleStatus.setText(R.string.title_xposed_module_enabled) binding.xposedModuleStatusMessage.text = Html.fromHtml(getString(R.string.text_xposed_module_enabled), Html.FROM_HTML_MODE_COMPACT) binding.xposedModuleStatusActionBtn.setImageResource(R.drawable.ic_round_settings) binding.xposedModuleStatusActionBtn.visibility = View.GONE } else if (!XposedUtil.isManagerInstalled(this)) { binding.xposedModuleStatusCard.visibility = View.GONE } else { binding.xposedModuleStatusCard.setCardBackgroundColor(getColor(R.color.red_A400)) binding.xposedModuleStatus.setText(R.string.title_xposed_module_not_actived) binding.xposedModuleStatusMessage.text = Html.fromHtml(getString(R.string.text_xposed_module_not_enabled), Html.FROM_HTML_MODE_COMPACT) binding.xposedModuleStatusActionBtn.setImageResource(R.drawable.ic_round_exit_to_app) binding.xposedModuleStatusCard.setOnClickListener { startApp(XposedUtil.getInstalledManagerPackageName(this)!!) } } } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) return true } @SuppressLint("SetTextI18n") override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.menu_about) { val dialogViewBinding = DialogAboutBinding.inflate(layoutInflater) dialogViewBinding.dialogAboutText.text = getString(R.string.text_dialog_about, VersionUtil.getVersionName(this), VersionUtil.getVersionCode(this)) dialogViewBinding.btnGithub.setOnClickListener { startURL(getString(R.string.link_source)) } AlertDialog.Builder(this) .setView(dialogViewBinding.root) .show() } return false } } ================================================ FILE: app/src/main/java/com/huanchengfly/miui/checker/utils/DeviceUtil.kt ================================================ package com.huanchengfly.miui.checker.utils import android.text.TextUtils import android.util.Log import java.io.* import java.util.* import java.util.regex.Matcher import java.util.regex.Pattern object DeviceUtil { private const val TAG = "DeviceUtil" private val MT_PATTERN: Pattern = Pattern.compile("MT([\\d]{2})([\\d]+)") private val SM_PATTERN: Pattern = Pattern.compile("Inc ([A-Z]+)([\\d]+)") const val DEVICE_HIGH_END = 2 const val DEVICE_MIDDLE = 1 const val DEVICE_PRIMARY = 0 const val DEVICE_UNKNOWN = -1 private const val ARM_V8 = 8 private const val CORE_COUNT = 8 private const val BIG_CORE_FREQ = 2000000 private const val MIDDLE_FREQ = 2300000 private const val HIGH_FREQ = 2700000 private const val MTK_DIMENSITY = 68 private const val D800 = 73 private const val MIDDLE_EIGHT_SERIES = 45 private const val HEX = "0x" private const val CPU_MAX_INFO_FORMAT = "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq" private const val IMPLEMENTOR = "CPU implementer" private const val ARCHITECTURE = "CPU architecture" private const val PART = "CPU part" private const val PROCESSOR = "processor" private const val QUALCOMM = "Qualcomm" private const val SNAPDRAGON = "sm" private const val SEPARATOR = ": " private var mLevel = DEVICE_UNKNOWN private var mTotalRam = Int.MAX_VALUE fun getDeviceLevel(): Int { if (mLevel != DEVICE_UNKNOWN) { return mLevel } if (isMiuiLite()) { mLevel = DEVICE_PRIMARY } else { mLevel = getCpuLevel() if (mLevel == DEVICE_MIDDLE && getTotalRam() <= 4) { mLevel = DEVICE_PRIMARY } } return mLevel } fun getTotalRam(): Int { if (mTotalRam == Int.MAX_VALUE) { mTotalRam = try { ((Class.forName("miui.util.HardwareInfo") .getMethod("getTotalPhysicalMemory") .invoke(null) as Long).toLong() / 1024 / 1024 / 1024).toInt() } catch (e: Exception) { Log.e(TAG, "${e.message}") 0 } } return mTotalRam } fun isMiuiLite(): Boolean { return try { Class.forName("miui.os.Build").getDeclaredField("IS_MIUI_LITE_VERSION") .get(null) as Boolean } catch (e: Exception) { e.printStackTrace() false } } private fun createCpuInfo(str: String): CpuInfo { val cpuInfo = CpuInfo() cpuInfo.id = str.toInt() val contentFromFileInfo = getContentFromFileInfo( String.format( Locale.ENGLISH, CPU_MAX_INFO_FORMAT, cpuInfo.id!! ) ) if (contentFromFileInfo != null) { cpuInfo.maxFreq = contentFromFileInfo.toInt() } return cpuInfo } private fun getContentFromFileInfo(filePath: String): String? { try { val fileInputStream = FileInputStream(filePath) val inputStreamReader = InputStreamReader(fileInputStream) val bufferedReader = BufferedReader(inputStreamReader) val str = bufferedReader.readLine() bufferedReader.close() fileInputStream.close() inputStreamReader.close() return str } catch (e: IOException) { e.printStackTrace() } return null } private fun getCpuInfoList(): List { val arrayList = mutableListOf() try { val scanner = Scanner(File("/proc/cpuinfo")) var cpuInfo: CpuInfo? = null while (scanner.hasNextLine()) { val split: List = scanner.nextLine().split(SEPARATOR) if (split.size > 1) { cpuInfo = parseLine(split, arrayList, cpuInfo) } } } catch (e: java.lang.Exception) { Log.e(TAG, "getChipSetFromCpuInfo failed", e) } return arrayList } private fun getCpuStats(): CpuStats { val cpuInfoList: List = getCpuInfoList() val cpuStats = CpuStats() if (cpuInfoList.size < CORE_COUNT) { cpuStats.level = DEVICE_PRIMARY } doCpuStats(cpuStats, cpuInfoList) return cpuStats } private fun doCpuStats(cpuStats: CpuStats, list: List) { for (next in list) { if (next.architecture!! < ARM_V8) { cpuStats.level = DEVICE_PRIMARY } if (next.maxFreq > cpuStats.maxFreq) { cpuStats.maxFreq = next.maxFreq } if (next.maxFreq >= BIG_CORE_FREQ) { cpuStats.bigCoreCount++ } else { cpuStats.smallCoreCount++ } } decideLevel(cpuStats) } private fun decideLevel(cpuStats: CpuStats) { if (cpuStats.level == DEVICE_UNKNOWN) { cpuStats.level = when { cpuStats.bigCoreCount >= 4 -> when { cpuStats.maxFreq > HIGH_FREQ -> DEVICE_HIGH_END cpuStats.maxFreq > MIDDLE_FREQ -> DEVICE_MIDDLE else -> DEVICE_PRIMARY } cpuStats.maxFreq > MIDDLE_FREQ -> DEVICE_MIDDLE else -> DEVICE_PRIMARY } } } private fun parseLine( strArr: List, list: MutableList, cpuInfo: CpuInfo? ): CpuInfo? { val trim = strArr[1].trim { it <= ' ' } return if (strArr[0].contains(PROCESSOR) && TextUtils.isDigitsOnly(trim)) { createCpuInfo(trim).also { list.add(it) } } else { if (cpuInfo != null) { getCpuInfo(strArr[0], trim, cpuInfo) } cpuInfo } } private fun getCpuInfo(str: String, str2: String, cpuInfo: CpuInfo) { when { str.contains(IMPLEMENTOR) -> { cpuInfo.implementor = toInt(str2) } str.contains(ARCHITECTURE) -> { cpuInfo.architecture = toInt(str2) } str.contains(PART) -> { cpuInfo.part = toInt(str2) } } } private fun toInt(str: String): Int { return if (str.startsWith(HEX)) { str.substring(2).toInt(16) } else { str.toInt() } } fun getHardwareInfo(): String { return try { val scanner = Scanner(File("/proc/cpuinfo")) while (scanner.hasNextLine()) { val nextLine = scanner.nextLine() if (!scanner.hasNextLine()) { val split = nextLine.split(SEPARATOR).toTypedArray() if (split.size > 1) { return split[1] } } } "" } catch (e: java.lang.Exception) { Log.e(TAG, "getChipSetFromCpuInfo failed", e) "" } } private fun getCpuLevel(): Int { val hardwareInfo = getHardwareInfo() val level = if (hardwareInfo.isNotEmpty()) { if (hardwareInfo.contains(QUALCOMM)) { getQualcommCpuLevel(hardwareInfo) } else { getMtkCpuLevel(hardwareInfo) } } else { DEVICE_UNKNOWN } return if (level == DEVICE_UNKNOWN) { getCpuStats().level } else { level } } private fun getMtkCpuLevel(str: String): Int { val matcher: Matcher = MT_PATTERN.matcher(str) if (!matcher.find()) { return DEVICE_UNKNOWN } val group: String? = matcher.group(1) val group2: String? = matcher.group(2) if (group == null || group2 == null) { return DEVICE_UNKNOWN } val parseInt = group.toInt() val parseInt2 = group2.toInt() return if (parseInt != MTK_DIMENSITY || parseInt2 < D800) { DEVICE_PRIMARY } else { DEVICE_MIDDLE } } private fun getQualcommCpuLevel(str: String): Int { val matcher: Matcher = SM_PATTERN.matcher(str) if (!matcher.find()) { return DEVICE_UNKNOWN } val group: String? = matcher.group(1) val group2: String? = matcher.group(2) if (group == null || group2 == null || group.toLowerCase(Locale.ENGLISH) != SNAPDRAGON) { return DEVICE_UNKNOWN } val parseInt = group2.substring(0, 1).toInt() val parseInt2 = group2.substring(1).toInt() if (parseInt >= 8 && parseInt2 > MIDDLE_EIGHT_SERIES) { return DEVICE_HIGH_END } return if (parseInt >= 7) { DEVICE_MIDDLE } else { DEVICE_PRIMARY } } class CpuInfo { var id: Int? = null var implementor: Int? = null var architecture: Int? = null var part: Int? = null var maxFreq: Int = 0 override fun toString(): String { return "CpuInfo(id=$id, implementor=$implementor, architecture=$architecture, part=$part, maxFreq=$maxFreq)" } } class CpuStats { var level: Int = DEVICE_UNKNOWN var maxFreq: Int = 0 var bigCoreCount: Int = 0 var smallCoreCount: Int = 0 override fun toString(): String { return "CpuStats(level=$level, maxFreq=$maxFreq, bigCoreCount=$bigCoreCount, smallCoreCount=$smallCoreCount)" } } } ================================================ FILE: app/src/main/java/com/huanchengfly/miui/checker/utils/OSUtil.kt ================================================ package com.huanchengfly.miui.checker.utils import java.io.File object OSUtil { fun isMIUI(): Boolean { return File("/system/framework/framework-miui-res.apk").exists() || File("/system/app/miui/miui.apk").exists() || File("/system/app/miuisystem/miuisystem.apk").exists() } } ================================================ FILE: app/src/main/java/com/huanchengfly/miui/checker/utils/VersionUtil.kt ================================================ package com.huanchengfly.miui.checker.utils import android.content.Context import android.content.pm.PackageManager object VersionUtil { fun getVersionCode(context: Context): Int { var versionCode = 0 try { versionCode = context.packageManager.getPackageInfo(context.packageName, 0).versionCode } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } return versionCode } fun getVersionName(context: Context): String { var verName = "" try { verName = context.packageManager.getPackageInfo(context.packageName, 0).versionName } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } return verName } } ================================================ FILE: app/src/main/java/com/huanchengfly/miui/checker/utils/XposedUtil.kt ================================================ package com.huanchengfly.miui.checker.utils import android.content.Context import android.content.pm.PackageInfo import android.content.pm.PackageManager object XposedUtil { private val MANAGER_PACKAGE_NAME_LIST = listOf( "org.meowcat.edxposed.manager" ) @JvmStatic val isModuleEnabled: Boolean get() = false fun isManagerInstalled(context: Context): Boolean { return getInstalledManagerPackageName(context) != null } fun getInstalledManagerPackageName(context: Context): String? { return MANAGER_PACKAGE_NAME_LIST.firstOrNull { checkAppInstalled(context, it) } } fun checkAppInstalled(context: Context, pkgName: String): Boolean { if (pkgName.isEmpty()) { return false } var packageInfo: PackageInfo? try { packageInfo = context.packageManager.getPackageInfo(pkgName, 0) } catch (e: PackageManager.NameNotFoundException) { packageInfo = null e.printStackTrace() } return packageInfo != null } } ================================================ FILE: app/src/main/java/com/huanchengfly/miui/checker/xposed/FullDeviceLevelModule.kt ================================================ package com.huanchengfly.miui.checker.xposed import de.robv.android.xposed.IXposedHookLoadPackage import de.robv.android.xposed.XC_MethodReplacement import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.callbacks.XC_LoadPackage class FullDeviceLevelModule : IXposedHookLoadPackage { override fun handleLoadPackage(packageParam: XC_LoadPackage.LoadPackageParam) { val pkgName = packageParam.packageName if (SELF_PACKAGE_NAME == pkgName) { val clazz = XposedHelpers.findClassIfExists( "$SELF_PACKAGE_NAME.utils.XposedUtil", packageParam.classLoader ) ?: return XposedHelpers.findAndHookMethod( clazz, "isModuleEnabled", XC_MethodReplacement.returnConstant(true) ) } else if ("miui" in pkgName || "xiaomi" in pkgName) { val clazz = XposedHelpers.findClassIfExists( MIUIX_DEVICE_UTILS_CLASS_NAME, packageParam.classLoader ) ?: return XposedHelpers.findAndHookMethod( clazz, "getDeviceLevel", XC_MethodReplacement.returnConstant(2) ) } } companion object { const val SELF_PACKAGE_NAME = "com.huanchengfly.miui.checker" const val MIUIX_DEVICE_UTILS_CLASS_NAME = "miuix.animation.utils.DeviceUtils" } } ================================================ FILE: app/src/main/res/animator/appbar_elevation.xml ================================================ ================================================ FILE: app/src/main/res/drawable/emoji_confused_face.xml ================================================ ================================================ FILE: app/src/main/res/drawable/emoji_expressionless_face.xml ================================================ ================================================ FILE: app/src/main/res/drawable/emoji_grinning_squinting_face.xml ================================================ ================================================ FILE: app/src/main/res/drawable/emoji_thinking_face.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_launcher_foreground.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_logo_github.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_developer_board.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_exit_to_app.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_help.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_memory.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_offline_bolt.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_phone_android.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_score.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_settings.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_smartphone.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_round_storage.xml ================================================ ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: app/src/main/res/layout/dialog_about.xml ================================================ ================================================ FILE: app/src/main/res/menu/menu_main.xml ================================================ ================================================ FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml ================================================ ================================================ FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml ================================================ ================================================ FILE: app/src/main/res/values/arrays.xml ================================================ com.miui.screenrecorder com.xiaomi.vipaccount com.miui.miwallpaper.miweatherwallpaper com.miui.backup com.miui.huanji com.miui.hybrid com.miui.securitycore com.miui.compass com.miui.aod com.miui.voicetrigger com.xiaomi.mirror com.miui.audiomonitor com.miui.calculator com.miui.weather2 com.xiaomi.scanner com.miui.home ================================================ FILE: app/src/main/res/values/colors.xml ================================================ #448AFF #2962FF #66BB6A #FF1744 #FFD600 #FF000000 #FFFFFFFF @color/blue_A200 ================================================ FILE: app/src/main/res/values/dimens.xml ================================================ 8dp 0dp ================================================ FILE: app/src/main/res/values/strings.xml ================================================ MIUILevelChecker 模块激活后,可以为您强行开启 MIUI 12.5 的完整动画 设备信息 完整支持 部分支持 不支持 未知 您的设备支持 MIUI 12.5 完整动画 您的设备只支持 MIUI 12.5 部分动画 您的设备不支持 MIUI 12.5 的动画 无法获取您的设备等级 高端 中端 低端 未知 MIUI “精简版” 非 MIUI “精简版” MIUI 机型分级 Xposed 模块已启用 Xposed 模块已激活,但未启用 Xposed 模块未激活 这是什么? 注意:由于设备性能限制,部分动画可能会导致卡顿。]]> 轻按此处可跳转至 Xposed 管理器以启用模块。
注意:由于设备性能限制,部分动画可能会导致卡顿。]]>
OK MIUI 可能会将部分机型标记为 \"Lite\" 版(此处译为“精简版”),被标记为精简版的设备无论性能如何都会被认为是“低端”设备,禁用绝大多数动画。 %dGB 运行内存 您似乎没有使用 MIUI 系统 本软件的检测结果仅适用于正在使用 MIUI 系统的手机。 关于 版本: %1$s(%2$d)\n帮助你查看自己的机型在 MIUI 12.5 上的分级。 https://github.com/HuanCheng65/MIUILevelChecker Github coolapk
================================================ FILE: app/src/main/res/values/themes.xml ================================================ ================================================ FILE: app/src/main/res/values-en/strings.xml ================================================ MIUILevelChecker After the module is activated, you can forcibly activate the full animation of MIUI 12.5 Device Info Full support Partial support Without support Unknown Your device supports MIUI 12.5 full animation Your device only supports MIUI 12.5 partial animations Your device does not support MIUI 12.5 animation Unable to get the level of your device High range Mid-range Low range Unknown MIUI Lite Edition MIUI Normal Edition MIUI model classification Xposed module is enabled Xposed module is actived but not enabled Xposed module is not activated What is this? Note: Due to device performance limitations, some animations may cause hangs.]]> Tap here to go to Xposed manager and enable the module.
Note: Due to device performance limitations, some animations may cause hangs.]]>
OK MIUI may mark some models as \"Lite\" version. Devices marked as lite version will be considered "low-end" devices regardless of performance, and most of them have animation disabled. %dGB RAM It seems that you are not using MIUI The detection results of this software only apply to mobile phones using the MIUI system. About Version: %1$s(%2$d)\nIt helps you to check the MIUI 12.5 rating of your model. https://github.com/HuanCheng65/MIUILevelChecker Github coolapk
================================================ FILE: app/src/main/res/values-es/strings.xml ================================================ MIUILevelChecker Una vez activado el módulo, puede activar a la fuerza la animación completa de MIUI 12.5 Información del dispositivo Soporte total Soporte parcial Sin soporte Desconocido Su dispositivo es compatible con la animación completa de MIUI 12.5 Su dispositivo solo admite animaciones parciales de MIUI 12.5 Su dispositivo no es compatible con la animación de MIUI 12.5 No se puede obtener el nivel de su dispositivo Gama Alta Gama Media Gama Baja Desconocido MIUI Lite MIUI normal Clasificación del modelo MIUI El módulo Xposed está habilitado El módulo Xposed está activado, pero no funcionando El módulo Xposed no está activado ¿Que es esto? Nota: debido a las limitaciones de rendimiento del dispositivo, algunas animaciones pueden provocar bloqueos.]]> Toque aquí para ir al administrador Xposed y habilitar el módulo.
Nota: debido a las limitaciones de rendimiento del dispositivo, algunas animaciones pueden provocar bloqueos.]]>
Vale MIUI puede marcar algunos modelos como versión \"Lite\" (aquí traducida como "versión reducida"). Los dispositivos marcados como versión lite se considerarán dispositivos de "gama baja" independientemente de su rendimiento, y la mayoría de ellos tienen animación desactivada. %dGB Memoria RAM Parece que no estás usando MIUI Los resultados de detección de este software solo se aplican a teléfonos móviles que utilizan el sistema MIUI. Acerca de Versión: %1$s(%2$d)\nTe ayuda a verificar la calificación MIUI 12.5 de tu modelo. https://github.com/HuanCheng65/MIUILevelChecker Github coolapk
================================================ FILE: build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = "1.4.21" repositories { google() jcenter() } dependencies { classpath "com.android.tools.build:gradle:4.1.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ #Sat Feb 13 14:46:21 CST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip ================================================ FILE: gradle.properties ================================================ # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true # AndroidX package structure to make it clearer which packages are bundled with the # Android operating system, and which are packaged with your app"s APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official ================================================ FILE: gradlew ================================================ #!/usr/bin/env sh ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn () { echo "$*" } die () { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Escape application args save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } APP_ARGS=$(save "$@") # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then cd "$(dirname "$0")" fi exec "$JAVACMD" "$@" ================================================ FILE: gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: settings.gradle ================================================ include ':app' rootProject.name = "FuckMIUI"