App 2.19.5: the installer screen fallback reads the APK

The car refuses the silent session for a non-system app; the fallback
installer screen could not read our FileProvider URI because grants
from the system user are refused. The car build now hands it a file
URI to the verified copy in Downloads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
This commit is contained in:
2026-10-23 21:48:46 +02:00
co-authored by Claude Opus 5.5
parent 66b403acb8
commit b6f41079cc
4 changed files with 43 additions and 5 deletions
+2 -2
View File
@@ -34,8 +34,8 @@ android {
applicationId "com.stinnesbeck.nilsmg4"
minSdk 27
targetSdk 36
versionCode 103
versionName "2.19.4"
versionCode 104
versionName "2.19.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.
@@ -566,6 +566,28 @@ final class OtaUpdater {
}
File publicApk = copyToPublicDownloads(apk);
if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
// As the system user, our FileProvider's read grant is refused ("not exported from
// UID 1000") and the installer reports the unreadable file as a parse error. A file
// URI it reads with its own storage permission instead, as from the Files app.
Intent install = new Intent(Intent.ACTION_VIEW)
.setDataAndType(Uri.fromFile(publicApk), "application/vnd.android.package-archive")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (install.resolveActivity(context.getPackageManager()) == null) {
throw new IllegalStateException("No package installer activity");
}
// StrictMode forbids file URIs in intents (FileUriExposedException): lifted for this
// one call only.
android.os.StrictMode.VmPolicy policy = android.os.StrictMode.getVmPolicy();
android.os.StrictMode.setVmPolicy(new android.os.StrictMode.VmPolicy.Builder().build());
try {
context.startActivity(install);
} finally {
android.os.StrictMode.setVmPolicy(policy);
}
Log.i(TAG, "System install UI opened with a file URI for " + publicApk.getAbsolutePath());
return;
}
Uri contentUri = FileProvider.getUriForFile(context,
context.getPackageName() + ".fileprovider", publicApk);
Intent install = new Intent(Intent.ACTION_VIEW)