From 5a82fe3dc1d338454e5597a936fc2df54690fef9 Mon Sep 17 00:00:00 2001 From: Nils Stinnesbeck Date: Sun, 18 Oct 2026 20:53:05 +0200 Subject: [PATCH] App 2.17.5: Server tab fits; installation ID is read-only - The "Your private connection" card is gone; its text was out of date (the ABRP credentials are no longer on the server). - Import from file moved next to Save and Test, in one row. - The installation ID is shown as text instead of an editable field: it is derived from the head unit, and changing it by hand only risked splitting the history. A config file can still carry an older one over, as before. - The page fits the car's 1778x640 window without scrolling (checked on the emulator), and the subtitle no longer says the server passes data on to ABRP. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki --- app/build.gradle | 4 +-- .../java/com/evsuite/abrp/MainActivity.java | 36 +++++++++---------- app/src/main/res/layout/pane_server.xml | 20 ++++------- app/src/main/res/values/strings.xml | 4 +-- app/src/main/res/values/strings_design.xml | 4 +-- 5 files changed, 27 insertions(+), 41 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c54e60a..396a0e6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { applicationId "com.stinnesbeck.nilsmg4" minSdk 27 targetSdk 36 - versionCode 93 - versionName "2.17.4" + versionCode 94 + versionName "2.17.5" // 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 00efca0..afffebc 100644 --- a/app/src/main/java/com/evsuite/abrp/MainActivity.java +++ b/app/src/main/java/com/evsuite/abrp/MainActivity.java @@ -114,8 +114,10 @@ public class MainActivity extends AppCompatActivity { private ChargingGraphView chargeGraph; /** Server page. */ - private TextInputLayout serverUrlLayout, serverTokenLayout, installationIdLayout; - private TextInputEditText serverUrlInput, serverTokenInput, installationIdInput; + private TextInputLayout serverUrlLayout, serverTokenLayout; + private TextInputEditText serverUrlInput, serverTokenInput; + /** Shown, not edited: derived from the head unit (ServerConfig.installationIdFor). */ + private TextView installationIdText; private View connectionStatusRow, connectionIndicator; private TextView connectionStatusText; @@ -460,19 +462,17 @@ public class MainActivity extends AppCompatActivity { private void bindServerPane() { serverUrlLayout = serverPane.findViewById(R.id.server_url_layout); serverTokenLayout = serverPane.findViewById(R.id.server_token_layout); - installationIdLayout = serverPane.findViewById(R.id.installation_id_layout); serverUrlInput = serverPane.findViewById(R.id.server_url_input); serverTokenInput = serverPane.findViewById(R.id.server_token_input); - installationIdInput = serverPane.findViewById(R.id.installation_id_input); + installationIdText = serverPane.findViewById(R.id.installation_id_text); connectionStatusRow = serverPane.findViewById(R.id.connection_status_row); connectionIndicator = serverPane.findViewById(R.id.connection_indicator); connectionStatusText = serverPane.findViewById(R.id.connection_status_text); showServerConfig(); - ((TextView) serverPane.findViewById(R.id.import_hint)) - .setText(getString(R.string.import_hint, configDirHint())); serverPane.findViewById(R.id.server_save_button).setOnClickListener(v -> { - if (saveServerConfig(textOf(serverUrlInput), textOf(serverTokenInput), textOf(installationIdInput))) { + if (saveServerConfig(textOf(serverUrlInput), textOf(serverTokenInput), + ServerConfig.get(this).installationId)) { setConnectionStatus(COLOR_OK, getString(R.string.server_saved)); } }); @@ -485,7 +485,7 @@ public class MainActivity extends AppCompatActivity { ServerConfig config = ServerConfig.get(this); serverUrlInput.setText(config.url); serverTokenInput.setText(config.token); - installationIdInput.setText(config.installationId); + installationIdText.setText(getString(R.string.installation_id_info, config.installationId)); } /** Validates, marks the bad fields, and saves only when all three are good. */ @@ -495,9 +495,12 @@ public class MainActivity extends AppCompatActivity { String id = rawId == null ? "" : rawId.trim().toLowerCase(java.util.Locale.US); serverUrlLayout.setError(url == null ? getString(R.string.server_err_url) : null); serverTokenLayout.setError(ServerConfig.isValidToken(token) ? null : getString(R.string.server_err_token)); - installationIdLayout.setError(ServerConfig.isValidInstallationId(id) - ? null : getString(R.string.server_err_installation_id)); - if (url == null || !ServerConfig.isValidToken(token) || !ServerConfig.isValidInstallationId(id)) return false; + // Only an imported config file can bring a different id; the field is not editable. + if (!ServerConfig.isValidInstallationId(id)) { + setConnectionStatus(COLOR_ERROR, getString(R.string.server_err_installation_id)); + return false; + } + if (url == null || !ServerConfig.isValidToken(token)) return false; ServerConfig.save(this, url, token, id); if (consumptionCloudClient != null) consumptionCloudClient.invalidateHistory(); showServerConfig(); @@ -513,15 +516,11 @@ public class MainActivity extends AppCompatActivity { private void testConnection() { String url = ServerConfig.normalizeUrl(textOf(serverUrlInput)); String token = textOf(serverTokenInput); - String id = textOf(installationIdInput).toLowerCase(java.util.Locale.US); + String id = ServerConfig.get(this).installationId; if (url == null) { serverUrlLayout.setError(getString(R.string.server_err_url)); return; } - if (!ServerConfig.isValidInstallationId(id)) { - installationIdLayout.setError(getString(R.string.server_err_installation_id)); - return; - } setConnectionStatus(COLOR_PENDING, getString(R.string.conn_testing)); new Thread(() -> { String message; @@ -563,9 +562,7 @@ public class MainActivity extends AppCompatActivity { return; } serverUrlLayout.setError(null); - String typedId = textOf(installationIdInput).toLowerCase(java.util.Locale.US); - String installationId = ServerConfig.isValidInstallationId(typedId) - ? typedId : ServerConfig.get(this).installationId; + String installationId = ServerConfig.get(this).installationId; PhoneQrDialog ui = new PhoneQrDialog(R.string.pair_title, R.string.pair_starting); final boolean[] cancelled = ui.cancelled; @@ -973,7 +970,6 @@ public class MainActivity extends AppCompatActivity { // Show what the file said, so the marked field is the one to fix in the file. if (config.serverUrl != null) serverUrlInput.setText(config.serverUrl); if (config.token != null) serverTokenInput.setText(config.token); - if (config.installationId != null) installationIdInput.setText(config.installationId); return false; } } diff --git a/app/src/main/res/layout/pane_server.xml b/app/src/main/res/layout/pane_server.xml index 850ed83..51b5762 100644 --- a/app/src/main/res/layout/pane_server.xml +++ b/app/src/main/res/layout/pane_server.xml @@ -1,6 +1,6 @@ - + @@ -11,22 +11,16 @@ - - - - - + + + + + + - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6380df6..0bf61cb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,6 +60,7 @@ Save Test connection Import from file + Installation ID %1$s · derived from the head unit; your data is stored under it Car server @@ -67,8 +68,6 @@ For example https://car.k8s.stinnesbeck.com Ingest token The server\'s INGEST_TOKEN, at least 24 characters - Installation ID - Your data is stored under this ID. Keep it when reinstalling. Enter an https:// URL Pair with phone Shows a QR code: scan it with your phone and approve with the approval password. The token below is then filled in for you. @@ -92,7 +91,6 @@ Not a valid ID (UUID) Server settings saved Server not configured — open the Server tab - Put a text file with server_url and token in %1$s (on the head unit or a USB stick in the same folder), then press Import. Config imported and saved — press Test to verify diff --git a/app/src/main/res/values/strings_design.xml b/app/src/main/res/values/strings_design.xml index 9f4d9e0..1c8dc16 100644 --- a/app/src/main/res/values/strings_design.xml +++ b/app/src/main/res/values/strings_design.xml @@ -8,7 +8,7 @@ Your drive at a glance. Data from your car, all in one place. Where your data goes. - Your own server stores it and passes it on to ABRP. + Your own server stores it; the car sends live data to ABRP itself. Live data. Where your car\'s live data goes, and how often. Settings. @@ -19,8 +19,6 @@ VEHICLE INFO TIRE PRESSURES SERVER LINK - Your private connection. - The token lets the car write to your server. It is stored encrypted on this device; your ABRP credentials stay on the server. Values that cannot be read are shown as —. LIVE DATA ABRP, DIRECTLY FROM THE CAR