Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
661 changes: 0 additions & 661 deletions LICENSE.md

This file was deleted.

16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ Additionally, some apps use various loopholes to acquire your app list, in order

This module can work as an Xposed module to hide apps or reject app list requests, and provides some methods to test whether you have hidden your app list properly.

## Copyright Notice

Copyright © 2025 HMA developers. All rights reserved.

The software Hide My Applist, starting from version v3.4, is no longer under the AGPL-3.0 License. Instead, certain rights to the software are reserved by the owner.

The following conditions now apply:

1. **No Modifications**: The software may not be modified in any way. This includes but is not limited to changing, adding, or removing any part of the software's code or functionality.

2. **No Redistribution**: The software may not be redistributed in any form. This includes but is not limited to renaming, selling, or including the software as part of another project.

3. **No Picking without Credit**: No parts, pieces, or components of the software may be extracted and submitted to other projects without proper credit. This includes, but is not limited to, code snippets, functions, and released binaries.

4. **No Claim to Succession**: Any fork of the software that was created before the license change may not claim to be an official or unofficial successor to the project. This includes but is not limited to using the project's name, branding, or reputation to imply a connection to the original project.

## Translation Contributing
You can contribute translation [here](https://crowdin.com/project/hide-my-applist).

Expand Down
15 changes: 15 additions & 0 deletions README_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,20 @@
与此同时,部分“不安分”的应用会使用各种漏洞绕过系统权限来获取你的应用列表,从而对你建立用户画像。(如陈叔叔将安装了 V2Ray 的用户分为一类),或是类似于某某校园某某乐跑的软件会要求你卸载作弊软件。
该模块提供了一些检测方式用于测试您是否成功地隐藏了某些特定的包名,如 Magisk/Edxposed Manager;同时可作为 Xposed 模块用于隐藏应用列表或特定应用,保护隐私。

## 版权声明
版权所有 © 2025 HMA 开发者。保留所有权利。

从版本 v3.4 开始,Hide My Applist 不再适用 AGPL-3.0 许可证。相反,某些权利将由所有者保留。

以下条件现适用:

1. **禁止修改**:不得以任何方式修改软件。这包括但不限于更改、添加或删除软件的任何部分代码或功能。

2. **禁止再分发**:不得以任何形式再分发软件。这包括但不限于重新命名、销售或将软件作为其他项目的一部分。

3. **禁止不注明出处的摘取**:不得提取软件的任何部分、片段或组件并提交到其他项目中,除非以合适方式注明出处。这包括但不限于代码片段、函数和已发布的二进制文件。

4. **禁止声称继承**:在许可证变更之前创建的任何软件分支均不得声称是该项目的官方或非官方继承者。这包括但不限于使用项目的名称、品牌或声誉来暗示与原项目的关联。

## 更新日志
[参考发布页面](https://github.com/Dr-TSNG/Hide-My-Applist/releases)
13 changes: 13 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import com.android.build.api.dsl.Packaging
import java.util.*

val officialBuild: Boolean by rootProject.extra
Expand All @@ -24,6 +25,18 @@ android {
buildConfig = true
viewBinding = true
}

packaging {
dex.useLegacyPackaging = true
resources {
excludes += arrayOf(
"/META-INF/*",
"/META-INF/androidx/**",
"/kotlin/**",
"/okhttp3/**",
)
}
}
}

kotlin {
Expand Down
5 changes: 0 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
android:label="@string/app_name"
android:theme="@style/AppTheme">

<property
android:name="android.adservices.AD_SERVICES_CONFIG"
android:resource="@xml/gma_ad_services_config"
tools:replace="android:resource" />

<activity
android:name="icu.nullptr.hidemyapplist.ui.activity.AboutActivity"
android:theme="@style/AppTheme.About" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class AboutActivity : AbsAboutActivity() {
items.add(Line())
items.add(Contributor(R.drawable.cont_k, "Ketal", "Collaborator", "https://github.com/keta1"))
items.add(Line())
items.add(Contributor(R.drawable.cont_aviraxp, "aviraxp", "Collaborator", "https://github.com/aviraxp"))
items.add(Line())
items.add(Contributor(R.drawable.cont_icon_designer, "辉少菌", "Icon designer", "http://www.coolapk.com/u/1560270"))
items.add(Line())
items.add(Contributor(R.drawable.cont_cpp_master, "LoveSy", "Idea provider", "https://github.com/yujincheng08"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package icu.nullptr.hidemyapplist.ui.activity
import android.content.res.Resources
import android.graphics.Color
import android.os.Bundle
import androidx.navigation.Navigation
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI.setupWithNavController
import com.google.android.gms.ads.MobileAds
Expand All @@ -29,7 +29,7 @@ class MainActivity : MaterialActivity() {
}

override fun onSupportNavigateUp(): Boolean {
val navController = Navigation.findNavController(this, R.id.nav_host_fragment)
val navController = this.findNavController(R.id.nav_host_fragment)
return navController.navigateUp() || super.onSupportNavigateUp()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,56 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen

findPreference<SwitchPreference>("appDataIsolation")?.let {
it.setOnPreferenceChangeListener { _, newValue ->
val value = if (newValue as Boolean) 1 else 0
val result = SuUtils.execPrivileged("setprop ${Constants.ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY} $value")
if (result) makeToast(R.string.settings_need_reboot)
else makeToast(R.string.settings_permission_denied)
it.isChecked = CommonUtils.isAppDataIsolationEnabled
handleIsolationChange(
preference = it,
enabled = newValue as Boolean,
property = Constants.ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY,
checker = CommonUtils::isAppDataIsolationEnabled
)
false
}
}

findPreference<SwitchPreference>("voldAppDataIsolation")?.let {
it.setOnPreferenceChangeListener { _, newValue ->
val value = if (newValue as Boolean) 1 else 0
val result = SuUtils.execPrivileged("setprop ${Constants.ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY} $value")
if (result) makeToast(R.string.settings_need_reboot)
else makeToast(R.string.settings_permission_denied)
it.isChecked = CommonUtils.isVoldAppDataIsolationEnabled
val enabled = newValue as Boolean
if (enabled) {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.settings_warning)
.setMessage(R.string.settings_vold_warning)
.setPositiveButton(android.R.string.ok) { _, _ ->
handleIsolationChange(
preference = it,
enabled = true,
property = Constants.ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY,
checker = CommonUtils::isVoldAppDataIsolationEnabled
)
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
it.isChecked = false
}
.setCancelable(false)
.show()
} else {
handleIsolationChange(
preference = it,
enabled = false,
property = Constants.ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY,
checker = CommonUtils::isVoldAppDataIsolationEnabled
)
}
false
}
}
}

private fun handleIsolationChange(preference: SwitchPreference, enabled: Boolean, property: String, checker: () -> Boolean) {
val value = if (enabled) 1 else 0
val result = SuUtils.execPrivileged("setprop $property $value")
if (result) makeToast(R.string.settings_need_reboot)
else makeToast(R.string.settings_permission_denied)
preference.isChecked = checker()
}
}

class SettingsPreferenceFragment : PreferenceFragmentCompat() {
Expand Down
Binary file added app/src/main/res/drawable/cont_aviraxp.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion app/src/main/res/drawable/ic_outline_layers_24.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@
android:focusable="true"
android:outlineAmbientShadowColor="?colorPrimary"
android:outlineSpotShadowColor="?colorPrimary"
app:cardBackgroundColor="?colorPrimary"
tools:targetApi="p">
app:cardBackgroundColor="?colorPrimary">

<LinearLayout
android:layout_width="match_parent"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
<string name="settings_data_isolation_unsupported">此选项仅适用于 Android 11 及以上版本的系统</string>
<string name="settings_app_data_isolation">App data 隔离</string>
<string name="settings_vold_app_data_isolation">Vold app data 隔离</string>
<string name="settings_warning">警告</string>
<string name="settings_vold_warning">这将启用 AOSP 中用于隔离应用外部私有存储目录的功能。这可以帮助改善隐藏效果,但可能会导致稳定性问题。此功能在 AOSP 中已被废弃,可能随时停止工作。</string>
<string name="settings_change_require_root">此更改需要 root 权限</string>
<string name="settings_need_reboot">重启以应用更改</string>
<string name="settings_permission_denied">权限被拒绝</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@
<string name="settings_data_isolation_unsupported">This option is only available on Android 11 and above</string>
<string name="settings_app_data_isolation">App data isolation</string>
<string name="settings_vold_app_data_isolation">Vold app data isolation</string>
<string name="settings_warning">Warning</string>
<string name="settings_vold_warning">This will enable an AOSP feature which make app\'s external private storage directory isolated. This can help improve hiding apps while may cause stability issues. This feature may stop working at any time since it is abandoned in AOSP.</string>
<string name="settings_change_require_root">Changing requires root permission</string>
<string name="settings_need_reboot">Changing requires reboot</string>
<string name="settings_permission_denied">Permission denied</string>
Expand Down
6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ fun String.execute(currentWorkingDir: File = file("./")): String {
val gitCommitCount = "git rev-list HEAD --count".execute().toInt()
val gitCommitHash = "git rev-parse --verify --short HEAD".execute()

val minSdkVer by extra(24)
val minSdkVer by extra(28)
val targetSdkVer by extra(35)
val buildToolsVer by extra("35.0.0")
val buildToolsVer by extra("35.0.1")

val appVerName by extra("3.3.1")
val appVerName by extra("3.4")
val configVerCode by extra(90)
val serviceVerCode by extra(97)
val minBackupVerCode by extra(65)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public class Constants {
public static final String GSF_PACKAGE_NAME = "com.google.android.gsf";
public static final String UPDATE_URL_BASE = "https://api.nullptr.icu/android/hide-my-applist/static/";
public static final String TRANSLATE_URL = "https://crowdin.com/project/hide-my-applist";
public static final String CLASS_PMS = "com.android.server.pm.PackageManagerService";

public static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.zygote.app_data_isolation";
public static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.sys.vold_app_data_isolation_enabled";
Expand All @@ -21,7 +20,6 @@ public class Constants {
public static final int ACTION_GET_BINDER = 1;

public static final int UID_SYSTEM = 1000;
public static final int PER_USER_RANGE = 100000;

public static final Set<String> packagesShouldNotHide = Set.of(
"android",
Expand Down
19 changes: 10 additions & 9 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
agp = "8.7.3"
kotlin = "2.1.0"
agp = "8.9.0"
kotlin = "2.1.10"
rxhttp = "3.3.1"
hidden-api = "4.3.3"

Expand All @@ -9,16 +9,17 @@ agp-app = { id = "com.android.application", version.ref = "agp" }
agp-lib = { id = "com.android.library", version.ref = "agp" }
kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version = "2.1.0-1.0.29" }
ksp = { id = "com.google.devtools.ksp", version = "2.1.10-1.0.31" }
gms = { id = "com.google.gms.google-services", version = "4.4.2" }
nav-safeargs-kotlin = { id = "androidx.navigation.safeargs.kotlin", version = "2.8.5" }
nav-safeargs-kotlin = { id = "androidx.navigation.safeargs.kotlin", version = "2.8.8" }
autoresconfig = { id = "dev.rikka.tools.autoresconfig", version = "1.2.2" }
materialthemebuilder = { id = "dev.rikka.tools.materialthemebuilder", version = "1.5.1" }
refine = { id = "dev.rikka.tools.refine", version = "4.4.0" }

[libraries]
androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version = "2.8.5" }
androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version = "2.8.5" }
androidx-annotation-jvm = { group = "androidx.annotation", name = "annotation-jvm", version = "1.9.1" }
androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version = "2.8.8" }
androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version = "2.8.8" }
androidx-preference-ktx = { module = "androidx.preference:preference-ktx", version = "1.2.1" }
androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
com-android-tools-build-apksig = { module = "com.android.tools.build:apksig", version.ref = "agp" }
Expand All @@ -31,9 +32,9 @@ com-github-liujingxing-rxhttp-compiler = { module = "com.github.liujingxing.rxht
com-github-liujingxing-rxhttp-converter-serialization = { module = "com.github.liujingxing.rxhttp:converter-serialization", version.ref = "rxhttp" }
com-github-topjohnwu-libsu-core = { module = "com.github.topjohnwu.libsu:core", version = "6.0.0" }
com-google-android-material = { module = "com.google.android.material:material", version = "1.12.0" }
com-google-android-gms-play-services-ads = { module = "com.google.android.gms:play-services-ads", version = "23.6.0" }
com-google-firebase-bom = { module = "com.google.firebase:firebase-bom", version = "33.7.0" }
com-google-firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx", version = "22.1.2" }
com-google-android-gms-play-services-ads = { module = "com.google.android.gms:play-services-ads", version = "24.0.0" }
com-google-firebase-bom = { module = "com.google.firebase:firebase-bom", version = "33.10.0" }
com-google-firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx", version = "22.3.0" }
com-squareup-okhttp3 = { module = "com.squareup.okhttp3:okhttp", version = "4.12.0" }
de-robv-android-xposed-api = { module = "de.robv.android.xposed:api", version = "82" }
dev-rikka-hidden-compat = { module = "dev.rikka.hidden:compat", version.ref = "hidden-api" }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 2 additions & 0 deletions xposed/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ kotlin {
}

afterEvaluate {
//noinspection WrongGradleMethod
android.libraryVariants.forEach { variant ->
val variantCapped = variant.name.replaceFirstChar { it.titlecase(Locale.ROOT) }
val variantLowered = variant.name.lowercase(Locale.ROOT)
Expand Down Expand Up @@ -63,6 +64,7 @@ afterEvaluate {
dependencies {
implementation(projects.common)

implementation(libs.androidx.annotation.jvm)
implementation(libs.com.android.tools.build.apksig)
implementation(libs.com.github.kyuubiran.ezxhelper)
implementation(libs.dev.rikka.hidden.compat)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,14 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
if (it.flags and ApplicationInfo.FLAG_SYSTEM != 0) it.packageName else null
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
frameworkHooks.add(PmsHookTarget34(this))
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
frameworkHooks.add(PmsHookTarget33(this))
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
frameworkHooks.add(PmsHookTarget30(this))
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
frameworkHooks.add(PmsHookTarget28(this))
} else {
frameworkHooks.add(PmsHookLegacy(this))
frameworkHooks.add(PmsHookTarget28(this))
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Expand Down
13 changes: 0 additions & 13 deletions xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import android.os.Binder
import android.os.Build
import com.android.apksig.ApkVerifier
import com.github.kyuubiran.ezxhelper.utils.findField
import com.github.kyuubiran.ezxhelper.utils.invokeMethodAutoAs
import de.robv.android.xposed.XposedHelpers
import icu.nullptr.hidemyapplist.Magic
import java.io.File
import java.util.*
Expand Down Expand Up @@ -37,17 +35,6 @@ object Utils {
return mainCert.encoded.contentEquals(Magic.magicNumbers)
}

fun getRecursiveField(entry: Any, list: List<String>): Any? {
var field: Any? = entry
for (it in list)
field = XposedHelpers.getObjectField(field, it) ?: return null
return field
}

fun Any.getBinderCaller(): String? {
return this.invokeMethodAutoAs<String>("getNameForUid", Binder.getCallingUid())
}

fun <T> binderLocalScope(block: () -> T): T {
val identity = Binder.clearCallingIdentity()
val result = block()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package icu.nullptr.hidemyapplist.xposed.hook

import android.annotation.TargetApi
import android.content.pm.ApplicationInfo
import android.os.Build
import androidx.annotation.RequiresApi
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import de.robv.android.xposed.XC_MethodHook
Expand All @@ -11,7 +11,7 @@ import icu.nullptr.hidemyapplist.xposed.HMAService
import icu.nullptr.hidemyapplist.xposed.logE
import icu.nullptr.hidemyapplist.xposed.logI

@TargetApi(Build.VERSION_CODES.S)
@RequiresApi(Build.VERSION_CODES.S)
class PlatformCompatHook(private val service: HMAService) : IFrameworkHook {

companion object {
Expand Down
Loading
Loading