Skip to content

Commit b799cd1

Browse files
committed
android: add option to change camera app id
1 parent c7dc545 commit b799cd1

File tree

3 files changed

+135
-3
lines changed

3 files changed

+135
-3
lines changed

android/app/src/main/java/me/kavishdevar/librepods/screens/AppSettingsScreen.kt

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,18 @@ fun AppSettingsScreen(navController: NavController) {
103103
val showResetDialog = remember { mutableStateOf(false) }
104104
val showIrkDialog = remember { mutableStateOf(false) }
105105
val showEncKeyDialog = remember { mutableStateOf(false) }
106+
val showCameraDialog = remember { mutableStateOf(false) }
106107
val irkValue = remember { mutableStateOf("") }
107108
val encKeyValue = remember { mutableStateOf("") }
109+
val cameraPackageValue = remember { mutableStateOf("") }
108110
val irkError = remember { mutableStateOf<String?>(null) }
109111
val encKeyError = remember { mutableStateOf<String?>(null) }
112+
val cameraPackageError = remember { mutableStateOf<String?>(null) }
110113

111114
LaunchedEffect(Unit) {
112115
val savedIrk = sharedPreferences.getString(AACPManager.Companion.ProximityKeyType.IRK.name, null)
113116
val savedEncKey = sharedPreferences.getString(AACPManager.Companion.ProximityKeyType.ENC_KEY.name, null)
117+
val savedCameraPackage = sharedPreferences.getString("custom_camera_package", null)
114118

115119
if (savedIrk != null) {
116120
try {
@@ -131,6 +135,9 @@ fun AppSettingsScreen(navController: NavController) {
131135
e.printStackTrace()
132136
}
133137
}
138+
if (savedCameraPackage != null) {
139+
cameraPackageValue.value = savedCameraPackage
140+
}
134141
}
135142

136143
val showPhoneBatteryInWidget = remember {
@@ -292,6 +299,18 @@ fun AppSettingsScreen(navController: NavController) {
292299
independent = true
293300
)
294301

302+
Spacer(modifier = Modifier.height(16.dp))
303+
304+
NavigationButton(
305+
to = "",
306+
title = stringResource(R.string.camera_control),
307+
name = stringResource(R.string.set_custom_camera_package),
308+
navController = navController,
309+
onClick = { showCameraDialog.value = true },
310+
independent = true,
311+
description = stringResource(R.string.camera_control_app_description)
312+
)
313+
295314
Spacer(modifier = Modifier.height(16.dp))
296315

297316
StyledToggle(
@@ -877,6 +896,86 @@ fun AppSettingsScreen(navController: NavController) {
877896
}
878897
)
879898
}
899+
900+
if (showCameraDialog.value) {
901+
AlertDialog(
902+
onDismissRequest = { showCameraDialog.value = false },
903+
title = {
904+
Text(
905+
stringResource(R.string.set_custom_camera_package),
906+
fontFamily = FontFamily(Font(R.font.sf_pro)),
907+
fontWeight = FontWeight.Medium
908+
)
909+
},
910+
text = {
911+
Column {
912+
Text(
913+
stringResource(R.string.enter_custom_camera_package),
914+
fontFamily = FontFamily(Font(R.font.sf_pro)),
915+
modifier = Modifier.padding(bottom = 8.dp)
916+
)
917+
918+
OutlinedTextField(
919+
value = cameraPackageValue.value,
920+
onValueChange = {
921+
cameraPackageValue.value = it
922+
cameraPackageError.value = null
923+
},
924+
modifier = Modifier.fillMaxWidth(),
925+
isError = cameraPackageError.value != null,
926+
keyboardOptions = KeyboardOptions(
927+
keyboardType = KeyboardType.Ascii,
928+
capitalization = KeyboardCapitalization.None
929+
),
930+
colors = OutlinedTextFieldDefaults.colors(
931+
focusedBorderColor = if (isDarkTheme) Color(0xFF007AFF) else Color(0xFF3C6DF5),
932+
unfocusedBorderColor = if (isDarkTheme) Color.Gray else Color.LightGray
933+
),
934+
supportingText = {
935+
if (cameraPackageError.value != null) {
936+
Text(cameraPackageError.value!!, color = MaterialTheme.colorScheme.error)
937+
}
938+
},
939+
label = { Text(stringResource(R.string.custom_camera_package)) }
940+
)
941+
}
942+
},
943+
confirmButton = {
944+
val successText = stringResource(R.string.custom_camera_package_set_success)
945+
TextButton(
946+
onClick = {
947+
if (cameraPackageValue.value.isBlank()) {
948+
sharedPreferences.edit { remove("custom_camera_package") }
949+
Toast.makeText(context, successText, Toast.LENGTH_SHORT).show()
950+
showCameraDialog.value = false
951+
return@TextButton
952+
}
953+
954+
sharedPreferences.edit { putString("custom_camera_package", cameraPackageValue.value) }
955+
Toast.makeText(context, successText, Toast.LENGTH_SHORT).show()
956+
showCameraDialog.value = false
957+
}
958+
) {
959+
Text(
960+
"Save",
961+
fontFamily = FontFamily(Font(R.font.sf_pro)),
962+
fontWeight = FontWeight.Medium
963+
)
964+
}
965+
},
966+
dismissButton = {
967+
TextButton(
968+
onClick = { showCameraDialog.value = false }
969+
) {
970+
Text(
971+
"Cancel",
972+
fontFamily = FontFamily(Font(R.font.sf_pro)),
973+
fontWeight = FontWeight.Medium
974+
)
975+
}
976+
}
977+
)
978+
}
880979
}
881980
}
882981
}

