From f76aa51b5467df597d67bd7efaf691cfe761db6b Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sat, 23 Mar 2024 19:26:39 -0400 Subject: [PATCH 1/6] Delete downloaded APK on install fail (#1495) --- lib/providers/apps_provider.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index e152163b..7f4efedc 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -297,8 +297,6 @@ Future downloadFile( tempDownloadedFile.deleteSync(recursive: true); throw response.reasonPhrase ?? tr('unexpectedError'); } - print(tempDownloadedFile.lengthSync()); - print(fullContentLength); if (tempDownloadedFile.existsSync()) { tempDownloadedFile.renameSync(downloadedFile.path); } @@ -648,7 +646,13 @@ class AppsProvider with ChangeNotifier { } bool installed = false; if (code != null && code != 0 && code != 3) { - throw InstallError(code); + try { + file.file.deleteSync(recursive: true); + } catch (e) { + // + } finally { + throw InstallError(code); + } } else if (code == 0) { installed = true; apps[file.appId]!.app.installedVersion = From d76b7375cb65a990757750dc3910bbd5443bd2e6 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 28 Mar 2024 22:28:55 -0400 Subject: [PATCH 2/6] Added 'Share new Apps with AppVerifier' (#255) --- assets/translations/bs.json | 2 + assets/translations/cs.json | 4 +- assets/translations/de.json | 2 + assets/translations/en.json | 2 + assets/translations/es.json | 2 + assets/translations/fa.json | 2 + assets/translations/fr.json | 2 + assets/translations/hu.json | 4 +- assets/translations/it.json | 4 +- assets/translations/ja.json | 2 + assets/translations/nl.json | 4 +- assets/translations/pl.json | 2 + assets/translations/pt.json | 2 + assets/translations/ru.json | 2 + assets/translations/sv.json | 4 +- assets/translations/tr.json | 2 + assets/translations/uk.json | 3 +- assets/translations/vi.json | 2 + assets/translations/zh.json | 2 + lib/pages/settings.dart | 69 +++++++++++++++++++++------- lib/providers/apps_provider.dart | 35 +++++++++++--- lib/providers/settings_provider.dart | 9 ++++ 22 files changed, 133 insertions(+), 29 deletions(-) diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 294654e9..a3e935ab 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -299,6 +299,8 @@ "note": "Note", "selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.", "badDownload": "The APK could not be parsed (incompatible or partial download)", + "beforeNewInstallsShareToAppVerifier": "Share new Apps with AppVerifier (if available)", + "appVerifierInstructionToast": "Share to AppVerifier, then return here when ready.", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/cs.json b/assets/translations/cs.json index f403304d..33fa3727 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -218,7 +218,7 @@ "dontShowTrackOnlyWarnings": "Nezobrazovat varování pro 'Jen sledované'", "dontShowAPKOriginWarnings": "Nezobrazovat varování pro původ APK", "moveNonInstalledAppsToBottom": "Přesunout nenainstalované aplikace na konec zobrazení Aplikace", - "gitlabPATLabel": "GitLab Personal Access Token", + "gitlabPATLabel": "Osobní přístupový token GitLab", "about": "O", "requiresCredentialsInSettings": "{}: Vyžaduje další pověření (v nastavení)", "checkOnStart": "Zkontrolovat jednou při spuštění", @@ -299,6 +299,8 @@ "note": "Poznámka", "selfHostedNote": "Rozbalovací seznam \"{}\" lze použít k dosažení vlastních/obvyklých instancí libovolného zdroje.", "badDownload": "APK nelze analyzovat (nekompatibilní nebo částečné stažení)", + "beforeNewInstallsShareToAppVerifier": "Sdílení nových aplikací s aplikací AppVerifier (pokud je k dispozici)", + "appVerifierInstructionToast": "Sdílejte do aplikace AppVerifier a po dokončení se sem vraťte.", "removeAppQuestion": { "one": "Odstranit Apku?", "other": "Odstranit Apky?" diff --git a/assets/translations/de.json b/assets/translations/de.json index 40d2315a..4d711bf7 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -299,6 +299,8 @@ "note": "Hinweis", "selfHostedNote": "Das „{}“-Dropdown-Menü kann verwendet werden, um selbst gehostete/angepasste Instanzen einer beliebigen Quelle zu erreichen.", "badDownload": "Die APK konnte nicht geparst werden (inkompatibler oder teilweiser Download)", + "beforeNewInstallsShareToAppVerifier": "Neue Apps mit AppVerifier teilen (falls verfügbar)", + "appVerifierInstructionToast": "Geben Sie die Daten an AppVerifier weiter und kehren Sie dann hierher zurück, wenn Sie fertig sind.", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index f6220bb3..23b389e4 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -299,6 +299,8 @@ "note": "Note", "selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.", "badDownload": "The APK could not be parsed (incompatible or partial download)", + "beforeNewInstallsShareToAppVerifier": "Share new Apps with AppVerifier (if available)", + "appVerifierInstructionToast": "Share to AppVerifier, then return here when ready.", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index 0f512e82..69b085cb 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -299,6 +299,8 @@ "note": "Nota", "selfHostedNote": "El desplegable \"{}\" puede utilizarse para acceder a instancias autoalojadas/personalizadas de cualquier fuente.", "badDownload": "No se ha podido analizar el APK (incompatible o descarga parcial)", + "beforeNewInstallsShareToAppVerifier": "Compartir nuevas aplicaciones con AppVerifier (si está disponible)", + "appVerifierInstructionToast": "Comparta con AppVerifier y vuelva aquí cuando esté listo.", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 7929634f..10731d6a 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -299,6 +299,8 @@ "note": "Note", "selfHostedNote": "The \"{}\" dropdown can be used to reach self-hosted/custom instances of any source.", "badDownload": "The APK could not be parsed (incompatible or partial download)", + "beforeNewInstallsShareToAppVerifier": "Share new Apps with AppVerifier (if available)", + "appVerifierInstructionToast": "Share to AppVerifier, then return here when ready.", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index f61527e0..61be34ef 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -299,6 +299,8 @@ "note": "Note", "selfHostedNote": "La liste déroulante \"{}\" peut être utilisée pour accéder aux instances auto-hébergées/personnalisées de n'importe quelle source.", "badDownload": "L'APK n'a pas pu être analysé (téléchargement incompatible ou partiel)", + "beforeNewInstallsShareToAppVerifier": "Partager les nouvelles applications avec AppVerifier (si disponible)", + "appVerifierInstructionToast": "Partagez avec AppVerifier, puis revenez ici lorsque vous êtes prêt.", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index 277f6a68..5e9c669c 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -218,7 +218,7 @@ "dontShowTrackOnlyWarnings": "Ne jelenítsen meg 'Csak nyomon követés' figyelmeztetést", "dontShowAPKOriginWarnings": "Ne jelenítsen meg az APK eredetére vonatkozó figyelmeztetéseket", "moveNonInstalledAppsToBottom": "Helyezze át a nem telepített appokat az App nézet aljára", - "gitlabPATLabel": "GitLab Personal Access Token", + "gitlabPATLabel": "GitLab személyes hozzáférési token", "about": "Rólunk", "requiresCredentialsInSettings": "{}: Ehhez további hitelesítő adatokra van szükség (a Beállításokban)", "checkOnStart": "Egyszer az alkalmazás indításakor is", @@ -299,6 +299,8 @@ "note": "Megjegyzés:", "selfHostedNote": "A \"{}\" legördülő menü használható bármely forrás saját üzemeltetésű/egyéni példányainak eléréséhez.", "badDownload": "Az APK-t nem lehetett elemezni (inkompatibilis vagy részleges letöltés)", + "beforeNewInstallsShareToAppVerifier": "Új alkalmazások megosztása az AppVerifierrel (ha elérhető)", + "appVerifierInstructionToast": "Ossza meg az AppVerifierrel, majd térjen vissza ide, ha kész.", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazásokat?" diff --git a/assets/translations/it.json b/assets/translations/it.json index 2e4b0d11..e6aa2a41 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -218,7 +218,7 @@ "dontShowTrackOnlyWarnings": "Non mostrare gli avvisi 'Solo-Monitoraggio'", "dontShowAPKOriginWarnings": "Non mostrare gli avvisi di origine dell'APK", "moveNonInstalledAppsToBottom": "Sposta le app non installate in fondo alla lista", - "gitlabPATLabel": "GitLab Personal Access Token", + "gitlabPATLabel": "GitLab Token di accesso personale", "about": "Informazioni", "requiresCredentialsInSettings": "{}: Servono credenziali aggiuntive (in Impostazioni)", "checkOnStart": "Controlla una volta all'avvio", @@ -299,6 +299,8 @@ "note": "Nota", "selfHostedNote": "Il menu a tendina \"{}\" può essere usato per raggiungere istanze autogestite/personali di qualsiasi fonte.", "badDownload": "Non è stato possibile analizzare l'APK (download incompatibile o parziale).", + "beforeNewInstallsShareToAppVerifier": "Condividere le nuove applicazioni con AppVerifier (se disponibile)", + "appVerifierInstructionToast": "Condividete con AppVerifier, quindi tornate qui quando siete pronti.", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index af5db0c5..171167e9 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -299,6 +299,8 @@ "note": "注", "selfHostedNote": "ドロップダウン\"{}\"を使用すると、あらゆるソースのセルフホスト/カスタムインスタンスにアクセスできます。", "badDownload": "APK を解析できませんでした(互換性がないか、部分的にダウンロードされています)。", + "beforeNewInstallsShareToAppVerifier": "AppVerifierで新しいアプリを共有する(利用可能な場合)", + "appVerifierInstructionToast": "AppVerifierに共有し、準備ができたらここに戻ってください。", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/nl.json b/assets/translations/nl.json index f946b5a0..845676d3 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -218,7 +218,7 @@ "dontShowTrackOnlyWarnings": "Geen waarschuwingen voor 'Track-Only' weergeven", "dontShowAPKOriginWarnings": "APK-herkomstwaarschuwingen niet weergeven", "moveNonInstalledAppsToBottom": "Verplaats niet-geïnstalleerde apps naar de onderkant van de apps-weergave", - "gitlabPATLabel": "GitLab Personal Access Token", + "gitlabPATLabel": "GitLab persoonlijk toegangskenmerk", "about": "Over", "requiresCredentialsInSettings": "{}: Dit vereist aanvullende referenties (in Instellingen)", "checkOnStart": "Controleren op updates bij opstarten", @@ -299,6 +299,8 @@ "note": "Opmerking", "selfHostedNote": "De \"{}\" dropdown kan gebruikt worden om zelf gehoste/aangepaste instanties van elke bron te bereiken.", "badDownload": "De APK kon niet worden verwerkt (incompatibele of gedeeltelijke download)", + "beforeNewInstallsShareToAppVerifier": "Nieuwe Apps delen met AppVerifier (indien beschikbaar)", + "appVerifierInstructionToast": "Deel naar AppVerifier en keer hier terug als je klaar bent.", "removeAppQuestion": { "one": "App verwijderen?", "other": "Apps verwijderen?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index f24aceb4..c017f930 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -299,6 +299,8 @@ "note": "Uwaga", "selfHostedNote": "Lista rozwijana \"{}\" może być używana do uzyskiwania dostępu do samodzielnie hostowanych / niestandardowych instancji dowolnego źródła.", "badDownload": "Nie można przeanalizować pliku APK (niekompatybilny lub częściowo pobrany).", + "beforeNewInstallsShareToAppVerifier": "Udostępnianie nowych aplikacji za pomocą AppVerifier (jeśli dostępne)", + "appVerifierInstructionToast": "Udostępnij w AppVerifier, a następnie wróć tutaj, gdy będziesz gotowy.", "removeAppQuestion": { "one": "Usunąć aplikację?", "few": "Usunąć aplikacje?", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index 2473c73a..c2281d94 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -299,6 +299,8 @@ "note": "Nota", "selfHostedNote": "O menu suspenso \"{}\" pode ser usado para acessar instâncias auto-hospedadas/personalizadas de qualquer fonte.", "badDownload": "Não foi possível analisar o APK (transferência incompatível ou parcial)", + "beforeNewInstallsShareToAppVerifier": "Partilhar novas aplicações com o AppVerifier (se disponível)", + "appVerifierInstructionToast": "Partilhe com o AppVerifier e, em seguida, regresse aqui quando estiver pronto.", "removeAppQuestion": { "one": "Remover aplicativo?", "other": "Remover aplicativos?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 52a42fb7..c5233d5f 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -299,6 +299,8 @@ "note": "Примечание", "selfHostedNote": "Выпадающий список \"{}\" можно использовать для доступа к самостоятельно размещенным/настроенным экземплярам любого источника.", "badDownload": "APK не удалось разобрать (несовместимая или неполная загрузка)", + "beforeNewInstallsShareToAppVerifier": "Поделитесь новыми приложениями с AppVerifier (если доступно)", + "appVerifierInstructionToast": "Поделитесь с AppVerifier, а затем вернитесь сюда, когда будете готовы.", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/sv.json b/assets/translations/sv.json index 44baa29e..57135363 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -218,7 +218,7 @@ "dontShowTrackOnlyWarnings": "Visa inte 'Följ-Endast' varningar", "dontShowAPKOriginWarnings": "Visa inte APK-ursprung varningar", "moveNonInstalledAppsToBottom": "Flytta icke-installerade appar till botten av appvyn", - "gitlabPATLabel": "GitLab Personal Access Token", + "gitlabPATLabel": "Personligt åtkomsttoken för GitLab", "about": "Om", "requiresCredentialsInSettings": "{}: This needs additional credentials (in Settings)", "checkOnStart": "Kolla efter uppdateringar vid start", @@ -299,6 +299,8 @@ "note": "Anmärkning", "selfHostedNote": "Rullgardinsmenyn \"{}\" kan användas för att nå självhostade/anpassade instanser av valfri källa.", "badDownload": "APK kunde inte analyseras (inkompatibel eller partiell nedladdning)", + "beforeNewInstallsShareToAppVerifier": "Dela nya appar med AppVerifier (om tillgängligt)", + "appVerifierInstructionToast": "Dela till AppVerifier och återvänd sedan hit när du är klar.", "removeAppQuestion": { "one": "Ta Bort App?", "other": "Ta Bort Appar?" diff --git a/assets/translations/tr.json b/assets/translations/tr.json index 240a0c12..176663a9 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -299,6 +299,8 @@ "note": "Not", "selfHostedNote": "\"{}\" açılır menüsü, herhangi bir kaynağın kendi kendine barındırılan/özel örneklerine ulaşmak için kullanılabilir.", "badDownload": "APK ayrıştırılamadı (uyumsuz veya kısmi indirme)", + "beforeNewInstallsShareToAppVerifier": "Yeni Uygulamaları AppVerifier ile paylaşın (varsa)", + "appVerifierInstructionToast": "AppVerifier ile paylaşın, hazır olduğunuzda buraya dönün.", "removeAppQuestion": { "one": "Uygulamayı Kaldır?", "other": "Uygulamaları Kaldır?" diff --git a/assets/translations/uk.json b/assets/translations/uk.json index c9710346..327d5fac 100644 --- a/assets/translations/uk.json +++ b/assets/translations/uk.json @@ -232,7 +232,6 @@ "addInfoBelow": "Додати цю інформацію нижче.", "addInfoInSettings": "Додати цю інформацію у налаштуваннях.", "githubSourceNote": "Лімітування швидкості GitHub можна уникнути, використовуючи ключ API.", - "gitlabSourceNote": "Вилучення APK з GitLab може не працювати без ключа API.", "sortByLastLinkSegment": "Сортувати лише за останнім сегментом посилання", "filterReleaseNotesByRegEx": "Фільтрувати примітки до релізу за регулярним виразом", "customLinkFilterRegex": "Фільтр кастомного посилання на APK за регулярним виразом (за замовчуванням '.apk$')", @@ -300,6 +299,8 @@ "note": "Примітка", "selfHostedNote": "Випадаючий список \"{}\" може використовуватися для доступу до власних/призначених для самостійного використання екземплярів будь-якого джерела.", "badDownload": "APK не вдалося розпарсити (несумісний або часткове завантаження)", + "beforeNewInstallsShareToAppVerifier": "Діліться новими додатками з AppVerifier (якщо доступно)", + "appVerifierInstructionToast": "Надішліть на AppVerifier, а потім поверніться сюди, коли будете готові.", "removeAppQuestion": { "one": "Видалити застосунок?", "other": "Видалити застосунки?" diff --git a/assets/translations/vi.json b/assets/translations/vi.json index 51b1f4f2..951f2093 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -299,6 +299,8 @@ "note": "Ghi chú", "selfHostedNote": "Trình đơn thả xuống \"{}\" có thể được dùng để tiếp cận các phiên bản tự lưu trữ/tùy chỉnh của bất kỳ nguồn nào.", "badDownload": "Không thể phân tích cú pháp APK (tải xuống một phần hoặc không tương thích)", + "beforeNewInstallsShareToAppVerifier": "Share new Apps with AppVerifier (if available)", + "appVerifierInstructionToast": "Share to AppVerifier, then return here when ready.", "removeAppQuestion": { "one": "Gỡ ứng dụng?", "other": "Gỡ ứng dụng?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 8e7e8adb..ed1482cb 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -299,6 +299,8 @@ "note": "备注", "selfHostedNote": "可以通过“{}”下拉菜单来指向任意来源的自托管/自定义实例。", "badDownload": "无法解析 APK 文件(不兼容或文件不完整)", + "beforeNewInstallsShareToAppVerifier": "与 AppVerifier 共享新应用程序(如有)", + "appVerifierInstructionToast": "分享到 AppVerifier,准备就绪后返回此处。", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index 5cc56a2f..bdf51e14 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -351,6 +351,22 @@ class _SettingsPageState extends State { ], ), height16, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: + Text(tr('removeOnExternalUninstall'))), + Switch( + value: settingsProvider + .removeOnExternalUninstall, + onChanged: (value) { + settingsProvider + .removeOnExternalUninstall = value; + }) + ], + ), + height16, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -363,6 +379,43 @@ class _SettingsPageState extends State { }) ], ), + height16, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text(tr( + 'beforeNewInstallsShareToAppVerifier')), + GestureDetector( + onTap: () { + launchUrlString( + 'https://github.com/soupslurpr/AppVerifier', + mode: LaunchMode + .externalApplication); + }, + child: Text( + tr('about'), + style: const TextStyle( + decoration: + TextDecoration.underline, + fontSize: 12), + )), + ], + )), + Switch( + value: settingsProvider + .beforeNewInstallsShareToAppVerifier, + onChanged: (value) { + settingsProvider + .beforeNewInstallsShareToAppVerifier = + value; + }) + ], + ), installMethodDropdown, height32, Text( @@ -474,22 +527,6 @@ class _SettingsPageState extends State { ], ), height16, - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: - Text(tr('removeOnExternalUninstall'))), - Switch( - value: settingsProvider - .removeOnExternalUninstall, - onChanged: (value) { - settingsProvider - .removeOnExternalUninstall = value; - }) - ], - ), - height16, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 7f4efedc..be8ceb52 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:math'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:http/http.dart' as http; import 'package:crypto/crypto.dart'; @@ -31,6 +32,7 @@ import 'package:obtainium/providers/source_provider.dart'; import 'package:http/http.dart'; import 'package:android_intent_plus/android_intent.dart'; import 'package:flutter_archive/flutter_archive.dart'; +import 'package:share_plus/share_plus.dart'; import 'package:shared_storage/shared_storage.dart' as saf; import 'native_provider.dart'; @@ -561,7 +563,8 @@ class AppsProvider with ChangeNotifier { zipFile: File(filePath), destinationDir: Directory(destinationPath)); } - Future installXApkDir(DownloadedXApkDir dir, + Future installXApkDir( + DownloadedXApkDir dir, BuildContext? firstTimeWithContext, {bool needsBGWorkaround = false}) async { // We don't know which APKs in an XAPK are supported by the user's device // So we try installing all of them and assume success if at least one installed @@ -575,7 +578,8 @@ class AppsProvider with ChangeNotifier { if (file.path.toLowerCase().endsWith('.apk')) { try { somethingInstalled = somethingInstalled || - await installApk(DownloadedApk(dir.appId, file), + await installApk( + DownloadedApk(dir.appId, file), firstTimeWithContext, needsBGWorkaround: needsBGWorkaround); } catch (e) { logs.add( @@ -597,8 +601,19 @@ class AppsProvider with ChangeNotifier { return somethingInstalled; } - Future installApk(DownloadedApk file, + Future installApk( + DownloadedApk file, BuildContext? firstTimeWithContext, {bool needsBGWorkaround = false}) async { + if (firstTimeWithContext != null && + settingsProvider.beforeNewInstallsShareToAppVerifier && + (await getInstalledInfo('dev.soupslurpr.appverifier')) != null) { + XFile f = XFile.fromData(file.file.readAsBytesSync(), + mimeType: 'application/vnd.android.package-archive'); + Fluttertoast.showToast( + msg: tr('appVerifierInstructionToast'), + toastLength: Toast.LENGTH_LONG); + await Share.shareXFiles([f]); + } var newInfo = await pm.getPackageArchiveInfo(archiveFilePath: file.file.path); if (newInfo == null) { @@ -834,17 +849,23 @@ class AppsProvider with ChangeNotifier { try { if (!skipInstalls) { bool sayInstalled = true; + var contextIfNewInstall = + apps[id]?.installedInfo == null ? context : null; if (downloadedFile != null) { if (willBeSilent && context == null) { - installApk(downloadedFile, needsBGWorkaround: true); + installApk(downloadedFile, contextIfNewInstall, + needsBGWorkaround: true); } else { - sayInstalled = await installApk(downloadedFile); + sayInstalled = + await installApk(downloadedFile, contextIfNewInstall); } } else { if (willBeSilent && context == null) { - installXApkDir(downloadedDir!, needsBGWorkaround: true); + installXApkDir(downloadedDir!, contextIfNewInstall, + needsBGWorkaround: true); } else { - sayInstalled = await installXApkDir(downloadedDir!); + sayInstalled = + await installXApkDir(downloadedDir!, contextIfNewInstall); } } if (willBeSilent && context == null) { diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 1b0edccd..b9b910aa 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -479,4 +479,13 @@ class SettingsProvider with ChangeNotifier { prefs?.setStringList('searchDeselected', list); notifyListeners(); } + + bool get beforeNewInstallsShareToAppVerifier { + return prefs?.getBool('beforeNewInstallsShareToAppVerifier') ?? true; + } + + set beforeNewInstallsShareToAppVerifier(bool val) { + prefs?.setBool('beforeNewInstallsShareToAppVerifier', val); + notifyListeners(); + } } From 6468d0edcc35a91dce9e67c859aad169f1bc4efc Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 28 Mar 2024 23:05:16 -0400 Subject: [PATCH 3/6] Fix GitLab's broken track-only mode (#1496) --- lib/app_sources/gitlab.dart | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/app_sources/gitlab.dart b/lib/app_sources/gitlab.dart index 42a00a05..53e0689f 100644 --- a/lib/app_sources/gitlab.dart +++ b/lib/app_sources/gitlab.dart @@ -121,9 +121,11 @@ class GitLab extends AppSource { String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {}); String optionalAuth = (PAT != null) ? 'private_token=$PAT' : ''; + bool trackOnly = additionalSettings['trackOnly'] == true; + // Request data from REST API Response res = await sourceRequest( - 'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}/releases?$optionalAuth', + 'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}/${trackOnly ? 'repository/tags' : 'releases'}?$optionalAuth', additionalSettings); if (res.statusCode != 200) { throw getObtainiumHttpError(res); @@ -152,9 +154,8 @@ class GitLab extends AppSource { var apkUrlsSet = apkUrlsFromAssets.toSet(); apkUrlsSet.addAll(uploadedAPKsFromDescription); var releaseDateString = e['released_at'] ?? e['created_at']; - DateTime? releaseDate = releaseDateString != null - ? DateTime.parse(releaseDateString) - : null; + DateTime? releaseDate = + releaseDateString != null ? DateTime.parse(releaseDateString) : null; return APKDetails( e['tag_name'] ?? e['name'], getApkUrlsFromUrls(apkUrlsSet.toList()), @@ -164,18 +165,19 @@ class GitLab extends AppSource { if (apkDetailsList.isEmpty) { throw NoReleasesError(); } + var finalResult = apkDetailsList.first; // Fallback procedure bool fallbackToOlderReleases = additionalSettings['fallbackToOlderReleases'] == true; - if (fallbackToOlderReleases) { - if (additionalSettings['trackOnly'] != true) { - apkDetailsList = - apkDetailsList.where((e) => e.apkUrls.isNotEmpty).toList(); - } - if (apkDetailsList.isEmpty) { - throw NoReleasesError(); - } + if (finalResult.apkUrls.isEmpty && fallbackToOlderReleases && !trackOnly) { + apkDetailsList = + apkDetailsList.where((e) => e.apkUrls.isNotEmpty).toList(); + finalResult = apkDetailsList.first; + } + + if (finalResult.apkUrls.isEmpty && !trackOnly) { + throw NoAPKError(); } return apkDetailsList.first; From a8838572300b8a83ffc5a4f1844bbd30a42ecf13 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 28 Mar 2024 23:13:45 -0400 Subject: [PATCH 4/6] Auto-delete download if likely invalid (#1498) --- lib/providers/apps_provider.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index be8ceb52..1c24a27f 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -291,11 +291,14 @@ Future downloadFile( return s; }).pipe(sink); await sink.close(); + bool likelyCorruptFile = (progress ?? 0) > 101; progress = null; if (onProgress != null) { onProgress(progress); } - if (response.statusCode < 200 || response.statusCode > 299) { + if (response.statusCode < 200 || + response.statusCode > 299 || + likelyCorruptFile) { tempDownloadedFile.deleteSync(recursive: true); throw response.reasonPhrase ?? tr('unexpectedError'); } From 491c42d68b2d342d1ec1eb2691af0db1c620fd1c Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 28 Mar 2024 23:27:22 -0400 Subject: [PATCH 5/6] Removed SourceForge (#1487) --- README.md | 1 - lib/providers/source_provider.dart | 1 - 2 files changed, 2 deletions(-) diff --git a/README.md b/README.md index 3acfdf29..9d8e3218 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ Currently supported App sources: - [F-Droid](https://f-droid.org/) - Third Party F-Droid Repos - [IzzyOnDroid](https://android.izzysoft.de/) - - [SourceForge](https://sourceforge.net/) - [SourceHut](https://git.sr.ht/) - Other - General: - [APKPure](https://apkpure.net/) diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index d2c34bff..7761f61e 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -736,7 +736,6 @@ class SourceProvider { FDroid(), FDroidRepo(), IzzyOnDroid(), - SourceForge(), SourceHut(), APKPure(), Aptoide(), From f2c15c5c8ee67ff01222227075dce7f1861614e2 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Thu, 28 Mar 2024 23:40:36 -0400 Subject: [PATCH 6/6] Update packages and Flutter, increment version --- .flutter | 2 +- pubspec.lock | 60 ++++++++++++++++++++++++++-------------------------- pubspec.yaml | 12 +++++------ 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/.flutter b/.flutter index ba393198..300451ad 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit ba393198430278b6595976de84fe170f553cc728 +Subproject commit 300451adae589accbece3490f4396f10bdf15e6e diff --git a/pubspec.lock b/pubspec.lock index a3b488c3..28bb66db 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: "direct main" description: name: android_intent_plus - sha256: e1c62bb41c90e15083b7fb84dc327fe90396cc9c1445b55ff1082144fabfb4d9 + sha256: e92d14009f3f6ebafca6a601958aaebb793559fb03a1961fe3c5596db95af2cb url: "https://pub.dev" source: hosted - version: "4.0.3" + version: "5.0.1" android_package_installer: dependency: "direct main" description: @@ -38,10 +38,10 @@ packages: dependency: "direct main" description: name: app_links - sha256: fd7fc1569870b4b0d90d17a9f36661a6ff92400fecb6e4adab4abe0f0488bb5f + sha256: "42dc15aecf2618ace4ffb74a2e58a50e45cd1b9f2c17c8f0cafe4c297f08c815" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.1" archive: dependency: transitive description: @@ -70,10 +70,10 @@ packages: dependency: "direct main" description: name: background_fetch - sha256: eb3af263d390d7e68ecb90f2ae984d2bfd96dceb4c7b4f72418dd5383b49de0a + sha256: dbffec0317ccdef6e2014cb543e147f52441e29c4fcb53dfd23558c4d92ddece url: "https://pub.dev" source: hosted - version: "1.2.4" + version: "1.3.2" boolean_selector: dependency: transitive description: @@ -126,18 +126,18 @@ packages: dependency: "direct main" description: name: connectivity_plus - sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0" + sha256: e9feae83b1849f61bad9f6f33ee00646e3410d54ce0821e02f262f9901dad3c9 url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "6.0.1" connectivity_plus_platform_interface: dependency: transitive description: name: connectivity_plus_platform_interface - sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a + sha256: b6a56efe1e6675be240de39107281d4034b64ac23438026355b4234042a35adb url: "https://pub.dev" source: hosted - version: "1.2.4" + version: "2.0.0" convert: dependency: transitive description: @@ -190,10 +190,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" + sha256: "50fb435ed30c6d2525cbfaaa0f46851ea6131315f213c0d921b0e407b34e3b84" url: "https://pub.dev" source: hosted - version: "9.1.2" + version: "10.0.1" device_info_plus_platform_interface: dependency: transitive description: @@ -254,10 +254,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: caa6bc229eab3e32eb2f37b53a5f9d22a6981474afd210c512a7546c1e1a04f6 + sha256: d1d0ac3966b36dc3e66eeefb40280c17feb87fa2099c6e22e6a1fc959327bd03 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "8.0.0+1" fixnum: dependency: transitive description: @@ -299,10 +299,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" flutter_local_notifications: dependency: "direct main" description: @@ -336,10 +336,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: cb44f7831b23a6bdd0f501718b0d2e8045cbc625a15f668af37ddb80314821db + sha256: "87e11b9df25a42e2db315b8b7a51fae8e66f57a4b2f50ec4b822d0fa155e6b52" url: "https://pub.dev" source: hosted - version: "0.6.21" + version: "0.6.22" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -426,10 +426,10 @@ packages: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.1" json_annotation: dependency: transitive description: @@ -586,10 +586,10 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "74e962b7fad7ff75959161bb2c0ad8fe7f2568ee82621c9c2660b751146bfe44" + sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" url: "https://pub.dev" source: hosted - version: "11.3.0" + version: "11.3.1" permission_handler_android: dependency: transitive description: @@ -602,10 +602,10 @@ packages: dependency: transitive description: name: permission_handler_apple - sha256: bdafc6db74253abb63907f4e357302e6bb786ab41465e8635f362ee71fd8707b + sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662 url: "https://pub.dev" source: hosted - version: "9.4.0" + version: "9.4.4" permission_handler_html: dependency: transitive description: @@ -618,10 +618,10 @@ packages: dependency: transitive description: name: permission_handler_platform_interface - sha256: "23dfba8447c076ab5be3dee9ceb66aad345c4a648f0cac292c77b1eb0e800b78" + sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "4.2.1" permission_handler_windows: dependency: transitive description: @@ -674,18 +674,18 @@ packages: dependency: "direct main" description: name: share_plus - sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" + sha256: "05ec043470319bfbabe0adbc90d3a84cbff0426b9d9f3a6e2ad3e131fa5fa629" url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "8.0.2" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: df08bc3a07d01f5ea47b45d03ffcba1fa9cd5370fb44b3f38c70e42cced0f956 + sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496" url: "https://pub.dev" source: hosted - version: "3.3.1" + version: "3.4.0" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 0d987f6f..3d8195a4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.6+2256 # When changing this, update the tag in main() accordingly +version: 1.1.0+2257 environment: sdk: '>=3.0.0 <4.0.0' @@ -48,22 +48,22 @@ dependencies: url_launcher: ^6.1.5 permission_handler: ^11.0.0 fluttertoast: ^8.0.9 - device_info_plus: ^9.0.0 - file_picker: ^6.0.0 + device_info_plus: ^10.0.1 + file_picker: ^8.0.0+1 animations: ^2.0.4 android_package_installer: git: url: https://github.com/ImranR98/android_package_installer ref: main android_package_manager: ^0.7.0 - share_plus: ^7.0.0 + share_plus: ^8.0.2 sqflite: ^2.2.0+3 easy_localization: ^3.0.1 - android_intent_plus: ^4.0.0 + android_intent_plus: ^5.0.1 flutter_markdown: ^0.6.14 flutter_archive: ^6.0.0 hsluv: ^1.1.3 - connectivity_plus: ^5.0.0 + connectivity_plus: ^6.0.1 shared_storage: ^0.8.0 crypto: ^3.0.3 app_links: ^4.0.0