From e5d16326b47c2e20202fdbf3f7e4b36ce5df2d22 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:53:58 +0200
Subject: [PATCH 1/7] Add DisableForcedCameraSounds
---
DisableSounds/build.gradle.kts | 13 ++++++++
DisableSounds/src/main/AndroidManifest.xml | 24 ++++++++++++++
DisableSounds/src/main/assets/xposed_init | 1 +
.../DisableForcedCameraSoundHook.kt | 31 +++++++++++++++++++
DisableSounds/src/main/res/values/arrays.xml | 7 +++++
modules.gradle.kts | 1 +
6 files changed, 77 insertions(+)
create mode 100644 DisableSounds/build.gradle.kts
create mode 100644 DisableSounds/src/main/AndroidManifest.xml
create mode 100644 DisableSounds/src/main/assets/xposed_init
create mode 100644 DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableForcedCameraSoundHook.kt
create mode 100644 DisableSounds/src/main/res/values/arrays.xml
diff --git a/DisableSounds/build.gradle.kts b/DisableSounds/build.gradle.kts
new file mode 100644
index 0000000..3391997
--- /dev/null
+++ b/DisableSounds/build.gradle.kts
@@ -0,0 +1,13 @@
+plugins {
+ alias(libs.plugins.buildlogic.android.application)
+ alias(libs.plugins.buildlogic.kotlin.android)
+}
+
+android {
+ namespace = "com.programminghoch10.DisableSounds"
+
+ defaultConfig {
+ minSdk = 17
+ targetSdk = 36
+ }
+}
diff --git a/DisableSounds/src/main/AndroidManifest.xml b/DisableSounds/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..7c13810
--- /dev/null
+++ b/DisableSounds/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DisableSounds/src/main/assets/xposed_init b/DisableSounds/src/main/assets/xposed_init
new file mode 100644
index 0000000..77947d2
--- /dev/null
+++ b/DisableSounds/src/main/assets/xposed_init
@@ -0,0 +1 @@
+com.programminghoch10.DisableSounds.DisableForcedCameraSoundHook
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableForcedCameraSoundHook.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableForcedCameraSoundHook.kt
new file mode 100644
index 0000000..9ae3396
--- /dev/null
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableForcedCameraSoundHook.kt
@@ -0,0 +1,31 @@
+package com.programminghoch10.DisableSounds
+
+import android.content.res.XResources
+import android.media.MediaActionSound
+import android.os.Build
+import android.util.Log
+import de.robv.android.xposed.IXposedHookLoadPackage
+import de.robv.android.xposed.IXposedHookZygoteInit
+import de.robv.android.xposed.XC_MethodReplacement
+import de.robv.android.xposed.XposedHelpers
+import de.robv.android.xposed.callbacks.XC_LoadPackage
+
+class DisableForcedCameraSoundHook : IXposedHookLoadPackage, IXposedHookZygoteInit {
+ override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
+ Log.d(TAG, "handleLoadPackage: loaded ${this::class.java.simpleName} with package ${lpparam.packageName}")
+ if (lpparam.packageName == "android") {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ val AudioServiceClass = XposedHelpers.findClass("com.android.server.audio.AudioService", lpparam.classLoader)
+ XposedHelpers.findAndHookMethod(AudioServiceClass, "isCameraSoundForced", XC_MethodReplacement.returnConstant(false))
+ XposedHelpers.findAndHookMethod(AudioServiceClass, "readCameraSoundForced", XC_MethodReplacement.returnConstant(false))
+ }
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ XposedHelpers.findAndHookMethod(MediaActionSound::class.java, "mustPlayShutterSound", XC_MethodReplacement.returnConstant(false))
+ }
+ }
+
+ override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
+ XResources.setSystemWideReplacement("android", "bool", "config_camera_sound_forced", false)
+ }
+}
diff --git a/DisableSounds/src/main/res/values/arrays.xml b/DisableSounds/src/main/res/values/arrays.xml
new file mode 100644
index 0000000..e452f4b
--- /dev/null
+++ b/DisableSounds/src/main/res/values/arrays.xml
@@ -0,0 +1,7 @@
+
+
+
+ - android
+ - org.lineageos.aperture
+
+
diff --git a/modules.gradle.kts b/modules.gradle.kts
index 352f7fa..f564be6 100644
--- a/modules.gradle.kts
+++ b/modules.gradle.kts
@@ -7,6 +7,7 @@ include(":BetterBluetoothDeviceSort")
include(":BetterVerboseWiFiLogging")
include(":ClassHunter")
include(":CodecMod")
+include(":DisableSounds")
include(":DontResetIfBootedAndConnected")
include(":FreeNotifications")
include(":KeepSplitScreenRatio")
From c27097f691d0ca209cde8b9f5dbd4eb6c37acecc Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Wed, 27 Aug 2025 00:22:17 +0200
Subject: [PATCH 2/7] Implement disable screenshot sounds
---
DisableSounds/build.gradle.kts | 9 +++
DisableSounds/src/main/AndroidManifest.xml | 19 +++++-
DisableSounds/src/main/assets/xposed_init | 1 +
.../DisableForcedCameraSoundHook.kt | 2 -
.../DisableScreenshotSoundHook.kt | 66 +++++++++++++++++++
.../DisableSounds/SettingsActivity.kt | 33 ++++++++++
.../src/main/res/layout/settings_activity.xml | 13 ++++
.../src/main/res/values-v21/themes.xml | 5 ++
DisableSounds/src/main/res/values/arrays.xml | 1 +
DisableSounds/src/main/res/values/strings.xml | 8 +++
DisableSounds/src/main/res/values/themes.xml | 9 +++
.../src/main/res/xml/root_preferences.xml | 9 +++
gradle/libs.versions.toml | 2 +
13 files changed, 172 insertions(+), 5 deletions(-)
create mode 100644 DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt
create mode 100644 DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt
create mode 100644 DisableSounds/src/main/res/layout/settings_activity.xml
create mode 100644 DisableSounds/src/main/res/values-v21/themes.xml
create mode 100644 DisableSounds/src/main/res/values/strings.xml
create mode 100644 DisableSounds/src/main/res/values/themes.xml
create mode 100644 DisableSounds/src/main/res/xml/root_preferences.xml
diff --git a/DisableSounds/build.gradle.kts b/DisableSounds/build.gradle.kts
index 3391997..9092b4b 100644
--- a/DisableSounds/build.gradle.kts
+++ b/DisableSounds/build.gradle.kts
@@ -11,3 +11,12 @@ android {
targetSdk = 36
}
}
+
+dependencies {
+ // fragment-ktx is included as transitive dependency through preference-ktx
+ // the transitive dependency is a lower version though, which allows minSdk 17,
+ // while explicit mention with the latest version forced minSdk 21
+ //implementation(libs.androidx.fragment.ktx)
+ implementation(libs.androidx.preference.ktx)
+ implementation(libs.kotlinx.coroutines.guava)
+}
diff --git a/DisableSounds/src/main/AndroidManifest.xml b/DisableSounds/src/main/AndroidManifest.xml
index 7c13810..ae5f241 100644
--- a/DisableSounds/src/main/AndroidManifest.xml
+++ b/DisableSounds/src/main/AndroidManifest.xml
@@ -2,18 +2,31 @@
-
+
+
+
+
+
+
+
+
= Build.VERSION_CODES.M) {
val AudioServiceClass = XposedHelpers.findClass("com.android.server.audio.AudioService", lpparam.classLoader)
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt
new file mode 100644
index 0000000..5c9f11f
--- /dev/null
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt
@@ -0,0 +1,66 @@
+package com.programminghoch10.DisableSounds
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.media.MediaActionSound
+import android.os.Build
+import com.google.common.util.concurrent.Futures
+import de.robv.android.xposed.IXposedHookLoadPackage
+import de.robv.android.xposed.XC_MethodHook
+import de.robv.android.xposed.XC_MethodReplacement
+import de.robv.android.xposed.XSharedPreferences
+import de.robv.android.xposed.XposedHelpers
+import de.robv.android.xposed.callbacks.XC_LoadPackage
+
+class DisableScreenshotSoundHook : IXposedHookLoadPackage {
+ @SuppressLint("ObsoleteSdkInt")
+ override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
+ if (lpparam.packageName != "com.android.systemui") return
+ val sharedPreferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
+ if (!sharedPreferences.getBoolean("screenshot", false)) return
+
+ when {
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> XposedHelpers.findAndHookMethod(
+ "com.android.systemui.screenshot.ScreenshotSoundControllerImpl",
+ lpparam.classLoader,
+ "playScreenshotSoundAsync",
+ XC_MethodReplacement.DO_NOTHING,
+ )
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ->
+ // TODO: check if inlined by r8 on 33
+ XposedHelpers.findAndHookMethod(
+ "com.android.systemui.screenshot.ScreenshotController",
+ lpparam.classLoader,
+ "playCameraSound",
+ XC_MethodReplacement.DO_NOTHING,
+ )
+
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU) {
+ val ScreenshotControllerClass = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ XposedHelpers.findClass("com.android.systemui.screenshot.ScreenshotController", lpparam.classLoader)
+ } else {
+ XposedHelpers.findClass("com.android.systemui.screenshot.GlobalScreenshot", lpparam.classLoader)
+ }
+
+ var replacementDummy: Any = MediaActionSoundDummy()
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) replacementDummy =
+ Futures.immediateFuture(replacementDummy)
+
+ XposedHelpers.findAndHookConstructor(
+ ScreenshotControllerClass, Context::class.java, object : XC_MethodHook() {
+ override fun afterHookedMethod(param: MethodHookParam) {
+ XposedHelpers.setObjectField(
+ param.thisObject, "mCameraSound", replacementDummy
+ )
+ }
+ })
+ }
+ }
+
+ class MediaActionSoundDummy : MediaActionSound() {
+ override fun load(soundName: Int) {}
+ override fun play(soundName: Int) {}
+ override fun release() {}
+ }
+}
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt
new file mode 100644
index 0000000..55430ba
--- /dev/null
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt
@@ -0,0 +1,33 @@
+package com.programminghoch10.DisableSounds
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import androidx.fragment.app.FragmentActivity
+import androidx.preference.PreferenceFragmentCompat
+
+val SHARED_PREFERENCES_NAME = "disable_sounds"
+
+class SettingsActivity : FragmentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.settings_activity)
+ if (savedInstanceState == null) {
+ supportFragmentManager.beginTransaction().replace(R.id.settings, SettingsFragment()).commit()
+ }
+ actionBar?.setDisplayHomeAsUpEnabled(true)
+ }
+
+ override fun onNavigateUp(): Boolean {
+ finish()
+ return true
+ }
+
+ class SettingsFragment : PreferenceFragmentCompat() {
+ @SuppressLint("WorldReadableFiles")
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ preferenceManager.sharedPreferencesName = SHARED_PREFERENCES_NAME
+ preferenceManager.sharedPreferencesMode = MODE_WORLD_READABLE
+ setPreferencesFromResource(R.xml.root_preferences, rootKey)
+ }
+ }
+}
diff --git a/DisableSounds/src/main/res/layout/settings_activity.xml b/DisableSounds/src/main/res/layout/settings_activity.xml
new file mode 100644
index 0000000..d4662df
--- /dev/null
+++ b/DisableSounds/src/main/res/layout/settings_activity.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/DisableSounds/src/main/res/values-v21/themes.xml b/DisableSounds/src/main/res/values-v21/themes.xml
new file mode 100644
index 0000000..ee02adb
--- /dev/null
+++ b/DisableSounds/src/main/res/values-v21/themes.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DisableSounds/src/main/res/values/arrays.xml b/DisableSounds/src/main/res/values/arrays.xml
index e452f4b..38ca316 100644
--- a/DisableSounds/src/main/res/values/arrays.xml
+++ b/DisableSounds/src/main/res/values/arrays.xml
@@ -2,6 +2,7 @@
- android
+ - com.android.systemui
- org.lineageos.aperture
diff --git a/DisableSounds/src/main/res/values/strings.xml b/DisableSounds/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e2ee3bd
--- /dev/null
+++ b/DisableSounds/src/main/res/values/strings.xml
@@ -0,0 +1,8 @@
+
+
+ DisableSounds Configuration
+ DisableSounds
+ Disable various system sounds
+ Disable screenshot sound
+ @null
+
diff --git a/DisableSounds/src/main/res/values/themes.xml b/DisableSounds/src/main/res/values/themes.xml
new file mode 100644
index 0000000..7e8afbb
--- /dev/null
+++ b/DisableSounds/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/DisableSounds/src/main/res/xml/root_preferences.xml b/DisableSounds/src/main/res/xml/root_preferences.xml
new file mode 100644
index 0000000..4eac241
--- /dev/null
+++ b/DisableSounds/src/main/res/xml/root_preferences.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 6c57813..2ac90bb 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -10,6 +10,7 @@ githubApi = "1.329"
hiddenapibypass = "6.1"
jebrainsAnnotations = "26.0.2"
kotlin = "2.2.10"
+kotlinxCoroutinesGuava = "1.10.2"
libsu = "6.0.0"
preference = "1.2.1"
xposed = "82"
@@ -30,6 +31,7 @@ jebtrains-annotations = { module = "org.jetbrains:annotations", version.ref = "j
kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin" }
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" }
+kotlinx-coroutines-guava = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-guava", version.ref = "kotlinxCoroutinesGuava" }
libsu-core = { module = "com.github.topjohnwu.libsu:core", version.ref = "libsu" }
xposed-api = { module = "de.robv.android.xposed:api", version.ref = "xposed" }
From aec91f1c2c48967de60ff8fe9c735ad5a58e9d40 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Wed, 27 Aug 2025 00:53:13 +0200
Subject: [PATCH 3/7] Add disable camera sounds
---
DisableSounds/src/main/assets/xposed_init | 1 +
.../DisableSounds/DisableShutterSoundsHook.kt | 29 +++++++++++++++++++
DisableSounds/src/main/res/values/strings.xml | 3 ++
.../src/main/res/xml/root_preferences.xml | 6 ++++
4 files changed, 39 insertions(+)
create mode 100644 DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt
diff --git a/DisableSounds/src/main/assets/xposed_init b/DisableSounds/src/main/assets/xposed_init
index e3deea6..10cb1e5 100644
--- a/DisableSounds/src/main/assets/xposed_init
+++ b/DisableSounds/src/main/assets/xposed_init
@@ -1,2 +1,3 @@
com.programminghoch10.DisableSounds.DisableForcedCameraSoundHook
com.programminghoch10.DisableSounds.DisableScreenshotSoundHook
+com.programminghoch10.DisableSounds.DisableShutterSoundsHook
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt
new file mode 100644
index 0000000..aef1eed
--- /dev/null
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt
@@ -0,0 +1,29 @@
+package com.programminghoch10.DisableSounds
+
+import android.annotation.SuppressLint
+import android.media.MediaActionSound
+import android.os.Build
+import de.robv.android.xposed.IXposedHookLoadPackage
+import de.robv.android.xposed.XC_MethodReplacement
+import de.robv.android.xposed.XSharedPreferences
+import de.robv.android.xposed.XposedHelpers
+import de.robv.android.xposed.callbacks.XC_LoadPackage
+
+class DisableShutterSoundsHook : IXposedHookLoadPackage {
+ @SuppressLint("ObsoleteSdkInt")
+ override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
+ val sharedPreferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
+ if (!sharedPreferences.getBoolean("shutter", false)) return
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) for (methodName in listOf("load", "play")) XposedHelpers.findAndHookMethod(
+ MediaActionSound::class.java,
+ methodName,
+ Int::class.java,
+ XC_MethodReplacement.DO_NOTHING,
+ )
+
+ // TODO: need a native hook for old Camera API methods
+ // https://cs.android.com/android/platform/superproject/main/+/main:frameworks/av/services/camera/libcameraservice/CameraService.cpp;l=4097?q=camera_click.ogg
+ // then the "might not work" warning can be removed from @string/disable_shutter_sounds_description_on
+ }
+}
diff --git a/DisableSounds/src/main/res/values/strings.xml b/DisableSounds/src/main/res/values/strings.xml
index e2ee3bd..48d3f04 100644
--- a/DisableSounds/src/main/res/values/strings.xml
+++ b/DisableSounds/src/main/res/values/strings.xml
@@ -3,6 +3,9 @@
DisableSounds Configuration
DisableSounds
Disable various system sounds
+ Disable shutter sounds
+ Disable shutter, focus and video recording sounds.
+ Some apps using the old Camera API might not be muted. On Android 13 and older the screenshot sound might be muted too.
Disable screenshot sound
@null
diff --git a/DisableSounds/src/main/res/xml/root_preferences.xml b/DisableSounds/src/main/res/xml/root_preferences.xml
index 4eac241..fc367e0 100644
--- a/DisableSounds/src/main/res/xml/root_preferences.xml
+++ b/DisableSounds/src/main/res/xml/root_preferences.xml
@@ -1,6 +1,12 @@
+
Date: Wed, 27 Aug 2025 00:54:11 +0200
Subject: [PATCH 4/7] suppress ObsoleteSdkInt lint for DisableSounds module
---
DisableSounds/build.gradle.kts | 4 ++++
.../DisableSounds/DisableScreenshotSoundHook.kt | 2 --
.../DisableSounds/DisableShutterSoundsHook.kt | 2 --
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/DisableSounds/build.gradle.kts b/DisableSounds/build.gradle.kts
index 9092b4b..dffdd2f 100644
--- a/DisableSounds/build.gradle.kts
+++ b/DisableSounds/build.gradle.kts
@@ -10,6 +10,10 @@ android {
minSdk = 17
targetSdk = 36
}
+
+ lint {
+ disable += "ObsoleteSdkInt"
+ }
}
dependencies {
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt
index 5c9f11f..ba26ef8 100644
--- a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableScreenshotSoundHook.kt
@@ -1,6 +1,5 @@
package com.programminghoch10.DisableSounds
-import android.annotation.SuppressLint
import android.content.Context
import android.media.MediaActionSound
import android.os.Build
@@ -13,7 +12,6 @@ import de.robv.android.xposed.XposedHelpers
import de.robv.android.xposed.callbacks.XC_LoadPackage
class DisableScreenshotSoundHook : IXposedHookLoadPackage {
- @SuppressLint("ObsoleteSdkInt")
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
if (lpparam.packageName != "com.android.systemui") return
val sharedPreferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt
index aef1eed..aa7f9c0 100644
--- a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableShutterSoundsHook.kt
@@ -1,6 +1,5 @@
package com.programminghoch10.DisableSounds
-import android.annotation.SuppressLint
import android.media.MediaActionSound
import android.os.Build
import de.robv.android.xposed.IXposedHookLoadPackage
@@ -10,7 +9,6 @@ import de.robv.android.xposed.XposedHelpers
import de.robv.android.xposed.callbacks.XC_LoadPackage
class DisableShutterSoundsHook : IXposedHookLoadPackage {
- @SuppressLint("ObsoleteSdkInt")
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
val sharedPreferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
if (!sharedPreferences.getBoolean("shutter", false)) return
From ab8608e4118ae8a14f9343f21de5897a667917d2 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Wed, 27 Aug 2025 01:01:39 +0200
Subject: [PATCH 5/7] add metadata for DisableSounds
---
DisableSounds/Readme.md | 20 +++++++++++++++++++
.../en-US/full_description.txt | 7 +++++++
.../en-US/short_description.txt | 1 +
.../en-US/title.txt | 1 +
4 files changed, 29 insertions(+)
create mode 100644 DisableSounds/Readme.md
create mode 100644 metadata/com.programminghoch10.DisableSounds/en-US/full_description.txt
create mode 100644 metadata/com.programminghoch10.DisableSounds/en-US/short_description.txt
create mode 100644 metadata/com.programminghoch10.DisableSounds/en-US/title.txt
diff --git a/DisableSounds/Readme.md b/DisableSounds/Readme.md
new file mode 100644
index 0000000..754bd1e
--- /dev/null
+++ b/DisableSounds/Readme.md
@@ -0,0 +1,20 @@
+# DisableSounds
+
+Disable various system sounds.
+
+- Disable (regionally) forced camera sound
+- Disable shutter sound
+- Disable screenshot sound
+
+## Forced camera sound
+
+In some regions the camera sounds
+for shutter, start/stop recording and focus
+are enforced by law.
+This module tells the system that disabling the sounds
+is allowed.
+The system and apps will then show/enable their options
+for disabling camera/shutter sounds.
+This hook is always enabled, since allowing the option to appear,
+does not change the option by default.
+Be aware that it might be illegal to disable camera sounds in your country.
diff --git a/metadata/com.programminghoch10.DisableSounds/en-US/full_description.txt b/metadata/com.programminghoch10.DisableSounds/en-US/full_description.txt
new file mode 100644
index 0000000..c3768b8
--- /dev/null
+++ b/metadata/com.programminghoch10.DisableSounds/en-US/full_description.txt
@@ -0,0 +1,7 @@
+# DisableSounds
+
+Disable various system sounds.
+
+- Disable (regionally) forced camera sound
+- Disable shutter sound
+- Disable screenshot sound
diff --git a/metadata/com.programminghoch10.DisableSounds/en-US/short_description.txt b/metadata/com.programminghoch10.DisableSounds/en-US/short_description.txt
new file mode 100644
index 0000000..e65c164
--- /dev/null
+++ b/metadata/com.programminghoch10.DisableSounds/en-US/short_description.txt
@@ -0,0 +1 @@
+Disable various system sounds.
\ No newline at end of file
diff --git a/metadata/com.programminghoch10.DisableSounds/en-US/title.txt b/metadata/com.programminghoch10.DisableSounds/en-US/title.txt
new file mode 100644
index 0000000..eb487d0
--- /dev/null
+++ b/metadata/com.programminghoch10.DisableSounds/en-US/title.txt
@@ -0,0 +1 @@
+DisableSounds
\ No newline at end of file
From 26fdbcc684cc0ee61ffca67dc3c752d36489ade4 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Wed, 27 Aug 2025 01:01:39 +0200
Subject: [PATCH 6/7] Add DisableChargingSounds
---
.idea/codeStyles/Project.xml | 2 -
DisableSounds/src/main/assets/xposed_init | 1 +
.../DisableChargingSoundsHook.kt | 64 +++++++++++++++++++
DisableSounds/src/main/res/values/strings.xml | 3 +
.../src/main/res/xml/root_preferences.xml | 14 +++-
5 files changed, 80 insertions(+), 4 deletions(-)
create mode 100644 DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableChargingSoundsHook.kt
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 9969487..4e7d7fc 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -2,7 +2,6 @@
-
-
diff --git a/DisableSounds/src/main/assets/xposed_init b/DisableSounds/src/main/assets/xposed_init
index 10cb1e5..051ac6a 100644
--- a/DisableSounds/src/main/assets/xposed_init
+++ b/DisableSounds/src/main/assets/xposed_init
@@ -1,3 +1,4 @@
+com.programminghoch10.DisableSounds.DisableChargingSoundsHook
com.programminghoch10.DisableSounds.DisableForcedCameraSoundHook
com.programminghoch10.DisableSounds.DisableScreenshotSoundHook
com.programminghoch10.DisableSounds.DisableShutterSoundsHook
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableChargingSoundsHook.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableChargingSoundsHook.kt
new file mode 100644
index 0000000..caa0cc8
--- /dev/null
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/DisableChargingSoundsHook.kt
@@ -0,0 +1,64 @@
+package com.programminghoch10.DisableSounds
+
+import android.content.ContentResolver
+import android.provider.Settings
+import de.robv.android.xposed.IXposedHookLoadPackage
+import de.robv.android.xposed.XC_MethodHook
+import de.robv.android.xposed.XC_MethodReplacement
+import de.robv.android.xposed.XSharedPreferences
+import de.robv.android.xposed.XposedHelpers
+import de.robv.android.xposed.callbacks.XC_LoadPackage
+
+class DisableChargingSoundsHook : IXposedHookLoadPackage {
+ override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
+ if (lpparam.packageName != "android") return
+ val sharedPreferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
+ if (!sharedPreferences.getBoolean("charging", false)) return
+ val disableChargingFeedback = sharedPreferences.getBoolean("chargingFeedback", false)
+
+ val CHARGING_STARTED_SOUND =
+ XposedHelpers.getStaticObjectField(Settings::class.java, "CHARGING_STARTED_SOUND") as String
+ val WIRELESS_CHARGING_STARTED_SOUND =
+ XposedHelpers.getStaticObjectField(Settings::class.java, "WIRELESS_CHARGING_STARTED_SOUND") as String
+ val CHARGING_VIBRATION_ENABLED =
+ XposedHelpers.getStaticObjectField(Settings.Secure::class.java, "CHARGING_VIBRATION_ENABLED") as String
+
+ XposedHelpers.findAndHookMethod(
+ Settings.Global::class.java,
+ "getString",
+ ContentResolver::class.java,
+ String::class.java,
+ object : XC_MethodHook() {
+ override fun beforeHookedMethod(param: MethodHookParam) {
+ val string = param.args[1] as String
+ if (string == CHARGING_STARTED_SOUND || string == WIRELESS_CHARGING_STARTED_SOUND) param.result =
+ null
+ }
+ },
+ )
+
+ if (disableChargingFeedback) {
+ XposedHelpers.findAndHookMethod(
+ Settings.Secure::class.java,
+ "getIntForUser",
+ ContentResolver::class.java,
+ String::class.java,
+ Int::class.java,
+ object : XC_MethodHook() {
+ override fun beforeHookedMethod(param: MethodHookParam) {
+ val string = param.args[1] as String
+ if (string == CHARGING_VIBRATION_ENABLED) param.result = 0
+ }
+ },
+ )
+
+ val NotifierClass = XposedHelpers.findClass("com.android.server.power.Notifier", lpparam.classLoader)
+ XposedHelpers.findAndHookMethod(
+ NotifierClass,
+ "isChargingFeedbackEnabled",
+ Int::class.java,
+ XC_MethodReplacement.returnConstant(false),
+ )
+ }
+ }
+}
diff --git a/DisableSounds/src/main/res/values/strings.xml b/DisableSounds/src/main/res/values/strings.xml
index 48d3f04..b4ec868 100644
--- a/DisableSounds/src/main/res/values/strings.xml
+++ b/DisableSounds/src/main/res/values/strings.xml
@@ -8,4 +8,7 @@
Some apps using the old Camera API might not be muted. On Android 13 and older the screenshot sound might be muted too.
Disable screenshot sound
@null
+ Disable charging sounds
+ Disable charging feedback
+ Also disable charging vibration.
diff --git a/DisableSounds/src/main/res/xml/root_preferences.xml b/DisableSounds/src/main/res/xml/root_preferences.xml
index fc367e0..f423511 100644
--- a/DisableSounds/src/main/res/xml/root_preferences.xml
+++ b/DisableSounds/src/main/res/xml/root_preferences.xml
@@ -3,13 +3,23 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
+
+
From efbce908dd3786d8ea389f03d406f1c55e6a23ae Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Thu, 28 Aug 2025 16:26:30 +0200
Subject: [PATCH 7/7] remove reserved icon space from DisableSounds settings
activity
---
.../programminghoch10/DisableSounds/SettingsActivity.kt | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt
index 55430ba..91a4b90 100644
--- a/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt
+++ b/DisableSounds/src/main/java/com/programminghoch10/DisableSounds/SettingsActivity.kt
@@ -3,7 +3,10 @@ package com.programminghoch10.DisableSounds
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
+import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
+import androidx.preference.PreferenceGroup
+import androidx.preference.children
val SHARED_PREFERENCES_NAME = "disable_sounds"
@@ -28,6 +31,12 @@ class SettingsActivity : FragmentActivity() {
preferenceManager.sharedPreferencesName = SHARED_PREFERENCES_NAME
preferenceManager.sharedPreferencesMode = MODE_WORLD_READABLE
setPreferencesFromResource(R.xml.root_preferences, rootKey)
+ preferenceScreen.setIconSpaceReservedRecursive(false)
+ }
+
+ fun Preference.setIconSpaceReservedRecursive(iconSpaceReserved: Boolean) {
+ this.isIconSpaceReserved = iconSpaceReserved
+ if (this is PreferenceGroup) children.forEach { it.setIconSpaceReservedRecursive(iconSpaceReserved) }
}
}
}