Skip to content

Commit bc50f18

Browse files
authored
Merge pull request #110 from xLexip/develop
v1.2.0
2 parents 708aecf + 3601af4 commit bc50f18

File tree

13 files changed

+169
-56
lines changed

13 files changed

+169
-56
lines changed
2.36 MB
Loading
41.2 KB
Loading

README.md

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,62 @@
1-
[![Feature Graphic with App Screenshot](https://i.ibb.co/bjHmz8Sh/feature-graphic-gh.png)](https://play.google.com/store/apps/details?id=dev.lexip.hecate&referrer=utm_source%3Dgithub%26utm_medium%3Dreadme_banner)
1+
[![Feature Graphic / Screenshot](.github/resources/feature-graphic.png)](https://play.google.com/store/apps/details?id=dev.lexip.hecate&referrer=utm_source%3Dgithub%26utm_medium%3Dreadme_banner)
22

33
# Adaptive Theme: Auto Dark Mode by Ambient Light
44

5-
Adaptive Theme automatically switches between light and **dark mode**
5+
Adaptive Theme automatically switches between light and dark mode
66
using the **ambient light sensor** — not a fixed schedule.
77

88
It adapts to real lighting conditions to optimize **readability**, **eye comfort**, and **battery
99
life**.
1010

1111
<a href="https://play.google.com/store/apps/details?id=dev.lexip.hecate&referrer=utm_source%3Dgithub%26utm_medium%3Dreadme_button">
12-
<img src=".github/resources/get-it-on-google-play.svg" alt="Get Adaptive Theme on Google Play" width="200"/>
12+
<img src=".github/resources/get-it-on-google-play.svg" alt="Get it on Google Play" width="200"/>
1313
</a>
1414
‎ ‎ ‎
1515
<a href="https://github.com/xLexip/Adaptive-Theme/releases/latest">
16-
<img src=".github/resources/github-releases.png" alt="GitHub" width="200"/>
16+
<img src=".github/resources/github-releases.png" alt="GitHub Releases" width="200"/>
17+
</a>
18+
‎ ‎ ‎
19+
<a href="https://play.google.com/store/apps/details?id=moe.shizuku.privileged.api&referrer=utm_source%3Dgithub%26utm_medium%3Dxlexip">
20+
<img src=".github/resources/works-with-shizuku.png" alt="Shizuku (PlayStore)" width="200"/>
1721
</a>
1822

19-
## 🚀 Quick Start (2 minutes)
23+
### YouTube: [HowToMen – Top 15 Best Android Apps - February 2026](https://www.youtube.com/watch?v=iY3FBMTA15A&t=98s&ref=GitHub_xLexip)
24+
25+
## Quick Start (2 minutes)
2026

2127
1. **Install** Adaptive Theme.
22-
2. **Grant the permission** with the [web-tool](https://lexip.dev/setup), Shizuku, or other methods
23-
below.
24-
3. **Pick your lux threshold** and you’re done. ✅
28+
2. **Grant the permission** with the [web-tool](https://lexip.dev/setup), Shizuku, or other methods.
29+
3. **Pick your lux threshold** and you’re done.
2530

26-
## 📋 Table of Contents
31+
## Table of Contents
2732

28-
- [✨ Features & Highlights](#-features--highlights)
29-
- [🛠️ One-Time Setup](#%EF%B8%8F-one-time-setup)
30-
- [✅ Safety](#-safety)
31-
- [⚙️ How it Works](#%EF%B8%8F-how-it-works)
32-
- [❓ FAQ](#-faq)
33-
- [❤️ Support the Project](#%EF%B8%8F-support-the-project)
34-
- [🏗️ Architecture & Tech Stack](#%EF%B8%8F-architecture--tech-stack)
33+
- [Features & Highlights](#features--highlights)
34+
- [One-Time Setup](#one-time-setup)
35+
- [Safety](#safety)
36+
- [How it works](#how-it-works)
37+
- [FAQ](#faq)
38+
- [Support the Project](#support-the-project)
39+
- [Architecture & Tech Stack](#architecture--tech-stack)
40+
- [Credits](#credits)
3541

36-
## Features & Highlights
42+
## Features & Highlights
3743

38-
* 🌤️ **Smart Detection:** Uses your devices physical light sensor to switch the system
44+
* **Smart Detection:** Uses your devices physical light sensor to switch the system
3945
theme.
40-
* ⚙️ **Custom brightness threshold:** Choose exactly when the theme should flip or use a preset (
46+
* **Custom brightness threshold:** Choose exactly when the theme should flip or use a preset (
4147
indoor, outdoor, sunlight, etc.).
42-
* 🔋 **Battery Friendly:** The app is passive. Its event-driven architecture only checks the sensor
48+
* **Battery Friendly:** The app is passive. Its event-driven architecture only checks the sensor
4349
when you turn on the screen — zero battery drain in the background.
44-
* 🗝️ **No Root Required:** Root access is not required (but supported as an alternative setup
50+
* **No Root Required:** Root access is not required (but supported as an alternative setup
4551
method).
46-
* 🐱 **Shizuku Support:** One of multiple setup options is
52+
* **Shizuku Support:** One of multiple setup options is
4753
using [Shizuku](https://github.com/RikkaApps/Shizuku).
48-
* 🚀 **Modern & Native:** Built with best-practices using Kotlin, Jetpack Compose and Material You
54+
* **Modern & Native:** Built with best-practices using Kotlin, Jetpack Compose and Material You
4955
for a smooth and solid experience.
50-
* 🌍 **50+ Languages:** Applied globalization at its best.
51-
* 🔒 **Transparent:** Free, open-source, no-ads.
56+
* **50+ Languages:** Applied globalization at its best.
57+
* **Transparent:** Free, open-source, no-ads.
5258

53-
## 🛠️ One-Time Setup
59+
## One-Time Setup
5460

5561
Android restricts apps from changing system themes by default. To unlock this feature, the
5662
permission (`WRITE_SECURE_SETTINGS`) has to be granted.
@@ -64,7 +70,7 @@ methods to do so:
6470
installation required (WebADB).
6571
👉 **[lexip.dev/setup](https://lexip.dev/setup)**
6672

67-
* **Shizuku** – If you have **[Shizuku](https://github.com/RikkaApps/Shizuku)** installed and
73+
* **Shizuku** – If you have [Shizuku](https://github.com/RikkaApps/Shizuku) installed and
6874
configured, you can
6975
grant the permission directly within Adaptive Theme.
7076

@@ -75,14 +81,14 @@ methods to do so:
7581
manually:
7682
```adb shell pm grant dev.lexip.hecate android.permission.WRITE_SECURE_SETTINGS```
7783

78-
## Safety
84+
## Safety
7985

8086
The required permission only allows the app to change system settings such as the dark mode. This is
8187
absolutely safe and
8288
completely reversible by uninstalling the app. It does **not** grant root access or read any user
8389
data.
8490

85-
## ⚙️ How it Works
91+
## How it works
8692

8793
**Wondering why the theme didn't change immediately?**
8894

@@ -91,11 +97,11 @@ To avoid screen flicker and unnecessary background work, Adaptive Theme follows
9197
- **Event-driven:** It checks the light sensor only right after the screen turns on. Combined with
9298
hysteresis, this prevents flicker, avoids interruptions while you’re using the phone, and saves
9399
battery.
94-
- **Validity check:** It verifies that the sensor is not obstructed (e.g., by a hand or pocket).
100+
- **Validity check:** It verifies that the sensor is not obstructed (e.g. by a hand or pocket).
95101
- **Seamless switch:** It switches the theme instantly, ensuring the UI is ready before you start
96102
interacting with it.
97103

98-
## FAQ
104+
## FAQ
99105

100106
**Does this require root?**
101107

@@ -121,7 +127,7 @@ To avoid screen flicker and unnecessary background work, Adaptive Theme follows
121127
If Adaptive Theme doesn’t work for you — or if you have any questions or ideas — please [open an
122128
issue](https://github.com/xLexip/Adaptive-Theme/issues/new) here or send feedback via the app.
123129

124-
## ❤️ Support the Project
130+
## Support the Project
125131

126132
Adaptive Theme is **completely free**, **ad-free**, **open source**, and developed in my free time.
127133

@@ -138,7 +144,7 @@ also [buy me a coffee](https://buymeacoffee.com/lexip).
138144

139145
📣 **Spread the Word:** Share the app to help the project grow.
140146

141-
## 🏗️ Architecture & Tech Stack
147+
## Architecture & Tech Stack
142148

143149
[![Android](https://img.shields.io/badge/Android-3DDC84?style=for-the-badge&logo=android&logoColor=white)](https://developer.android.com/)
144150
[![Kotlin](https://img.shields.io/badge/Kotlin-B125EA?style=for-the-badge&logo=kotlin&logoColor=white)](https://kotlinlang.org/)
@@ -162,12 +168,15 @@ including haptic feedback.
162168
**Background Work:** Sensor operations run event-driven – only upon screen-on
163169
broadcasts – ensuring zero unnecessary battery drain in the background.
164170

165-
### **Made with 🥨 in Germany.**
171+
## Credits
172+
173+
* Thanks to Facundo Holzmeister (HowToMen)
174+
for featuring Adaptive Theme in
175+
a [YouTube video](https://youtu.be/iY3FBMTA15A?si=N8aCNyHj7vzRpiiC&t=98).
176+
* Thanks to Abdul
177+
for featuring Adaptive Theme in
178+
a [YouTube video](https://youtu.be/CH_4E1LzGcU?si=BHWwIAIMiiWp6iWf&t=459).
179+
* Thanks to [AlbertCaro](https://github.com/xLexip/Adaptive-Theme/pull/107) for spanish translation
180+
strings.
166181

167-
> ~~> Keywords: theme switcher · android automation · night mode · dark sense · automatic android
168-
dark
169-
mode ·
170-
brightness-based ·
171-
light-based · based on lux · google pixel · auto dark theme · shizuku apps · android 14 · android
172-
15 · android 16 ·
173-
android 17 <~~
182+
### **Made with 🥨 in Germany.**

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ android {
1616
applicationId = "dev.lexip.hecate"
1717
minSdk = 34
1818
targetSdk = 35
19-
versionCode = 103
20-
versionName = "1.1.0"
19+
versionCode = 106
20+
versionName = "1.2.0"
2121
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2222
}
2323

app/src/main/kotlin/dev/lexip/hecate/ui/MainScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ fun MainScreen(
168168
ThreeDotMenu(
169169
isAdaptiveThemeEnabled = uiState.adaptiveThemeEnabled,
170170
packageName = packageName,
171+
isInstalledFromPlayStore = uiState.isInstalledFromPlayStore,
171172
onShowCustomThresholdDialog = { showCustomDialog.value = true }
172173
)
173174
},

app/src/main/kotlin/dev/lexip/hecate/ui/MainViewModel.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import dev.lexip.hecate.data.UserPreferencesRepository
2525
import dev.lexip.hecate.logging.Logger
2626
import dev.lexip.hecate.services.BroadcastReceiverService
2727
import dev.lexip.hecate.util.DarkThemeHandler
28+
import dev.lexip.hecate.util.InstallSourceChecker
2829
import dev.lexip.hecate.util.LightSensorManager
2930
import dev.lexip.hecate.util.ProximitySensorManager
3031
import kotlinx.coroutines.CoroutineDispatcher
@@ -51,7 +52,8 @@ data class MainUiState(
5152
val customAdaptiveThemeThresholdLux: Float? = null,
5253
val hasSetupCompleted: Boolean = false,
5354
val isDeviceCovered: Boolean = false,
54-
val isShizukuInstalled: Boolean = false
55+
val isShizukuInstalled: Boolean = false,
56+
val isInstalledFromPlayStore: Boolean = false
5557
)
5658

5759
class MainViewModel(
@@ -143,6 +145,11 @@ class MainViewModel(
143145
private var customThresholdTemp: Float? = null
144146

145147
init {
148+
viewModelScope.launch(ioDispatcher) {
149+
val fromPlayStore = InstallSourceChecker.fromPlayStore(application)
150+
_uiState.value = _uiState.value.copy(isInstalledFromPlayStore = fromPlayStore)
151+
}
152+
146153
viewModelScope.launch {
147154
userPreferencesRepository.userPreferencesFlow.collect { userPreferences ->
148155
_uiState.value = _uiState.value.copy(

app/src/main/kotlin/dev/lexip/hecate/ui/components/ThreeDotMenu.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import dev.lexip.hecate.BuildConfig
2929
import dev.lexip.hecate.R
3030
import dev.lexip.hecate.logging.Logger
3131
import dev.lexip.hecate.util.InAppReviewHandler
32-
import dev.lexip.hecate.util.InstallSourceChecker
3332
import java.net.URLEncoder
3433
import java.nio.charset.StandardCharsets
3534

@@ -39,6 +38,7 @@ const val FEEDBACK_SUBJECT = "Adaptive Theme Feedback (v${BuildConfig.VERSION_NA
3938
fun ThreeDotMenu(
4039
isAdaptiveThemeEnabled: Boolean,
4140
packageName: String,
41+
isInstalledFromPlayStore: Boolean,
4242
onShowCustomThresholdDialog: () -> Unit
4343
) {
4444
val context = LocalContext.current
@@ -123,7 +123,7 @@ fun ThreeDotMenu(
123123

124124
// 4) Beta Feedback (only on beta builds from Play Store)
125125
if (BuildConfig.VERSION_NAME.contains("-beta")
126-
&& InstallSourceChecker.fromPlayStore(context)
126+
&& isInstalledFromPlayStore
127127
) {
128128
DropdownMenuItem(
129129
text = { Text(text = "Beta Feedback") },
@@ -156,7 +156,7 @@ fun ThreeDotMenu(
156156
}
157157

158158
val supportUri =
159-
"https://github.com/xLexip/Adaptive-Theme?tab=readme-ov-file#%EF%B8%8F-support-the-project".toUri()
159+
"https://lexip.dev/hecate/support-the-project".toUri()
160160
val supportIntent = Intent(Intent.ACTION_VIEW, supportUri)
161161
try {
162162
context.startActivity(supportIntent)
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<resources>
2+
<string name="action_back">Atrás</string>
3+
<string name="action_cancel">Cancelar</string>
4+
<string name="action_close">Cerrar</string>
5+
<string name="action_continue">Continuar</string>
6+
<string name="action_disable_notification">Ocultar notificación</string>
7+
<string name="action_finish">Finalizar</string>
8+
<string name="action_set">Establecer</string>
9+
<string name="action_share_url">Compartir enlace</string>
10+
<string name="action_skip">Omitir</string>
11+
<string name="action_use_adaptive_theme">Usar %1$s</string>
12+
13+
<string name="description_service_purpose">
14+
Alterna entre el modo claro y oscuro según la luz ambiental, optimizando el confort visual y la batería.
15+
</string>
16+
17+
<string name="description_switching_conditions">
18+
Los cambios solo ocurren inmediatamente después de encender la pantalla, siempre que el sensor no esté cubierto.
19+
</string>
20+
21+
<string name="description_notification_service_running">
22+
Ajustando el tema del sistema según el brillo ambiental.
23+
</string>
24+
25+
<string name="device_covered_title">Sensor cubierto</string>
26+
<string name="device_covered_message">Los cambios de tema están pausados porque el sensor de luz está cubierto.</string>
27+
28+
<string name="error_invalid_lux_value">Valor de brillo no válido.</string>
29+
<string name="error_negative_lux_value">El valor no puede ser negativo.</string>
30+
<string name="error_lux_value_too_large">El valor no puede exceder 100,000.</string>
31+
32+
<string name="title_about_github">Acerca de / GitHub</string>
33+
<string name="title_brightness_threshold">Umbral de brillo</string>
34+
<string name="title_live_measurement">Valor en vivo</string>
35+
<string name="title_change_language">Cambiar idioma</string>
36+
<string name="title_current_brightness">Brillo actual</string>
37+
<string name="title_custom_threshold">Umbral personalizado</string>
38+
<string name="title_more">Más</string>
39+
<string name="title_notification_channel_service">Servicio de cambio de tema</string>
40+
<string name="title_send_feedback">Enviar comentarios</string>
41+
<string name="title_support_project">Apoyar el proyecto</string>
42+
43+
<string name="adaptive_threshold_bright">Brillante</string>
44+
<string name="adaptive_threshold_custom">Personalizado</string>
45+
<string name="adaptive_threshold_dark">Oscuro</string>
46+
<string name="adaptive_threshold_daylight">Luz de día</string>
47+
<string name="adaptive_threshold_dim">Tenue</string>
48+
<string name="adaptive_threshold_soft">Suave</string>
49+
<string name="adaptive_threshold_sunlight">Luz solar</string>
50+
51+
<string name="hint_custom_threshold_value">Valor en Lux</string>
52+
53+
<string name="setup_action_open_developer_settings">Abrir opciones para desarrolladores</string>
54+
<string name="setup_action_open_settings">Abrir configuración</string>
55+
<string name="setup_connect_title">Paso 2: Conectar a otro dispositivo</string>
56+
<string name="setup_connect_body">Para conceder el permiso, necesitas un <b>dispositivo secundario</b> (computadora, tableta o teléfono). Conecta este dispositivo a él mediante USB.</string>
57+
<string name="setup_developer_mode_title">Paso 1: Habilitar modo desarrollador</string>
58+
<string name="setup_developer_mode_body">Habilita la depuración por USB en las opciones para desarrolladores.</string>
59+
<string name="setup_developer_options_unlock">Desbloquear opciones para desarrolladores</string>
60+
<string name="setup_developer_options_enabled">Opciones para desarrolladores habilitadas</string>
61+
<string name="setup_dev_options_toast_one">Busca el número de compilación y tócalo 7 veces para habilitar las opciones para desarrolladores.</string>
62+
<string name="setup_dev_options_toast_two">Usa la función de búsqueda si no puedes encontrarlo.</string>
63+
<string name="setup_alternative_methods">Métodos alternativos</string>
64+
<string name="setup_grant_title">Paso 3: Conceder el permiso con el otro dispositivo</string>
65+
<string name="setup_grant_body">Abre el siguiente enlace en tu otro dispositivo y sigue las instrucciones:</string>
66+
<string name="setup_alternatives">Alternativamente, puedes ejecutar un comando ADB tú mismo o usar root para conceder el permiso. Shizuku también es compatible.</string>
67+
<string name="setup_permission_granted">Permiso concedido.</string>
68+
<string name="setup_permission_not_granted">Permiso aún no concedido. Por favor completa la configuración con el otro dispositivo.</string>
69+
<string name="setup_usb_debugging_disabled">Habilitar depuración por USB</string>
70+
<string name="setup_usb_debugging_enabled">Depuración por USB habilitada</string>
71+
<string name="setup_usb_debugging_toast">Habilitar depuración por USB</string>
72+
<string name="setup_usb_not_connected">Esperando conexión USB…</string>
73+
<string name="setup_usb_connected">USB conectado</string>
74+
<string name="setup_why_other_device_title">¿Por qué se requiere otro dispositivo?</string>
75+
<string name="setup_why_other_device">Android impide que las aplicaciones se concedan el permiso requerido a sí mismas. Requiere otro dispositivo con un navegador web o ADB instalado. </string>
76+
<string name="setup_is_this_safe_title">¿Es esto seguro?</string>
77+
<string name="setup_is_this_safe_body">Sí. Solo permite a la aplicación modificar configuraciones como el modo oscuro. Esto es absolutamente seguro y completamente reversible. Además, el código fuente está disponible públicamente en GitHub.</string>
78+
<string name="setup_shizuku_title">Alternativa: Shizuku</string>
79+
<string name="setup_shizuku_body">Si ya usas Shizuku, no necesitarás un segundo dispositivo ni ADB.</string>
80+
<string name="setup_shizuku_action">Usar Shizuku en su lugar</string>
81+
<string name="setup_action_use_root">Usar Root</string>
82+
<string name="setup_root_request">Solicitando acceso root…</string>
83+
<string name="setup_root_grant_failed">Falló la concesión de root.</string>
84+
<string name="setup_root_question">¿Está el dispositivo rooteado?</string>
85+
86+
<string name="setup_required_title">Configuración requerida</string>
87+
<string name="setup_required_message">%1$s requiere una configuración única para funcionar.</string>
88+
<string name="action_start_setup">Iniciar configuración</string>
89+
90+
<string name="shizuku_not_ready">Inicia Shizuku e inténtalo de nuevo.</string>
91+
<string name="shizuku_denied">Acceso denegado. Permite esta aplicación en Shizuku.</string>
92+
<string name="shizuku_request_permission">Solicitando permiso…</string>
93+
<string name="shizuku_grant_shell_failed">Shizuku no pudo ejecutar el comando.</string>
94+
<string name="shizuku_grant_unexpected">Error inesperado al usar Shizuku.</string>
95+
</resources>

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
sonar {
1212
properties {
1313
property("sonar.projectKey", "xLexip_Hecate")
14-
property("sonar.projectVersion", "1.1.0")
14+
property("sonar.projectVersion", "1.2.0")
1515
property("sonar.organization", "xlexip")
1616
property("sonar.host.url", "https://sonarcloud.io")
1717
property("sonar.androidLint.reportPaths", "app/build/reports/lint-results-debug.html")

0 commit comments

Comments
 (0)