App 2.17.1: tidier Settings and Logs

- Settings: the Wi-Fi and saved-networks cards are gone, and the rest
  sits in three columns (display and steering wheel | battery |
  charging price and app) instead of one tall column. The background
  Wi-Fi auto-connect stays on, without a switch.
- Logs: only the upload log. The steering-key reports, the car-colour
  probe and the screen line answered their questions and are removed,
  with their code (CarColorProbe, the key-report log) and strings.
- README lists the current tabs.

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-18 20:32:01 +02:00
co-authored by Claude Opus 5.5
parent 8d3eb80f66
commit 851a4a34d4
14 changed files with 24 additions and 298 deletions
@@ -35,7 +35,11 @@ import com.evsuite.hardware.telemetry.EnergyTelemetryReader;
public class MainActivity extends AppCompatActivity {
/** Shared with {@link AbrpUploadService}, which reads it on every tick. */
/**
* Rejoin a saved network (the phone hotspot) in the background; read by
* {@link AbrpUploadService} on every tick. On by default; the Wi-Fi card with its switch was
* removed from Settings (2.17.1), so it now stays on.
*/
static final String WIFI_AUTO_KEY = "wifi_auto_connect";
private static final String REPOSITORY_URL = "https://git.stinnesbeck.com/nils/mg4";
@@ -76,9 +80,6 @@ public class MainActivity extends AppCompatActivity {
/** The pages in navigation order. Parallel to {@link #TAB_IDS}. */
private View[] panes;
/** Wi-Fi page. The helper is the same one the upload service uses on its own tick. */
private WifiAutoConnect wifi;
private TextView wifiSsid, wifiState, wifiSavedList;
/**
* Value cells of the Vehicle page, looked up once and refreshed on the UI tick.
@@ -126,7 +127,6 @@ public class MainActivity extends AppCompatActivity {
/** Upload page: live telemetry switch and cadence. */
private SwitchMaterial liveTelemetrySwitch, boostSwitch, voiceKeySwitch, fullScreenSwitch;
private TextView steeringKeysText;
private com.google.android.material.textfield.MaterialAutoCompleteTextView intervalChoices;
private TextInputLayout lowSocLayout;
private TextInputEditText lowSocInput;
@@ -215,10 +215,8 @@ public class MainActivity extends AppCompatActivity {
@Override public void run() {
refreshStatus();
refreshCallLog();
refreshSteeringKeys();
sampleTrackers();
refreshConsumption();
refreshWifi();
uiHandler.postDelayed(this, 2_000L);
}
};
@@ -254,22 +252,12 @@ public class MainActivity extends AppCompatActivity {
bindVehiclePane();
bindConsumptionPane();
bindChargingPane();
bindWifiPane();
bindServerPane();
bindServicePane();
requestLocationPermissionIfNeeded();
statusText = servicePane.findViewById(R.id.status_text);
callLogText = logPane.findViewById(R.id.call_log_text);
steeringKeysText = logPane.findViewById(R.id.steering_keys_text);
TextView carColorText = logPane.findViewById(R.id.car_color_text);
showScreenInfo(logPane.findViewById(R.id.screen_text));
logPane.findViewById(R.id.car_color_button).setOnClickListener(v -> new Thread(() -> {
java.util.List<String> found = CarColorProbe.run(60);
String shown = found.isEmpty() ? getString(R.string.car_color_none)
: android.text.TextUtils.join("\n", found);
runOnUiThread(() -> carColorText.setText(shown));
}, "car-color-probe").start());
logPane.findViewById(R.id.flush_now_button).setOnClickListener(v -> manualFlush());
setUpPager();
@@ -292,21 +280,6 @@ public class MainActivity extends AppCompatActivity {
startForegroundService(new Intent(this, AbrpUploadService.class));
}
/**
* What the head unit reports about its screen, for the Logs tab: the panel in pixels and its
* density, and this app's window in pixels and in dp, which is what layouts are chosen by.
* Sources disagree on the MG4's numbers (1920×720, 1280×480, a 1778×720 window).
*/
@SuppressWarnings("deprecation") // getRealMetrics: the WindowMetrics API starts at 30; this is 28
private void showScreenInfo(TextView view) {
android.util.DisplayMetrics panel = new android.util.DisplayMetrics();
getWindowManager().getDefaultDisplay().getRealMetrics(panel);
android.util.DisplayMetrics window = getResources().getDisplayMetrics();
android.content.res.Configuration config = getResources().getConfiguration();
view.setText(getString(R.string.screen_info, panel.widthPixels, panel.heightPixels, panel.densityDpi,
window.widthPixels, window.heightPixels, config.screenWidthDp, config.screenHeightDp));
}
/**
* Shows a dialog without bringing the car's bars back. A dialog is a window of its own, and
* the system shows the bars when a window without the full-screen flags takes focus. So it
@@ -1224,45 +1197,6 @@ public class MainActivity extends AppCompatActivity {
}
}
// ---------- Wi-Fi page ----------
private void bindWifiPane() {
wifi = new WifiAutoConnect(getApplicationContext());
wifiSsid = settingsPane.findViewById(R.id.wifi_ssid);
wifiState = settingsPane.findViewById(R.id.wifi_state);
wifiSavedList = settingsPane.findViewById(R.id.wifi_saved_list);
SwitchMaterial auto = settingsPane.findViewById(R.id.wifi_auto_switch);
auto.setChecked(prefs.getBoolean(WIFI_AUTO_KEY, true));
auto.setOnCheckedChangeListener((btn, checked) ->
prefs.edit().putBoolean(WIFI_AUTO_KEY, checked).apply());
settingsPane.findViewById(R.id.wifi_connect_button).setOnClickListener(v -> {
// force: the driver is asking now, so the rate limit does not apply.
WifiAutoConnect.Result r = wifi.ensureConnected(true);
wifiState.setText(r.message);
refreshWifi();
});
}
private void refreshWifi() {
if (wifi == null) return;
String ssid = wifi.currentSsid();
wifiSsid.setText(ssid == null ? getString(R.string.wifi_not_connected) : ssid);
if (ssid != null) {
wifiState.setText(R.string.wifi_connected);
} else if (!wifi.isWifiEnabled()) {
wifiState.setText(R.string.wifi_off);
}
// Left alone otherwise: a message the button just set says more about what is
// happening than "not connected" would.
java.util.List<String> saved = wifi.savedNetworkNames();
wifiSavedList.setText(saved.isEmpty()
? getString(R.string.wifi_saved_empty)
: android.text.TextUtils.join("\n", saved));
}
// ---------- Vehicle page ----------
/** Looks up the value cells once; the labels are static and never touched from code. */
@@ -1752,15 +1686,6 @@ public class MainActivity extends AppCompatActivity {
}, "cloud-refresh").start();
}
/** What the car's steering-wheel key broadcasts looked like, newest first. */
private void refreshSteeringKeys() {
if (steeringKeysText == null) return;
java.util.List<String> keys = SteeringKeyListener.recent();
String text = keys.isEmpty() ? getString(R.string.steering_keys_empty)
: android.text.TextUtils.join("\n", keys);
if (!text.contentEquals(steeringKeysText.getText())) steeringKeysText.setText(text);
}
private void refreshCallLog() {
java.util.List<UploadLog.Entry> entries = AbrpUploadService.log().recent();
if (entries.isEmpty()) {