diff --git a/SPECS.md b/SPECS.md index 0ec7454..d5fa8e9 100644 --- a/SPECS.md +++ b/SPECS.md @@ -114,6 +114,9 @@ tyre pressures, GPS (lat, lon, elevation, heading) and the is_* flags. It does * INGEST_TOKEN) into git and pushed it. Commit amended and force-pushed; both values regenerated in the now gitignored `k8s/secrets.yaml` (since moved to `k8s/secrets/secrets.yaml`, outside `kubectl apply -f k8s/`). Filled-in secrets live only there from now on. +- 2026-10-17 — App 2.8.0: immersive full screen (switch in the Upload tab, default on). Hides the + system bars on the emulator; whether SAIC's own bars on the MG4 can be hidden is only known once + tried on the car. - 2026-10-17 — App 2.7.1: the voice key works. The car's key report, read off the on-screen log: `android.intent.extra.hardkey.keycode` (Integer), `.down` (Boolean, a report per press and per release), `.longpress` (Boolean). 2.7.0 looked only for short names and never found the code. diff --git a/app/build.gradle b/app/build.gradle index f38b18d..a050f40 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { applicationId "com.stinnesbeck.nilsmg4" minSdk 27 targetSdk 36 - versionCode 65 - versionName "2.7.1" + versionCode 66 + versionName "2.8.0" // Nothing about the server ships in the APK: its URL and ingest token are entered in // the app's Server tab (ServerConfig), and the database is only reachable by the server. diff --git a/app/src/main/java/com/evsuite/abrp/MainActivity.java b/app/src/main/java/com/evsuite/abrp/MainActivity.java index fae8d78..44fa0b0 100644 --- a/app/src/main/java/com/evsuite/abrp/MainActivity.java +++ b/app/src/main/java/com/evsuite/abrp/MainActivity.java @@ -120,7 +120,7 @@ public class MainActivity extends AppCompatActivity { private TextView connectionStatusText; /** Upload page: live telemetry switch and cadence. */ - private SwitchMaterial liveTelemetrySwitch, boostSwitch, voiceKeySwitch; + private SwitchMaterial liveTelemetrySwitch, boostSwitch, voiceKeySwitch, fullScreenSwitch; private TextView steeringKeysText; private android.widget.Spinner intervalSpinner; private TextInputLayout lowSocLayout; @@ -308,6 +308,35 @@ public class MainActivity extends AppCompatActivity { uiHandler.post(uiRefresh); } + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + // The system shows its bars again when focus moves (a dialog, the bars swiped in); + // re-applying on regaining focus keeps the app full screen. + if (hasFocus) applyFullScreen(); + } + + /** + * Immersive full screen: the head unit's top and bottom bars are hidden while the app is + * in front, and a swipe from the edge shows them briefly. On the MG4 those bars are SAIC's + * own (climate strip, hazard and home shortcuts); if the platform keeps them, these flags + * simply have no effect. + */ + @SuppressWarnings("deprecation") // the WindowInsetsController API starts at 30; this is 28 + private void applyFullScreen() { + View decor = getWindow().getDecorView(); + if (UploadSettings.fullScreen(prefs)) { + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN); + } else { + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + } + } + @Override protected void onPause() { super.onPause(); @@ -798,6 +827,12 @@ public class MainActivity extends AppCompatActivity { voiceKeySwitch.setChecked(UploadSettings.voiceKeyOpensApp(prefs)); voiceKeySwitch.setOnCheckedChangeListener((btn, checked) -> prefs.edit().putBoolean(UploadSettings.KEY_VOICE_KEY_OPENS, checked).apply()); + fullScreenSwitch = servicePane.findViewById(R.id.full_screen_switch); + fullScreenSwitch.setChecked(UploadSettings.fullScreen(prefs)); + fullScreenSwitch.setOnCheckedChangeListener((btn, checked) -> { + prefs.edit().putBoolean(UploadSettings.KEY_FULL_SCREEN, checked).apply(); + applyFullScreen(); + }); liveTelemetrySwitch = servicePane.findViewById(R.id.abrp_upload_switch); intervalSpinner = servicePane.findViewById(R.id.interval_spinner); boostSwitch = servicePane.findViewById(R.id.boost_switch); diff --git a/app/src/main/java/com/evsuite/abrp/UploadSettings.java b/app/src/main/java/com/evsuite/abrp/UploadSettings.java index fd3d717..7a867a3 100644 --- a/app/src/main/java/com/evsuite/abrp/UploadSettings.java +++ b/app/src/main/java/com/evsuite/abrp/UploadSettings.java @@ -16,6 +16,13 @@ final class UploadSettings { static final String KEY_LOW_SOC_PERCENT = "low_soc_percent"; static final String KEY_AUTOSTART = "autostart"; static final String KEY_ABRP_UPLOAD_ENABLED = "abrp_upload_enabled"; + /** Hide the head unit's system bars while the app is open. */ + static final String KEY_FULL_SCREEN = "full_screen"; + + static boolean fullScreen(SharedPreferences prefs) { + return prefs.getBoolean(KEY_FULL_SCREEN, true); + } + /** A double press of the steering wheel's voice key opens the app. */ static final String KEY_VOICE_KEY_OPENS = "voice_key_opens_app"; diff --git a/app/src/main/res/layout-w1000dp/pane_service.xml b/app/src/main/res/layout-w1000dp/pane_service.xml index ea2863f..2ed63fd 100644 --- a/app/src/main/res/layout-w1000dp/pane_service.xml +++ b/app/src/main/res/layout-w1000dp/pane_service.xml @@ -6,6 +6,8 @@ + + diff --git a/app/src/main/res/layout/pane_service.xml b/app/src/main/res/layout/pane_service.xml index b14540c..fbe693c 100644 --- a/app/src/main/res/layout/pane_service.xml +++ b/app/src/main/res/layout/pane_service.xml @@ -6,6 +6,8 @@ + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9f7431d..6d4d5ab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -107,6 +107,8 @@ Connection timed out Server error (HTTP %1$d) + Full screen + Hides the car\'s top and bottom bars while this app is open. Swipe in from the top or bottom edge to show them briefly, e.g. for the climate controls. Double-press the voice key to open this app Press the voice key on the steering wheel twice quickly. The voice assistant may still react to the presses. Steering-wheel keys