From 634a374ea785191cc04345f1595e7774452df056 Mon Sep 17 00:00:00 2001 From: TCFDONMEZ Date: Wed, 30 Sep 2026 11:27:14 +0300 Subject: [PATCH] Download one OTA APK and open Downloads --- FatihsMG4-unstable-2.2.20.apk.sha256 | 1 + app/build.gradle | 4 +- .../java/com/evsuite/abrp/OtaUpdater.java | 39 ++++++++++++++----- .../java/com/evsuite/abrp/UpdateHook.java | 23 ++--------- 4 files changed, 36 insertions(+), 31 deletions(-) create mode 100644 FatihsMG4-unstable-2.2.20.apk.sha256 diff --git a/FatihsMG4-unstable-2.2.20.apk.sha256 b/FatihsMG4-unstable-2.2.20.apk.sha256 new file mode 100644 index 0000000..8723121 --- /dev/null +++ b/FatihsMG4-unstable-2.2.20.apk.sha256 @@ -0,0 +1 @@ +3a3a782523a7da5d71b8b50829fce19b48008177c0df4d808aca441b7395d1d3 FatihsMG4-unstable-2.2.20.apk diff --git a/app/build.gradle b/app/build.gradle index 6448170..e920db8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { applicationId "com.evsuite.abrp" minSdk 27 targetSdk 36 - versionCode 36 - versionName "2.2.19" + versionCode 37 + versionName "2.2.20" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/unstable/java/com/evsuite/abrp/OtaUpdater.java b/app/src/unstable/java/com/evsuite/abrp/OtaUpdater.java index 35f47e5..bf3ad5d 100644 --- a/app/src/unstable/java/com/evsuite/abrp/OtaUpdater.java +++ b/app/src/unstable/java/com/evsuite/abrp/OtaUpdater.java @@ -337,7 +337,7 @@ final class OtaUpdater { String safe = (versionName == null || versionName.isEmpty()) ? "unknown" : versionName.toLowerCase(Locale.US).replaceAll("[^a-z0-9._-]", "_"); - return "EVABRPUploader-unstable-" + safe + ".apk"; + return safe + ".apk"; } /** @@ -381,25 +381,20 @@ final class OtaUpdater { Thread.sleep(250L); } - File staged = new File(context.getCacheDir(), CACHE_PREFIX - + java.util.UUID.randomUUID() + ".apk"); MessageDigest digest = MessageDigest.getInstance("SHA-256"); try (ParcelFileDescriptor descriptor = manager.openDownloadedFile(downloadId); - java.io.InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(descriptor); - FileOutputStream output = new FileOutputStream(staged)) { + java.io.InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(descriptor)) { byte[] buffer = new byte[64 * 1024]; int count; while ((count = input.read(buffer)) != -1) { - output.write(buffer, 0, count); digest.update(buffer, 0, count); } - output.getFD().sync(); } if (!hex(digest.digest()).equalsIgnoreCase(expectedSha256)) { - staged.delete(); + if (!publicFile.delete()) Log.w(TAG, "Could not remove invalid OTA file"); return null; } - return staged; + return publicFile; } catch (Exception e) { Log.w(TAG, "Update download failed", e); } @@ -412,6 +407,32 @@ final class OtaUpdater { return out.toString(); } + /** Opens Android's document UI directly in Downloads; the driver chooses the APK. */ + static boolean openDownloads(Context context) { + Intent picker = new Intent(Intent.ACTION_OPEN_DOCUMENT) + .addCategory(Intent.CATEGORY_OPENABLE) + .setType("application/vnd.android.package-archive") + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + if (Build.VERSION.SDK_INT >= 26) { + picker.putExtra("android.provider.extra.INITIAL_URI", Uri.parse( + "content://com.android.externalstorage.documents/document/primary%3ADownload")); + } + try { + context.startActivity(picker); + return true; + } catch (Throwable first) { + try { + Intent downloads = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(downloads); + return true; + } catch (Throwable second) { + Log.w(TAG, "No Downloads UI available", second); + return false; + } + } + } + /** * What {@link #install} did. The PackageInstaller is the authority for signing-certificate * compatibility, matching the proven DriveHub_Dort flow on this head unit. diff --git a/app/src/unstable/java/com/evsuite/abrp/UpdateHook.java b/app/src/unstable/java/com/evsuite/abrp/UpdateHook.java index fc8e595..8629c21 100644 --- a/app/src/unstable/java/com/evsuite/abrp/UpdateHook.java +++ b/app/src/unstable/java/com/evsuite/abrp/UpdateHook.java @@ -117,25 +117,8 @@ final class UpdateHook { if (apk == null) return "İndirme veya SHA-256 doğrulaması başarısız (" + update.versionName + ")"; - OtaUpdater.InstallResult result = OtaUpdater.install(app, apk); - // FileProvider's interactive installer opens asynchronously and still needs this file. - // Other outcomes have either streamed the bytes already or rejected the archive. - if (result != OtaUpdater.InstallResult.INSTALL_UI_STARTED && !apk.delete()) { - Log.w(TAG, "Could not remove cached OTA APK"); - } - - switch (result) { - case SESSION_STARTED: - // Deliberately not "Güncellendi": committing a session is not installing. The - // platform may still want the driver to confirm, and either way the verdict - // arrives at OtaInstallResultReceiver, not here. - return "Kuruluyor: " + update.versionName + " — ekrandaki onayı bekleyin"; - case INSTALL_UI_STARTED: - return "Kurulum ekranı açıldı: " + update.versionName; - case UNREADABLE_ARCHIVE: - return "Kurulum reddedildi: APK okunamadı"; - default: - return "Kurulum başlatılamadı (" + update.versionName + ") — Log sayfasına bakın"; - } + if (!OtaUpdater.openDownloads(app)) + return "APK Downloads'a indirildi; dosya yöneticisi açılamadı"; + return update.versionName + ".apk Downloads'a indirildi — dosyaya dokunup kurun"; } }