App 2.8.0: full screen

Immersive full screen while the app is in front: the system's top and
bottom bars are hidden, and a swipe from the edge shows them briefly.
Re-applied whenever the window regains focus. A "Full screen" switch in
the Upload tab (default on) turns it off.

On the Android 9 emulator the bars are hidden (system UI flags 0x1706),
stay hidden after leaving and returning, and the switch toggles them
through the UI. Whether SAIC's own bars on the MG4 obey the flags is
only known on the car; if they do not, nothing changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
This commit is contained in:
2026-10-17 23:52:33 +02:00
co-authored by Claude Opus 5.5
parent 55710fb722
commit 3f1e196817
7 changed files with 54 additions and 3 deletions
@@ -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);