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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

## [1.2.11] - 2026-09-30

### Fixed

- The glucose screen no longer ends in "This task can't be done while driving" after a few minutes in the foreground. Android Auto allows an app only a handful of screen changes per task and counts an update as free only while the screen's titles stay the same, but the reading and its age were shown as titles, so every refresh used one up. The titles are now fixed labels ("Glucose", "Status") and the reading, delta and timestamps sit beneath them
- Switching sources on cars without tabs no longer uses up the same allowance, and no longer fails with three or four sources. The numbered source buttons changed the screen's title on every switch and were more buttons than that screen permits; sources are now switched through the "Switch source" list, as they already were for five or more

## [1.2.10] - 2026-09-12

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId = "de.autosugar"
minSdk = 26
targetSdk = 37
versionCode = 15
versionName = "1.2.10"
versionCode = 16
versionName = "1.2.11"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

Expand Down
86 changes: 34 additions & 52 deletions app/src/main/java/de/autosugar/car/GlucoseScreen.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package de.autosugar.car

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
import androidx.car.app.CarContext
import androidx.car.app.Screen
import androidx.car.app.annotations.RequiresCarApi
Expand Down Expand Up @@ -113,7 +108,6 @@ class GlucoseScreen(
// onGetTemplate can fire frequently; cache the small generated bitmaps so they are
// not re-rendered on the main thread on every rebuild.
private val trendIconCache = mutableMapOf<String, CarIcon>()
private val numberIconCache = mutableMapOf<Pair<Int, Boolean>, CarIcon>()

// A reading older than this is considered stale (≥2 missed 5-min CGM readings) and is
// labelled as such in the UI. Alerting itself is handled by BackgroundAlertMonitor.
Expand Down Expand Up @@ -233,7 +227,7 @@ class GlucoseScreen(

// endregion

// region PaneTemplate (fallback: 1 profile, >5 profiles, or CarApi < 6)
// region PaneTemplate (fallback: 1 profile, >4 profiles, or CarApi < 6)

private fun buildPaneTemplate(): Template {
val activeProfile = profiles.find { it.id == activeProfileId }
Expand All @@ -246,53 +240,33 @@ class GlucoseScreen(
.build()
}

/**
* Without tabs, switching sources goes through [SourceSelectScreen] for any number of
* profiles rather than switching in place.
*
* Switching in place changes the template title to the new profile's name, which the host
* never treats as a refresh: every switch spent a step of the five-template quota, and a
* handful of switches while driving ended in the host's "can't do this while driving"
* error. Popping back from the picker hands the quota back, and a back operation may
* change the contents of a same-type template freely, so the renamed pane costs nothing.
*
* It also replaces the numbered profile buttons this used for 2–4 profiles: the pane's
* action strip takes at most two actions, so three or four buttons failed validation.
*/
private fun buildActionStrip(): ActionStrip {
val builder = ActionStrip.Builder()
return when {
profiles.size > 4 -> builder.addAction(
Action.Builder()
.setTitle(carContext.getString(R.string.action_switch_source))
.setOnClickListener {
screenManager.push(
SourceSelectScreen(carContext, repository) { id -> switchTo(id) }
)
}
.build()
).build()
profiles.size in 2..5 -> {
// Numbered icon fallback when TabTemplate is unavailable (CarApi < 6).
// The upper bound of 5 here is unreachable in practice since the ">4"
// branch above already matches size 5 — this only ever runs for 2..4.
profiles.forEachIndexed { index, profile ->
val active = profile.id == activeProfileId
builder.addAction(
Action.Builder()
.setIcon(numberIconCache.getOrPut(index + 1 to active) {
profileNumberIcon(index + 1, active)
})
.setOnClickListener { switchTo(profile.id) }
.build()
val action = if (profiles.size >= 2) {
Action.Builder()
.setTitle(carContext.getString(R.string.action_switch_source))
.setOnClickListener {
screenManager.push(
SourceSelectScreen(carContext, repository) { id -> switchTo(id) }
)
}
builder.build()
}
else -> builder.addAction(Action.APP_ICON).build()
}
}

private fun profileNumberIcon(number: Int, active: Boolean): CarIcon {
val size = 96
val bmp = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
val c = Canvas(bmp)
val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = if (active) Color.WHITE else Color.argb(150, 200, 200, 200)
textSize = size * 0.65f
textAlign = Paint.Align.CENTER
typeface = Typeface.DEFAULT_BOLD
.build()
} else {
Action.APP_ICON
}
val textY = size / 2f - (paint.fontMetrics.ascent + paint.fontMetrics.descent) / 2f
c.drawText(number.toString(), size / 2f, textY, paint)
return CarIcon.Builder(IconCompat.createWithBitmap(bmp)).build()
return ActionStrip.Builder().addAction(action).build()
}

// endregion
Expand All @@ -318,11 +292,18 @@ class GlucoseScreen(
.build()

else -> {
// Row titles must never carry live data. The host treats a new Pane as a refresh
// (free) only while the template title, the row count and every row title stay
// the same; anything else counts as a new step against the five-template quota.
// With the reading and its age in the titles, every poll spent a step, and a few
// minutes on screen while driving ended in the host's "can't do this while
// driving" error. Everything that changes goes into the row texts instead.
val e = entry!!
val now = System.currentTimeMillis()
val stale = errorMessage != null || now - e.dateMs > staleAfterMs
val statsRow = Row.Builder()
.setTitle(
.setTitle(carContext.getString(R.string.label_status))
.addText(
if (stale)
carContext.getString(R.string.label_stale_reading, ageString(now - e.dateMs))
else
Expand All @@ -334,7 +315,8 @@ class GlucoseScreen(
statsRow.addText(carContext.getString(R.string.label_received, ageString(now - lastFetchedMs)))
}
val valueRow = Row.Builder()
.setTitle("${e.displayValue(unit)} ${unitLabel(unit)}")
.setTitle(carContext.getString(R.string.label_glucose))
.addText("${e.displayValue(unit)} ${unitLabel(unit)}")
.addText("${e.displayDelta(unit) ?: "-"} ${unitLabel(unit)}")
if (TREND_ARROW_ENABLED) {
valueRow.setImage(
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ القراءة: %s</string>
<string name="label_reading">القراءة: %s</string>
<string name="label_received">تم الاستقبال: %s</string>
<string name="label_glucose">الجلوكوز</string>
<string name="label_status">الحالة</string>

<!-- Settings UI -->
<string name="label_settings">الإعدادات</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ Messung: %s</string>
<string name="label_reading">Messung: %s</string>
<string name="label_received">Empfangen: %s</string>
<string name="label_glucose">Blutzucker</string>
<string name="label_status">Status</string>

<!-- Settings UI -->
<string name="label_settings">Einstellungen</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ Lectura: %s</string>
<string name="label_reading">Lectura: %s</string>
<string name="label_received">Recibido: %s</string>
<string name="label_glucose">Glucosa</string>
<string name="label_status">Estado</string>

<!-- Settings UI -->
<string name="label_settings">Ajustes</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ Lecture : %s</string>
<string name="label_reading">Lecture : %s</string>
<string name="label_received">Reçu : %s</string>
<string name="label_glucose">Glycémie</string>
<string name="label_status">État</string>

<!-- Settings UI -->
<string name="label_settings">Paramètres</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-hi/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ रीडिंग: %s</string>
<string name="label_reading">रीडिंग: %s</string>
<string name="label_received">प्राप्त: %s</string>
<string name="label_glucose">ग्लूकोज़</string>
<string name="label_status">स्थिति</string>

<!-- Settings UI -->
<string name="label_settings">सेटिंग्स</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ Lettura: %s</string>
<string name="label_reading">Lettura: %s</string>
<string name="label_received">Ricevuto: %s</string>
<string name="label_glucose">Glicemia</string>
<string name="label_status">Stato</string>

<!-- Settings UI -->
<string name="label_settings">Impostazioni</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-ja/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ 測定値: %s</string>
<string name="label_reading">測定値: %s</string>
<string name="label_received">受信: %s</string>
<string name="label_glucose">血糖値</string>
<string name="label_status">ステータス</string>

<!-- Settings UI -->
<string name="label_settings">設定</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-nl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ Meting: %s</string>
<string name="label_reading">Meting: %s</string>
<string name="label_received">Ontvangen: %s</string>
<string name="label_glucose">Glucose</string>
<string name="label_status">Status</string>

<!-- Settings UI -->
<string name="label_settings">Instellingen</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-pt/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ Leitura: %s</string>
<string name="label_reading">Leitura: %s</string>
<string name="label_received">Recebido: %s</string>
<string name="label_glucose">Glicose</string>
<string name="label_status">Estado</string>

<!-- Settings UI -->
<string name="label_settings">Configurações</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-zh/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="label_stale_reading">⚠️ 读数:%s</string>
<string name="label_reading">读数:%s</string>
<string name="label_received">已接收:%s</string>
<string name="label_glucose">血糖</string>
<string name="label_status">状态</string>

<!-- Settings UI -->
<string name="label_settings">设置</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 @@ -37,6 +37,8 @@
<string name="label_reading">Reading: %s</string>
<string name="label_stale_reading">⚠️ Reading: %s</string>
<string name="label_received">Received: %s</string>
<string name="label_glucose">Glucose</string>
<string name="label_status">Status</string>

<!-- Glucose alerts -->
<string name="label_glucose_alerts">Glucose alerts</string>
Expand Down
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-ar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
إصلاح خطأ "لا يمكن تنفيذ هذه المهمة أثناء القيادة" الذي كان يظهر بعد بضع دقائق على شاشة الجلوكوز. تظهر القراءة الآن أسفل التسمية الثابتة "الجلوكوز". في السيارات بدون علامات تبويب، بدّل المصدر عبر "تبديل المصدر"؛ ويعمل ذلك الآن مع ثلاثة أو أربعة مصادر أيضًا.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-de-DE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Behebt den Fehler „kann nicht während der Fahrt erledigt werden“, der nach einigen Minuten auf dem Glukosebildschirm erschien. Der Wert steht jetzt unter der festen Beschriftung „Blutzucker“. In Autos ohne Tabs wechselst du Quellen über „Quelle wechseln“; das klappt jetzt auch mit drei oder vier Quellen.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-en-US
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixes the "can't be done while driving" error that appeared after a few minutes on the glucose screen. The reading now sits under a fixed "Glucose" label. On cars without tabs, switch sources via "Switch Source"; this also works with three or four sources now.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-es-ES
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Corrige el error «no se puede hacer mientras conduces» que aparecía tras unos minutos en la pantalla de glucosa. La lectura aparece ahora bajo la etiqueta fija «Glucosa». En coches sin pestañas, cambia de fuente con «Cambiar fuente»; ahora también funciona con tres o cuatro fuentes.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-fr-FR
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Corrige l’erreur « impossible pendant la conduite » qui apparaissait après quelques minutes sur l’écran de glycémie. La valeur s’affiche désormais sous le libellé fixe « Glycémie ». Sur les voitures sans onglets, changez de source via « Changer de source » ; cela fonctionne aussi avec trois ou quatre sources.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-hi-IN
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ग्लूकोज़ स्क्रीन पर कुछ मिनट बाद दिखने वाली "ड्राइविंग के दौरान यह नहीं किया जा सकता" त्रुटि ठीक की गई। रीडिंग अब स्थायी "ग्लूकोज़" लेबल के नीचे दिखती है। बिना टैब वाली कारों में "स्रोत बदलें" से स्रोत बदलें; अब यह तीन या चार स्रोतों के साथ भी काम करता है।
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-it-IT
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Corregge l’errore «non è possibile durante la guida» che compariva dopo alcuni minuti sulla schermata della glicemia. Il valore appare ora sotto l’etichetta fissa «Glicemia». Sulle auto senza schede, cambia sorgente con «Cambia sorgente»; ora funziona anche con tre o quattro sorgenti.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-ja-JP
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
血糖値画面を数分表示すると「運転中はこの操作を行えません」と表示される問題を修正しました。測定値は固定ラベル「血糖値」の下に表示されます。タブのない車では「ソース切替」から切り替えます。3〜4個のソースでも動作するようになりました。
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-nl-NL
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Verhelpt de fout ‘kan niet tijdens het rijden’ die na een paar minuten op het glucosescherm verscheen. De meting staat nu onder het vaste label ‘Glucose’. In auto’s zonder tabbladen wissel je van bron via ‘Bron wisselen’; dat werkt nu ook met drie of vier bronnen.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-pt-PT
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Corrige o erro «não pode ser feito durante a condução» que surgia após alguns minutos no ecrã de glicose. A leitura aparece agora sob a etiqueta fixa «Glicose». Em carros sem separadores, troque de fonte com «Trocar fonte»; agora também funciona com três ou quatro fontes.
1 change: 1 addition & 0 deletions docs/whatsnew/1.2.11-zh-CN
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
修复了血糖界面显示几分钟后出现“驾驶时无法执行此操作”错误的问题。读数现在显示在固定标签“血糖”下方。在不支持标签页的车辆上,请通过“切换来源”切换;现在三个或四个来源也能正常使用。
Loading