App 2.18.0: install from a USB stick
Settings -> App -> "Install from USB stick" (car build only). It looks in the top folder of every mounted volume (found from the app's own folder on it, since the head unit has no file picker) for NilsMG4-unstable-<version>.apk, takes the newest one newer than the installed version, checks it against its .sha256 sidecar and the package name, and installs it with the same PackageInstaller session as the over-the-air update. The stable build gets a stub and no button. Tested on the emulator: 2.18.0 installed a 2.18.1 from the storage's top folder without a confirmation, as the system user, so the OTA install step should not need one either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
This commit is contained in:
@@ -265,6 +265,10 @@ public class MainActivity extends AppCompatActivity {
|
||||
.setText(getString(R.string.settings_version, BuildConfig.VERSION_NAME));
|
||||
settingsPane.findViewById(R.id.settings_about_button).setOnClickListener(v -> showAbout());
|
||||
settingsPane.findViewById(R.id.settings_update_button).setOnClickListener(v -> checkForUpdate(v));
|
||||
View usbButton = settingsPane.findViewById(R.id.settings_usb_button);
|
||||
usbButton.setOnClickListener(v -> installFromUsb(v));
|
||||
// The stable build installs nothing itself, so it has no use for the button.
|
||||
if (!UpdateHook.isSupported()) usbButton.setVisibility(View.GONE);
|
||||
|
||||
// Unstable builds check for a newer pre-release; the stable flavor's UpdateHook is
|
||||
// a no-op and does not even contain the updater.
|
||||
@@ -408,13 +412,24 @@ public class MainActivity extends AppCompatActivity {
|
||||
* SHA-256 verified; the final result remains visible until dismissed.
|
||||
*/
|
||||
private void checkForUpdate(View button) {
|
||||
runUpdate(button, R.string.update_checking, listener -> UpdateHook.checkInBackground(this, listener));
|
||||
}
|
||||
|
||||
/** Installs the newest car build from the top folder of a USB stick (unstable builds). */
|
||||
private void installFromUsb(View button) {
|
||||
runUpdate(button, R.string.update_usb_looking, listener -> UpdateHook.installFromUsbInBackground(this, listener));
|
||||
}
|
||||
|
||||
/** The update dialog: progress while [start] runs, then its result. */
|
||||
private void runUpdate(View button, int startText,
|
||||
java.util.function.Consumer<UpdateHook.Listener> start) {
|
||||
button.setEnabled(false);
|
||||
android.widget.LinearLayout panel = new android.widget.LinearLayout(this);
|
||||
panel.setOrientation(android.widget.LinearLayout.VERTICAL);
|
||||
int padding = (int) (24 * getResources().getDisplayMetrics().density);
|
||||
panel.setPadding(padding, padding, padding, padding);
|
||||
TextView status = new TextView(this);
|
||||
status.setText(R.string.update_checking);
|
||||
status.setText(startText);
|
||||
status.setTextAppearance(R.style.Text_EV_Body);
|
||||
android.widget.ProgressBar progress = new android.widget.ProgressBar(this, null,
|
||||
android.R.attr.progressBarStyleHorizontal);
|
||||
@@ -432,7 +447,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
.setCancelable(false)
|
||||
.create();
|
||||
showKeepingFullScreen(dialog);
|
||||
UpdateHook.checkInBackground(this, new UpdateHook.Listener() {
|
||||
start.accept(new UpdateHook.Listener() {
|
||||
@Override public void onProgress(int percent) {
|
||||
if (percent < 0) {
|
||||
progress.setIndeterminate(true);
|
||||
|
||||
Reference in New Issue
Block a user