android/app/src/main/java/me/kavishdevar/librepods/services/AppListenerService.kt

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,47 @@ import kotlin.io.encoding.ExperimentalEncodingApi
2828

2929
private const val TAG="AppListenerService"
3030

31-
val cameraPackages = setOf(
31+
val cameraPackages = mutableSetOf(
3232
"com.google.android.GoogleCamera",
3333
"com.sec.android.app.camera",
3434
"com.android.camera",
3535
"com.oppo.camera",
3636
"com.motorola.camera2",
37-
"org.codeaurora.snapcam",
38-
"com.nothing.camera"
37+
"org.codeaurora.snapcam"
3938
)
4039

4140
var cameraOpen = false
41+
private var currentCustomPackage: String? = null
4242

4343
class AppListenerService : AccessibilityService() {
44+
private lateinit var prefs: android.content.SharedPreferences
45+
private val preferenceChangeListener = android.content.SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
46+
if (key == "custom_camera_package") {
47+
val newPackage = sharedPreferences.getString(key, null)
48+
currentCustomPackage?.let { cameraPackages.remove(it) }
49+
if (newPackage != null && newPackage.isNotBlank()) {
50+
cameraPackages.add(newPackage)
51+
}
52+
currentCustomPackage = newPackage
53+
}
54+
}
55+
56+
override fun onCreate() {
57+
super.onCreate()
58+
prefs = getSharedPreferences("settings", MODE_PRIVATE)
59+
val customPackage = prefs.getString("custom_camera_package", null)
60+
if (customPackage != null && customPackage.isNotBlank()) {
61+
cameraPackages.add(customPackage)
62+
currentCustomPackage = customPackage
63+
}
64+
prefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
65+
}
66+
67+
override fun onDestroy() {
68+
super.onDestroy()
69+
prefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
70+
}
71+
4472
override fun onAccessibilityEvent(ev: AccessibilityEvent?) {
4573
try {
4674
if (ev?.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {

android/app/src/main/res/values/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@
177177
<string name="camera_remote">Camera Remote</string>
178178
<string name="camera_control">Camera Control</string>
179179
<string name="camera_control_description">Capture a photo, start or stop recording, and more using either Press Once or Press and Hold. When using AirPods for camera actions, if you select Press Once, media control gestures will be unavailable, and if you select Press and Hold, listening mode and Digital Assistant gestures will be unavailable.</string>
180+
<string name="camera_control_app_description">Set a custom app package for camera detection</string>
181+
<string name="set_custom_camera_package">Set Custom Camera appid</string>
182+
<string name="enter_custom_camera_package">Enter the application id of the camera app:</string>
183+
<string name="custom_camera_package">Custom Camera appid</string>
184+
<string name="custom_camera_package_set_success">Custom camera appid set successfully</string>
180185
<string name="app_listener_service_label">Camera listener</string>
181186
<string name="app_listener_service_description">Listener service for LibrePods to detect when the camera is active to activate camera control on AirPods.</string>
182187
</resources>

0 commit comments

Comments
 (0)