Compare commits

...

6 Commits

Author SHA1 Message Date
19a4489d4f Merge pull request #2387 from ImranR98/dev
- Added the option to run background updates in a "foreground" service (more reliable, more power drain)
- Fix unsupported protocol error for some sources (#2385)
- Make downgrade detection message more clear (#2342)
- Make some English strings sentence case (#2338)
- More logs to troubleshoot BG task (#1550)
2025-07-02 21:22:07 -04:00
98e4ae1921 More logs to troubleshoot BG task (#1550) 2025-07-02 21:17:02 -04:00
cdff0613b3 Make some English strings sentence case (#2338) 2025-07-02 20:40:09 -04:00
0f803b963f Make downgrade detection message more clear (#2342) 2025-07-02 20:33:11 -04:00
b9fffed625 Fix unsupported protocol error for some sources (#2385) 2025-07-02 20:25:21 -04:00
918091ba54 Added foreground service option + other updates 2025-07-02 20:09:20 -04:00
41 changed files with 382 additions and 112 deletions

View File

@ -61,6 +61,13 @@
android:enabled="true"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
<service
android:name="com.pravera.flutter_foreground_task.service.ForegroundService"
android:foregroundServiceType="specialUse"
android:exported="false" />
<meta-data
android:name="dev.imranr.obtainium.service.NOTIFICATION_ICON"
android:resource="@drawable/ic_notification" />
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
@ -74,6 +81,8 @@
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "تحتوي صفحة Obtainium على GitHub المرتبطة أدناه على روابط لمقاطع فيديو، مقالات، مناقشات وموارد أخرى ستساعدك على فهم كيفية استخدام التطبيق.",
"batteryOptimizationNote": "لاحظ أن التنزيلات في الخلفية قد تعمل بشكل أكثر موثوقية إذا قمت بتعطيل تحسينات بطارية النظام لـ Obtainium.",
"fileDeletionError": "فشل حذف الملف (حاول حذفه يدويًا ثم حاول مرة أخرى): \"{}\"",
"foregroundService": "الحصول على خدمة الحصول على خدمة المقدمة",
"foregroundServiceExplanation": "استخدام خدمة مقدمة للتحقق من التحديثات (أكثر موثوقية وتستهلك طاقة أكبر)",
"fgServiceNotice": "هذا الإشعار مطلوب للتحقق من التحديث في الخلفية (يمكن إخفاؤه في إعدادات نظام التشغيل)",
"removeAppQuestion": {
"one": "إزالة التطبيق؟",
"other": "إزالة التطبيقات؟"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "The Obtainium GitHub page linked below contains links to videos, articles, discussions and other resources that will help you understand how to use the app.",
"batteryOptimizationNote": "Note that background downloads may work more reliably if you disable OS battery optimizations for Obtainium.",
"fileDeletionError": "Failed to delete file (try deleting it manually then try again): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)",
"fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)",
"removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "La pàgina GitHub d'Obtainium enllaçada a sota conté enllaços a vídeos, articles, debats i altres recursos que t'ajudaran a entendre com usar l'aplicació.",
"batteryOptimizationNote": "Tingues present que les descàrregues en segon pla funcionaran millor si inhabilites l'optimització de bateria per a Obtainium.",
"fileDeletionError": "No s'ha pogut suprimir el fitxer (intenta suprimir-lo manualment i torna-ho a provar): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)",
"fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)",
"removeAppQuestion": {
"one": "¿Suprimeixo l'aplicació?",
"other": "¿Suprimeixo les aplicacions?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Níže odkazovaná stránka Obtainium GitHub obsahuje odkazy na videa, články, diskuse a další zdroje, které vám pomohou pochopit, jak aplikaci používat.",
"batteryOptimizationNote": "Všimněte si, že stahování na pozadí může fungovat spolehlivěji, pokud vypnete optimalizaci baterie operačního systému pro Obtainium.",
"fileDeletionError": "Soubor se nepodařilo odstranit (zkuste jej odstranit ručně a pak to zkuste znovu): \"{}\"",
"foregroundService": "Služba Obtainium na popředí",
"foregroundServiceExplanation": "Použití služby v popředí pro kontrolu aktualizací (spolehlivější, spotřebovává více energie).",
"fgServiceNotice": "Toto oznámení je nutné pro kontrolu aktualizací na pozadí (lze jej skrýt v nastavení operačního systému).",
"removeAppQuestion": {
"one": "Odstranit Apku?",
"other": "Odstranit Apky?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Obtainiums GitHub-side, som der linkes til nedenfor, indeholder links til videoer, artikler, diskussioner og andre ressourcer, som kan hjælpe dig med at forstå, hvordan du bruger appen.",
"batteryOptimizationNote": "Bemærk, at baggrundsdownloads kan fungere mere pålideligt, hvis du deaktiverer OS-batterioptimering for Obtainium.",
"fileDeletionError": "Kunne ikke slette filen (prøv at slette den manuelt og prøv igen): \"{}\"",
"foregroundService": "Obtainium forgrundstjeneste",
"foregroundServiceExplanation": "Brug en forgrundstjeneste til opdateringskontrol (mere pålidelig, bruger mere strøm)",
"fgServiceNotice": "Denne meddelelse er nødvendig for baggrundsopdateringskontrol (den kan skjules i OS-indstillingerne).",
"removeAppQuestion": {
"one": "Fjern app?",
"other": "Fjern apps?"

View File

@ -224,7 +224,7 @@
"autoLinkFilterByArch": "Nach Möglichkeit versuchen, APKs nach CPU-Architektur zu filtern",
"overrideSource": "Quelle überschreiben",
"dontShowAgain": "Nicht noch einmal anzeigen",
"dontShowTrackOnlyWarnings": Warnung für Nur nachverfolgen nicht anzeigen",
"dontShowTrackOnlyWarnings": "Warnung für Nur nachverfolgen nicht anzeigen",
"dontShowAPKOriginWarnings": "Warnung für APK-Herkunft nicht anzeigen",
"moveNonInstalledAppsToBottom": "Nicht installierte Apps ans Ende der App-Ansicht verschieben",
"gitlabPATLabel": "Persönlicher Zugangstoken für GitLab",
@ -330,6 +330,9 @@
"documentationLinksNote": "Die unten verlinkte GitHub-Seite von Obtainium enthält Links zu Videos, Artikeln, Diskussionen und anderen Ressourcen, die Ihnen helfen werden, die Verwendung der App zu verstehen.",
"batteryOptimizationNote": "Beachten Sie, dass Downloads im Hintergrund möglicherweise zuverlässiger funktionieren, wenn Sie die Batterieoptimierung des Betriebssystems für Obtainium deaktivieren.",
"fileDeletionError": "Die Datei konnte nicht gelöscht werden (versuchen Sie, sie manuell zu löschen und versuchen Sie es dann erneut): \"{}\"",
"foregroundService": "Obtainium-Vordergrunddienst",
"foregroundServiceExplanation": "Verwendung eines Dienstes im Vordergrund für die Aktualisierungsprüfung (zuverlässiger, verbraucht mehr Strom)",
"fgServiceNotice": "Diese Benachrichtigung ist für die Prüfung von Updates im Hintergrund erforderlich (sie kann in den Betriebssystemeinstellungen ausgeblendet werden)",
"removeAppQuestion": {
"one": "App entfernen?",
"other": "Apps entfernen?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "The Obtainium GitHub page linked below contains links to videos, articles, discussions and other resources that will help you understand how to use the app.",
"batteryOptimizationNote": "Note that background downloads may work more reliably if you disable OS battery optimizations for Obtainium.",
"fileDeletionError": "Failed to delete file (try deleting it manually then try again): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)",
"fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)",
"removeAppQuestion": {
"one": "Forigi la aplikaĵon?",
"other": "Forigi la aplikaĵojn?"

View File

@ -37,7 +37,7 @@
"cancelled": "Cancelled",
"appAlreadyAdded": "App already added",
"alreadyUpToDateQuestion": "App already up to date?",
"addApp": "Add App",
"addApp": "Add app",
"appSourceURL": "App source URL",
"error": "Error",
"add": "Add",
@ -88,7 +88,7 @@
"author": "Author",
"upToDateApps": "Up to date apps",
"nonInstalledApps": "Non-installed apps",
"importExport": "Import/Export",
"importExport": "Import/export",
"settings": "Settings",
"exportedTo": "Exported to {}",
"obtainiumExport": "Obtainium export",
@ -328,8 +328,11 @@
"sortMethod": "Sort method",
"welcome": "Welcome",
"documentationLinksNote": "The Obtainium GitHub page linked below contains links to videos, articles, discussions and other resources that will help you understand how to use the app.",
"batteryOptimizationNote": "Note that background downloads may work more reliably if you disable OS battery optimizations for Obtainium.",
"batteryOptimizationNote": "Note that background downloads may work more reliably if you switch to the \"foreground service\" in the Obtainium settings and/or disable battery optimization for Obtainium in your OS settings.",
"fileDeletionError": "Failed to delete file (try deleting it manually then try again): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)",
"fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)",
"removeAppQuestion": {
"one": "Remove app?",
"other": "Remove apps?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "La página GitHub de Obtainium enlazada a continuación contiene enlaces a vídeos, artículos, debates y otros recursos que te ayudarán a entender cómo utilizar la aplicación.",
"batteryOptimizationNote": "Ten en cuenta que las descargas en segundo plano pueden funcionar de forma más fiable si desactivas las optimizaciones de batería del sistema operativo para Obtainium.",
"fileDeletionError": "No se ha podido eliminar el archivo (intente eliminarlo manualmente y vuelva a intentarlo): \"{}\"",
"foregroundService": "Obtainium servicio en primer plano",
"foregroundServiceExplanation": "Utilizar un servicio en primer plano para comprobar las actualizaciones (más fiable, consume más energía).",
"fgServiceNotice": "Esta notificación es necesaria para la comprobación de actualizaciones en segundo plano (puede ocultarse en la configuración del sistema operativo).",
"removeAppQuestion": {
"one": "¿Eliminar aplicación?",
"other": "¿Eliminar aplicaciones?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "The Obtainium GitHub page linked below contains links to videos, articles, discussions and other resources that will help you understand how to use the app.",
"batteryOptimizationNote": "Note that background downloads may work more reliably if you disable OS battery optimizations for Obtainium.",
"fileDeletionError": "Failed to delete file (try deleting it manually then try again): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)",
"fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)",
"removeAppQuestion": {
"one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "La page GitHub d'Obtainium, dont le lien figure ci-dessous, contient des liens vers des vidéos, des articles, des discussions et d'autres ressources qui vous aideront à comprendre comment utiliser l'application.",
"batteryOptimizationNote": "Notez que les téléchargements en arrière-plan peuvent fonctionner de manière plus fiable si vous désactivez les optimisations de la batterie du système d'exploitation pour Obtainium.",
"fileDeletionError": "Échec de la suppression du fichier (essayez de le supprimer manuellement puis réessayez) : \"{}\"",
"foregroundService": "Service d'avant-plan Obtainium",
"foregroundServiceExplanation": "Utiliser un service de premier plan pour la vérification des mises à jour (plus fiable, consomme plus d'énergie)",
"fgServiceNotice": "Cette notification est nécessaire pour la vérification des mises à jour en arrière-plan (elle peut être masquée dans les paramètres du système d'exploitation).",
"removeAppQuestion": {
"one": "Supprimer l'application ?",
"other": "Supprimer les applications ?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Az alábbi hivatkozás az Obtainium GitHub oldalára vezet, amely további videók, cikkek, beszélgetések és egyéb források hivatkozásait tartalmazza, amelyek segítenek megérteni az alkalmazás használatát.",
"batteryOptimizationNote": "Megjegyzés: A háttérfrissítések megbízhatóbban működhetnek, ha kikapcsolja a rendszer akkumulátor-optimalizálását az Obtainium számára.",
"fileDeletionError": "Nem sikerült törölni a fájlt (próbálja meg kézzel törölni, majd próbálja meg újra): \"{}\"",
"foregroundService": "Obtainium új szolgáltatás",
"foregroundServiceExplanation": "Frissítésellenőrzéshez előtérben lévő szolgáltatás használata (megbízhatóbb, de több energiát fogyaszt)",
"fgServiceNotice": "Ez az értesítés a háttérben történő frissítésellenőrzéshez szükséges (az operációs rendszer beállításaiban elrejthető).",
"removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazásokat?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Halaman GitHub Obtainium yang ditautkan di bawah ini berisi tautan ke video, artikel, diskusi, dan sumber daya lain yang akan membantu Anda memahami cara menggunakan aplikasi.",
"batteryOptimizationNote": "Perhatikan bahwa unduhan latar belakang dapat bekerja lebih andal jika Anda menonaktifkan optimasi baterai OS untuk Obtainium.",
"fileDeletionError": "Gagal menghapus file (coba hapus secara manual, lalu coba lagi): \"{}\"",
"foregroundService": "Layanan latar depan Obtainium",
"foregroundServiceExplanation": "Gunakan layanan latar depan untuk pemeriksaan pembaruan (lebih dapat diandalkan, menghabiskan lebih banyak daya)",
"fgServiceNotice": "Pemberitahuan ini diperlukan untuk pemeriksaan pembaruan latar belakang (dapat disembunyikan dalam pengaturan OS)",
"removeAppQuestion": {
"one": "Hapus aplikasi?",
"other": "Hapus aplikasi?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "La pagina GitHub di Obtainium collegata qui sotto contiene collegamenti a video, articoli, discussioni e altre risorse che vi aiuteranno a capire come utilizzare l'applicazione.",
"batteryOptimizationNote": "Si noti che i download in background potrebbero funzionare in modo più affidabile se si disabilita l'ottimizzazione della batteria del sistema operativo per Obtainium.",
"fileDeletionError": "Errore nell'eliminazione del file (provare a cancellarlo manualmente e poi riprovare): \"{}\"",
"foregroundService": "Servizio Obtainium in primo piano",
"foregroundServiceExplanation": "Utilizzare un servizio in primo piano per il controllo degli aggiornamenti (più affidabile, consuma più energia)",
"fgServiceNotice": "Questa notifica è necessaria per il controllo degli aggiornamenti in background (può essere nascosta nelle impostazioni del sistema operativo).",
"removeAppQuestion": {
"one": "Rimuovere l'app?",
"other": "Rimuovere le app?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "以下のリンクにあるObtainium GitHubページには、ビデオ、記事、ディスカッション、その他のリソースへのリンクがあり、アプリの使い方を理解するのに役立ちます。",
"batteryOptimizationNote": "ObtainiumのOSバッテリー最適化を無効にすると、バックグラウンドダウンロードがより確実に動作するようになります。",
"fileDeletionError": "ファイルの削除に失敗しました(手動で削除してから再試行してください):\"{}\"",
"foregroundService": "フォアグラウンド・サービス",
"foregroundServiceExplanation": "更新チェックにフォアグラウンド・サービスを使用する(より信頼性が高いが、より電力を消費する)",
"fgServiceNotice": "この通知は、バックグラウンドでアップデートをチェックするために必要ですOSの設定で非表示にできます。",
"removeAppQuestion": {
"one": "アプリを削除しますか?",
"other": "アプリを削除しますか?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "아래에 링크된 Obtainium 깃허브 페이지에는 앱 사용 방법을 이해하는 데 도움이 되는 동영상, 기사, 토론 및 기타 리소스에 대한 링크가 포함되어 있습니다.",
"batteryOptimizationNote": "Obtainium의 OS 배터리 최적화를 비활성화하면 백그라운드 다운로드가 더 안정적으로 작동할 수 있습니다.",
"fileDeletionError": "파일을 삭제하지 못했습니다(수동으로 삭제한 후 다시 시도하세요): \"{}\"",
"foregroundService": "오베티움 포그라운드 서비스",
"foregroundServiceExplanation": "업데이트 확인을 위해 포그라운드 서비스 사용(안정성 향상, 전력 소비량 증가)",
"fgServiceNotice": "이 알림은 백그라운드 업데이트 확인에 필요합니다(OS 설정에서 숨길 수 있음).",
"removeAppQuestion": {
"one": "앱을 제거하시겠습니까?",
"other": "앱을 제거하시겠습니까?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "താഴെ ലിങ്ക് ചെയ്തിട്ടുള്ള ഒബ്‌റ്റേനിയം GitHub പേജിൽ ആപ്പ് എങ്ങനെ ഉപയോഗിക്കാമെന്ന് മനസ്സിലാക്കാൻ സഹായിക്കുന്ന വീഡിയോകൾ, ലേഖനങ്ങൾ, ചർച്ചകൾ, മറ്റ് വിഭവങ്ങൾ എന്നിവയുടെ ലിങ്കുകൾ അടങ്ങിയിരിക്കുന്നു.",
"batteryOptimizationNote": "ഒബ്‌റ്റേനിയത്തിനായുള്ള OS ബാറ്ററി ഒപ്റ്റിമൈസേഷനുകൾ പ്രവർത്തനരഹിതമാക്കുകയാണെങ്കിൽ ബാക്ക്ഗ്രൗണ്ട് ഡൗൺലോഡുകൾ കൂടുതൽ വിശ്വസനീയമായി പ്രവർത്തിച്ചേക്കാം എന്നത് ശ്രദ്ധിക്കുക.",
"fileDeletionError": "ഫയൽ ഇല്ലാതാക്കാൻ പരാജയപ്പെട്ടു (സ്വമേധയാ ഇല്ലാതാക്കാൻ ശ്രമിക്കുക, എന്നിട്ട് വീണ്ടും ശ്രമിക്കുക): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)",
"fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)",
"removeAppQuestion": {
"one": "ആപ്പ് നീക്കം ചെയ്യണോ?",
"other": "ആപ്പുകൾ നീക്കം ചെയ്യണോ?"
@ -390,4 +393,4 @@
"one": "{} APK",
"other": "{} APK-കൾ"
}
}
}

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "De GitHub pagina van Obtainium waarnaar hieronder wordt gelinkt bevat links naar video's, artikelen, discussies en andere bronnen die je zullen helpen begrijpen hoe je de app kunt gebruiken.",
"batteryOptimizationNote": "Merk op dat downloads op de achtergrond mogelijk betrouwbaarder werken als je de batterijoptimalisatie van het besturingssysteem voor Obtainium uitschakelt.",
"fileDeletionError": "Bestand is niet verwijderd (probeer het handmatig te verwijderen en probeer het opnieuw): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Gebruik een voorgronddienst voor het controleren van updates (betrouwbaarder, verbruikt meer stroom)",
"fgServiceNotice": "Deze melding is nodig voor het controleren van updates op de achtergrond (kan worden verborgen in de OS-instellingen)",
"removeAppQuestion": {
"one": "App verwijderen?",
"other": "Apps verwijderen?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Strona Obtainium GitHub, do której link znajduje się poniżej, zawiera linki do filmów, artykułów, dyskusji i innych zasobów, które pomogą ci zrozumieć, jak korzystać z aplikacji.",
"batteryOptimizationNote": "Należy pamiętać, że pobieranie w tle może działać bardziej niezawodnie po wyłączeniu optymalizacji baterii systemu operacyjnego dla Obtainium.",
"fileDeletionError": "Nie udało się usunąć pliku (spróbuj usunąć go ręcznie, a następnie spróbuj ponownie): \"{}\"",
"foregroundService": "Usługa nowej generacji Obtainium",
"foregroundServiceExplanation": "Używanie usługi pierwszoplanowej do sprawdzania aktualizacji (bardziej niezawodne, zużywa więcej energii)",
"fgServiceNotice": "To powiadomienie jest wymagane do sprawdzania aktualizacji w tle (można je ukryć w ustawieniach systemu operacyjnego).",
"removeAppQuestion": {
"one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?",

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "A página do Obtainium no GitHub visível abaixo contém links de vídeos, artigos, discussões, e outros recursos que podem te ajudar ao usar o app.",
"batteryOptimizationNote": "Observe que os downloads em segundo plano podem funcionar de forma mais confiável se você desativar as otimizações de bateria do sistema operacional para o Obtainium.",
"fileDeletionError": "Falha ao excluir o arquivo (tente excluí-lo manualmente e tente novamente): \"{}\"",
"foregroundService": "Serviço de primeiro plano do Obtainium",
"foregroundServiceExplanation": "Usar um serviço em primeiro plano para verificação de atualizações (mais confiável, consome mais energia)",
"fgServiceNotice": "Essa notificação é necessária para a verificação de atualizações em segundo plano (ela pode ser ocultada nas configurações do sistema operacional)",
"removeAppQuestion": {
"one": "Remover app?",
"other": "Remover apps?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "A página do Obtainium no GitHub com a ligação abaixo contém ligações para vídeos, artigos, discussões e outros recursos que o ajudarão a compreender como utilizar a aplicação.",
"batteryOptimizationNote": "Note que os downloads em segundo plano podem funcionar de forma mais fiável se desativar as optimizações da bateria do SO para o Obtainium.",
"fileDeletionError": "Falha ao eliminar o ficheiro (tente eliminá-lo manualmente e depois tente novamente): \"{}\"",
"foregroundService": "Serviço de primeiro plano Obtainium",
"foregroundServiceExplanation": "Utilizar um serviço em primeiro plano para verificação de actualizações (mais fiável, consome mais energia)",
"fgServiceNotice": "Esta notificação é necessária para a verificação de actualizações em segundo plano (pode ser ocultada nas definições do SO)",
"removeAppQuestion": {
"one": "Remover aplicativo?",
"other": "Remover aplicativos?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "На странице Obtainium в GitHub, ссылка на которую приведена ниже, содержатся ссылки на видео, статьи, обсуждения и другие ресурсы, которые помогут вам понять, как пользоваться приложением.",
"batteryOptimizationNote": "Обратите внимание, что фоновая загрузка может работать более надёжно, если отключить оптимизацию батареи ОС для Obtainium.",
"fileDeletionError": "Не удалось удалить файл (попробуйте удалить его вручную, а затем повторите попытку): «{}»",
"foregroundService": "Передний план службы Obtainium",
"foregroundServiceExplanation": "Используйте службу переднего плана для проверки обновлений (более надежно, потребляет больше энергии).",
"fgServiceNotice": "Это уведомление необходимо для фоновой проверки обновлений (его можно скрыть в настройках ОС)",
"removeAppQuestion": {
"one": "Удалить приложение?",
"other": "Удалить приложения?"
@ -345,7 +348,6 @@
"other": "При проверке обновлений в фоновом режиме возникла ошибка {}, повторная проверка будет через {} минут"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "При проверке в фоновом режиме было обнаружено {} обновление — пользователь будет уведомлен по необходимости",
"one": "При проверке в фоновом режиме было обнаружено {} обновления — пользователь будет уведомлен по необходимости",
"other": "При проверке в фоновом режиме было обнаружено {} обновлений — пользователь будет уведомлен по необходимости"
},

View File

@ -16,10 +16,11 @@ const neverAutoTranslate = {
placeholder: ['pl'],
importExport: ['fr'],
url: ['fr'],
vivoAppStore: ['cs', 'ja', 'ko'],
vivoAppStore: ['cs', 'ja', 'ko', 'vi'],
coolapk: ['ja'],
obtainiumImport: ['nl'],
appLogs: ['nl'],
apks: ['vi'],
tencentAppStore: ['*']
}

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Obtainium GitHub-sidan som länkas nedan innehåller länkar till videor, artiklar, diskussioner och andra resurser som hjälper dig att förstå hur du använder appen.",
"batteryOptimizationNote": "Observera att nedladdningar i bakgrunden kan fungera mer tillförlitligt om du inaktiverar OS-batterioptimeringar för Obtainium.",
"fileDeletionError": "Misslyckades med att radera filen (försök radera den manuellt och försök sedan igen): \"{}\"",
"foregroundService": "Obtainium förgrundstjänst",
"foregroundServiceExplanation": "Använd en förgrundstjänst för uppdateringskontroll (mer tillförlitlig, förbrukar mer ström)",
"fgServiceNotice": "Detta meddelande krävs för bakgrundsuppdateringskontroll (det kan döljas i OS-inställningarna)",
"removeAppQuestion": {
"one": "Ta Bort App?",
"other": "Ta Bort Appar?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Aşağıda bağlantısı verilen Obtainium GitHub sayfası, uygulamayı nasıl kullanacağınızı anlamanıza yardımcı olacak videolara, makalelere, tartışmalara ve diğer kaynaklara bağlantılar içerir.",
"batteryOptimizationNote": "Obtainium için işletim sistemi pil optimizasyonlarını devre dışı bırakırsanız arka planda indirmelerin daha güvenilir şekilde çalışabileceğini unutmayın.",
"fileDeletionError": "Dosya silinemedi (elle silmeyi deneyin ve sonra tekrar deneyin): \"{}\"",
"foregroundService": "Obtainium ön plan hizmeti",
"foregroundServiceExplanation": "Güncelleme denetimi için bir ön plan hizmeti kullanın (daha güvenilir, daha fazla güç tüketir)",
"fgServiceNotice": "Bu bildirim arka planda güncelleme kontrolü için gereklidir (işletim sistemi ayarlarından gizlenebilir)",
"removeAppQuestion": {
"one": "Uygulamayı Kaldır?",
"other": "Uygulamaları Kaldır?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "Сторінка Obtainium на GitHub, посилання на яку наведено нижче, містить посилання на відео, статті, дискусії та інші ресурси, які допоможуть вам зрозуміти, як користуватися додатком.",
"batteryOptimizationNote": "Зауважте, що фонові завантаження можуть працювати надійніше, якщо ви вимкнете оптимізацію батареї ОС для Obtainium.",
"fileDeletionError": "Не вдалося видалити файл (спробуйте видалити його вручну, а потім спробуйте ще раз): \"{}\"",
"foregroundService": "Обслуговування переднього плану Obtainium",
"foregroundServiceExplanation": "Використовуйте службу переднього плану для перевірки оновлень (надійніша, споживає більше енергії)",
"fgServiceNotice": "Це сповіщення необхідне для фонової перевірки оновлень (його можна приховати в налаштуваннях ОС)",
"removeAppQuestion": {
"one": "Видалити застосунок?",
"other": "Видалити застосунки?"

View File

@ -113,7 +113,7 @@
"dark": "Tối",
"light": "Sáng",
"followSystem": "Theo hệ thống",
"followSystemThemeExplanation": "Following system theme is possible only by using third-party applications",
"followSystemThemeExplanation": "Việc áp dụng chủ đề hệ thống chỉ có thể thực hiện được thông qua việc sử dụng các ứng dụng của bên thứ ba.",
"useBlackTheme": "Nền đen",
"appSortBy": "Sắp xếp ứng dụng",
"authorName": "Tác giả",
@ -211,7 +211,7 @@
"uninstallFromDevice": "Gỡ cài đặt khỏi thiết bị",
"onlyWorksWithNonVersionDetectApps": "Chỉ hoạt động với Ứng dụng đã tắt tính năng phát hiện phiên bản.",
"releaseDateAsVersion": "Sử dụng ngày phát hành làm phiên bản",
"releaseTitleAsVersion": "Use release title as version string",
"releaseTitleAsVersion": "Sử dụng tiêu đề bản phát hành làm chuỗi phiên bản",
"releaseDateAsVersionExplanation": "Chỉ nên sử dụng tùy chọn này cho Ứng dụng trong đó tính năng phát hiện phiên bản không hoạt động chính xác nhưng đã có ngày phát hành.",
"changes": "Thay đổi",
"releaseDate": "Ngày phát hành",
@ -221,7 +221,7 @@
"standardVersionDetection": "Phát hiện phiên bản tiêu chuẩn",
"groupByCategory": "Nhóm theo danh mục",
"autoApkFilterByArch": "Cố gắng lọc APK theo kiến trúc CPU nếu có thể",
"autoLinkFilterByArch": "Attempt to filter links by CPU architecture if possible",
"autoLinkFilterByArch": "Cố gắng lọc các liên kết theo kiến trúc CPU nếu có thể.",
"overrideSource": "Ghi đè nguồn",
"dontShowAgain": "Đừng hiển thị thông tin này nữa",
"dontShowTrackOnlyWarnings": "Không hiển thị cảnh báo 'Chỉ theo dõi'",
@ -257,7 +257,7 @@
"intermediateLink": "Liên kết trung gian",
"exemptFromBackgroundUpdates": "Miễn cập nhật nền (nếu được bật)",
"bgUpdatesOnWiFiOnly": "Tắt cập nhật nền khi không có Wi-Fi",
"bgUpdatesWhileChargingOnly": "Disable background updates when not charging",
"bgUpdatesWhileChargingOnly": "Tắt cập nhật nền khi không sạc pin.",
"autoSelectHighestVersionCode": "Tự động chọn APK mã phiên bản cao nhất",
"versionExtractionRegEx": "Trích xuất phiên bản RegEx",
"trimVersionString": "Trim Version String With RegEx",
@ -295,7 +295,7 @@
"shizukuBinderNotFound": "Shizuku chưa khởi động",
"shizukuOld": "Phiên bản Shizuku lỗi thời (<11) - hãy cập nhật nó",
"shizukuOldAndroidWithADB": "Shizuku chạy trên Android < 8.1 với ADB - hãy cập nhật Android hoặc thay bằng Sui",
"shizukuPretendToBeGooglePlay": "Set Google Play as the installation source (if Shizuku is used)",
"shizukuPretendToBeGooglePlay": "Đặt Google Play làm nguồn cài đặt (nếu sử dụng Shizuku)",
"useSystemFont": "Sử dụng phông chữ hệ thống",
"useVersionCodeAsOSVersion": "Sử dụng Mã phiên bản ứng dụng làm phiên bản do hệ điều hành phát hiện",
"requestHeader": "Tiêu đề yêu cầu",
@ -316,20 +316,23 @@
"wiki": "Trợ giúp/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourced App Configurations (use at your own risk)",
"crowdsourcedConfigsShort": "Crowdsourced App Configurations",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"useFirstApkOfVersion": "Auto-select first of multiple APKs",
"refreshBeforeDownload": "Refresh app details before download",
"allowInsecure": "Cho phép các yêu cầu HTTP không an toàn",
"stayOneVersionBehind": "Luôn sử dụng phiên bản cũ hơn một phiên bản so với phiên bản mới nhất.",
"useFirstApkOfVersion": "Tự động chọn tệp APK đầu tiên trong danh sách nhiều tệp APK.",
"refreshBeforeDownload": "Cập nhật thông tin ứng dụng trước khi tải xuống",
"tencentAppStore": "Tencent App Store",
"coolApk": "CoolApk",
"vivoAppStore": "vivo App Store (CN)",
"name": "Name",
"name": "Tên",
"smartname": "Name (Smart)",
"sortMethod": "Sort Method",
"welcome": "Welcome",
"documentationLinksNote": "The Obtainium GitHub page linked below contains links to videos, articles, discussions and other resources that will help you understand how to use the app.",
"welcome": "Chào mừng",
"documentationLinksNote": "Trang GitHub của Obtainium được liên kết bên dưới chứa các liên kết đến video, bài viết, thảo luận và các tài nguyên khác sẽ giúp bạn hiểu cách sử dụng ứng dụng.",
"batteryOptimizationNote": "Note that background downloads may work more reliably if you disable OS battery optimizations for Obtainium.",
"fileDeletionError": "Failed to delete file (try deleting it manually then try again): \"{}\"",
"fileDeletionError": "Không thể xóa tệp (hãy thử xóa tệp thủ công rồi thử lại): \"{}\"",
"foregroundService": "Dịch vụ nền Obtainium",
"foregroundServiceExplanation": "Sử dụng dịch vụ nền trước để kiểm tra cập nhật (đáng tin cậy hơn, tiêu tốn nhiều pin hơn)",
"fgServiceNotice": "Thông báo này là bắt buộc để kiểm tra cập nhật nền (có thể ẩn trong cài đặt hệ điều hành).",
"removeAppQuestion": {
"one": "Gỡ ứng dụng?",
"other": "Gỡ ứng dụng?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "下方連結的 Obtainium GitHub 頁面包含影片、文章、討論及其他資源,能幫助你瞭解如何使用這款應用程式。",
"batteryOptimizationNote": "Note that background downloads may work more reliably if you disable OS battery optimizations for Obtainium.",
"fileDeletionError": "Failed to delete file (try deleting it manually then try again): \"{}\"",
"foregroundService": "Obtainium foreground service",
"foregroundServiceExplanation": "Use a foreground service for update checking (more reliable, consumes more power)",
"fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)",
"removeAppQuestion": {
"one": "移除應用程式?",
"other": "移除應用程式?"

View File

@ -330,6 +330,9 @@
"documentationLinksNote": "下面链接的 Obtainium GitHub 页面包含视频、文章、讨论和其他资源的链接,可帮助您了解如何使用该应用程序。",
"batteryOptimizationNote": "请注意,如果为 Obtainium 禁用操作系统电池优化功能,后台下载可能会更稳定。",
"fileDeletionError": "删除文件失败(尝试手动删除,然后再试一次):\"{}\"",
"foregroundService": "获取前台服务",
"foregroundServiceExplanation": "使用前台服务进行更新检查(更可靠,耗电量更大)",
"fgServiceNotice": "后台更新检查需要此通知(可在操作系统设置中隐藏)。",
"removeAppQuestion": {
"one": "是否删除应用?",
"other": "是否删除应用?"

View File

@ -53,7 +53,10 @@ class UnsupportedURLError extends ObtainiumError {
}
class DowngradeError extends ObtainiumError {
DowngradeError() : super(tr('cantInstallOlderVersion'));
DowngradeError(int currentVersionCode, int newVersionCode)
: super(
'${tr('cantInstallOlderVersion')} (versionCode $currentVersionCode$newVersionCode)',
);
}
class InstallError extends ObtainiumError {

View File

@ -9,7 +9,6 @@ import 'package:obtainium/providers/native_provider.dart';
import 'package:obtainium/providers/notifications_provider.dart';
import 'package:obtainium/providers/settings_provider.dart';
import 'package:obtainium/providers/source_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:device_info_plus/device_info_plus.dart';
@ -19,6 +18,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:easy_localization/src/easy_localization_controller.dart';
// ignore: implementation_imports
import 'package:easy_localization/src/localization.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
List<MapEntry<Locale, String>> supportedLocales = const [
MapEntry(Locale('en'), 'English'),
@ -51,6 +51,7 @@ List<MapEntry<Locale, String>> supportedLocales = const [
MapEntry(Locale('ko'), '한국어'),
MapEntry(Locale('ca'), 'Català'),
MapEntry(Locale('ar'), 'العربية'),
MapEntry(Locale('ml'), 'മലയാളം'),
];
const fallbackLocale = Locale('en');
const localeDir = 'assets/translations';
@ -98,6 +99,34 @@ void backgroundFetchHeadlessTask(HeadlessTask task) async {
BackgroundFetch.finish(taskId);
}
@pragma('vm:entry-point')
void startCallback() {
FlutterForegroundTask.setTaskHandler(MyTaskHandler());
}
class MyTaskHandler extends TaskHandler {
static const String incrementCountCommand = 'incrementCount';
@override
Future<void> onStart(DateTime timestamp, TaskStarter starter) async {
print('onStart(starter: ${starter.name})');
bgUpdateCheck('bg_check', null);
}
@override
void onRepeatEvent(DateTime timestamp) {
bgUpdateCheck('bg_check', null);
}
@override
Future<void> onDestroy(DateTime timestamp, bool isTimeout) async {
print('Foreground service onDestroy(isTimeout: $isTimeout)');
}
@override
void onReceiveData(Object data) {}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
try {
@ -119,6 +148,7 @@ void main() async {
}
final np = NotificationsProvider();
await np.initialize();
FlutterForegroundTask.initCommunicationPort();
runApp(
MultiProvider(
providers: [
@ -153,6 +183,80 @@ class _ObtainiumState extends State<Obtainium> {
void initState() {
super.initState();
initPlatformState();
WidgetsBinding.instance.addPostFrameCallback((_) {
requestNonOptionalPermissions();
initForegroundService();
});
}
Future<void> requestNonOptionalPermissions() async {
final NotificationPermission notificationPermission =
await FlutterForegroundTask.checkNotificationPermission();
if (notificationPermission != NotificationPermission.granted) {
await FlutterForegroundTask.requestNotificationPermission();
}
if (!await FlutterForegroundTask.isIgnoringBatteryOptimizations) {
await FlutterForegroundTask.requestIgnoreBatteryOptimization();
}
}
void initForegroundService() {
FlutterForegroundTask.init(
androidNotificationOptions: AndroidNotificationOptions(
channelId: 'bg_update',
channelName: tr('foregroundService'),
channelDescription: tr('foregroundService'),
onlyAlertOnce: true,
),
iosNotificationOptions: const IOSNotificationOptions(
showNotification: false,
playSound: false,
),
foregroundTaskOptions: ForegroundTaskOptions(
eventAction: ForegroundTaskEventAction.repeat(900000),
autoRunOnBoot: true,
autoRunOnMyPackageReplaced: true,
allowWakeLock: true,
allowWifiLock: true,
),
);
}
Future<ServiceRequestResult?> startForegroundService(bool restart) async {
if (await FlutterForegroundTask.isRunningService) {
if (restart) {
return FlutterForegroundTask.restartService();
}
} else {
return FlutterForegroundTask.startService(
serviceTypes: [ForegroundServiceTypes.specialUse],
serviceId: 666,
notificationTitle: tr('foregroundService'),
notificationText: tr('fgServiceNotice'),
notificationIcon: NotificationIcon(
metaDataName: 'dev.imranr.obtainium.service.NOTIFICATION_ICON',
),
callback: startCallback,
);
}
return null;
}
stopForegroundService() async {
if (await FlutterForegroundTask.isRunningService) {
return FlutterForegroundTask.stopService();
}
}
// void onReceiveForegroundServiceData(Object data) {
// print('onReceiveTaskData: $data');
// }
@override
void dispose() {
// Remove a callback to receive data sent from the TaskHandler.
// FlutterForegroundTask.removeTaskDataCallback(onReceiveForegroundServiceData);
super.dispose();
}
Future<void> initPlatformState() async {
@ -186,15 +290,25 @@ class _ObtainiumState extends State<Obtainium> {
AppsProvider appsProvider = context.read<AppsProvider>();
LogsProvider logs = context.read<LogsProvider>();
NotificationsProvider notifs = context.read<NotificationsProvider>();
if (settingsProvider.updateInterval == 0) {
stopForegroundService();
BackgroundFetch.stop();
} else {
if (settingsProvider.useFGService) {
BackgroundFetch.stop();
startForegroundService(false);
} else {
stopForegroundService();
BackgroundFetch.start();
}
}
if (settingsProvider.prefs == null) {
settingsProvider.initializeSettings();
} else {
bool isFirstRun = settingsProvider.checkAndFlipFirstRun();
if (isFirstRun) {
logs.add('This is the first ever run of Obtainium.');
// If this is the first run, ask for notification permissions and add Obtainium to the Apps list
Permission.notification.request();
// If this is the first run, add Obtainium to the Apps list
if (!fdroid) {
getInstalledInfo(obtainiumId)
.then((value) {
@ -236,68 +350,71 @@ class _ObtainiumState extends State<Obtainium> {
notifs.checkLaunchByNotif();
});
return DynamicColorBuilder(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
// Decide on a colour/brightness scheme based on OS and user settings
ColorScheme lightColorScheme;
ColorScheme darkColorScheme;
if (lightDynamic != null &&
darkDynamic != null &&
settingsProvider.useMaterialYou) {
lightColorScheme = lightDynamic.harmonized();
darkColorScheme = darkDynamic.harmonized();
} else {
lightColorScheme = ColorScheme.fromSeed(
seedColor: settingsProvider.themeColor,
return WithForegroundTask(
child: DynamicColorBuilder(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
// Decide on a colour/brightness scheme based on OS and user settings
ColorScheme lightColorScheme;
ColorScheme darkColorScheme;
if (lightDynamic != null &&
darkDynamic != null &&
settingsProvider.useMaterialYou) {
lightColorScheme = lightDynamic.harmonized();
darkColorScheme = darkDynamic.harmonized();
} else {
lightColorScheme = ColorScheme.fromSeed(
seedColor: settingsProvider.themeColor,
);
darkColorScheme = ColorScheme.fromSeed(
seedColor: settingsProvider.themeColor,
brightness: Brightness.dark,
);
}
// set the background and surface colors to pure black in the amoled theme
if (settingsProvider.useBlackTheme) {
darkColorScheme = darkColorScheme
.copyWith(surface: Colors.black)
.harmonized();
}
if (settingsProvider.useSystemFont) NativeFeatures.loadSystemFont();
return MaterialApp(
title: 'Obtainium',
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
navigatorKey: globalNavigatorKey,
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
colorScheme: settingsProvider.theme == ThemeSettings.dark
? darkColorScheme
: lightColorScheme,
fontFamily: settingsProvider.useSystemFont
? 'SystemFont'
: 'Montserrat',
),
darkTheme: ThemeData(
useMaterial3: true,
colorScheme: settingsProvider.theme == ThemeSettings.light
? lightColorScheme
: darkColorScheme,
fontFamily: settingsProvider.useSystemFont
? 'SystemFont'
: 'Montserrat',
),
home: Shortcuts(
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.select):
const ActivateIntent(),
},
child: const HomePage(),
),
);
darkColorScheme = ColorScheme.fromSeed(
seedColor: settingsProvider.themeColor,
brightness: Brightness.dark,
);
}
// set the background and surface colors to pure black in the amoled theme
if (settingsProvider.useBlackTheme) {
darkColorScheme = darkColorScheme
.copyWith(surface: Colors.black)
.harmonized();
}
if (settingsProvider.useSystemFont) NativeFeatures.loadSystemFont();
return MaterialApp(
title: 'Obtainium',
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
navigatorKey: globalNavigatorKey,
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
colorScheme: settingsProvider.theme == ThemeSettings.dark
? darkColorScheme
: lightColorScheme,
fontFamily: settingsProvider.useSystemFont
? 'SystemFont'
: 'Montserrat',
),
darkTheme: ThemeData(
useMaterial3: true,
colorScheme: settingsProvider.theme == ThemeSettings.light
? lightColorScheme
: darkColorScheme,
fontFamily: settingsProvider.useSystemFont
? 'SystemFont'
: 'Montserrat',
),
home: Shortcuts(
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
},
child: const HomePage(),
),
);
},
},
),
);
}
}

View File

@ -312,7 +312,10 @@ class AddAppPageState extends State<AddAppPage> {
context: context,
builder: (BuildContext ctx) {
return SelectionModal(
title: tr('selectX', args: [plural('source', 2)]),
title: tr(
'selectX',
args: [plural('source', 2).toLowerCase()],
),
entries: sourceStrings,
selectedByDefault: true,
onlyOneSelectionAllowed: false,

View File

@ -46,7 +46,10 @@ class _AppPageState extends State<AppPage> {
}
},
onNavigationRequest: (NavigationRequest request) =>
request.url.startsWith("rustore://")
!(request.url.startsWith("http://") ||
request.url.startsWith("https://") ||
request.url.startsWith("ftp://") ||
request.url.startsWith("ftps://"))
? NavigationDecision.prevent
: NavigationDecision.navigate,
),

View File

@ -272,7 +272,9 @@ class _ImportExportPageState extends State<ImportExportPage> {
showMessage(
tr(
'importedX',
args: [plural('apps', selectedUrls.length)],
args: [
plural('apps', selectedUrls.length).toLowerCase(),
],
),
context,
);
@ -339,7 +341,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
showMessage(
tr(
'importedX',
args: [plural('apps', selectedUrls.length)],
args: [plural('apps', selectedUrls.length).toLowerCase()],
),
context,
);
@ -512,7 +514,11 @@ class _ImportExportPageState extends State<ImportExportPage> {
return SelectionModal(
title: tr(
'selectX',
args: [tr('source')],
args: [
tr(
'source',
).toLowerCase(),
],
),
entries: sourceStrings,
selectedByDefault: false,

View File

@ -138,7 +138,7 @@ class _SettingsPageState extends State<SettingsPage> {
ColorPickerType.wheel: tr('custom'),
},
title: Text(
tr('selectX', args: [tr('colour')]),
tr('selectX', args: [tr('colour').toLowerCase()]),
style: Theme.of(context).textTheme.titleLarge,
),
wheelDiameter: 192,
@ -180,7 +180,7 @@ class _SettingsPageState extends State<SettingsPage> {
var colorPicker = ListTile(
dense: true,
contentPadding: EdgeInsets.zero,
title: Text(tr('selectX', args: [tr('colour')])),
title: Text(tr('selectX', args: [tr('colour').toLowerCase()])),
subtitle: Text(
"${ColorTools.nameThatColor(settingsProvider.themeColor)} "
"(${ColorTools.materialNameAndCode(settingsProvider.themeColor, colorSwatchNameMap: colorsNameMap)})",
@ -381,6 +381,27 @@ class _SettingsPageState extends State<SettingsPage> {
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
tr(
'foregroundServiceExplanation',
),
),
),
Switch(
value:
settingsProvider.useFGService,
onChanged: (value) {
settingsProvider.useFGService =
value;
},
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,

View File

@ -916,7 +916,7 @@ class AppsProvider with ChangeNotifier {
if (appInfo != null &&
newInfo.versionCode! < appInfo.versionCode! &&
!(await canDowngradeApps())) {
throw DowngradeError();
throw DowngradeError(appInfo.versionCode!, newInfo.versionCode!);
}
if (needsBGWorkaround) {
// The below 'await' will never return if we are in a background process
@ -2272,7 +2272,7 @@ class _APKOriginWarningDialogState extends State<APKOriginWarningDialog> {
///
Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
// ignore: avoid_print
print('Started $taskId: ${params.toString()}');
print('BG task started $taskId: ${params.toString()}');
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
await loadTranslations();
@ -2441,10 +2441,14 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
// Filter out updates that will be installed silently (the rest go into toNotify)
for (var i = 0; i < updates.length; i++) {
if (networkRestricted ||
chargingRestricted ||
!(await appsProvider.canInstallSilently(updates[i]))) {
var canInstallSilently = await appsProvider.canInstallSilently(
updates[i],
);
if (networkRestricted || chargingRestricted || !canInstallSilently) {
if (updates[i].additionalSettings['skipUpdateNotifications'] != true) {
logs.add(
'BG update task notifying for ${updates[i].id} (networkRestricted $networkRestricted, chargingRestricted: $chargingRestricted, canInstallSilently: $canInstallSilently).',
);
toNotify.add(updates[i]);
}
}
@ -2470,7 +2474,7 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
logs.add('BG update task: Done checking for updates.');
if (toRetry.isNotEmpty) {
logs.add(
'BG update task $taskId: Will retry in $retryAfterXSeconds seconds.',
'BG update task $taskId: Will retry in $retryAfterXSeconds seconds (${toRetry.length} to retry, ${toInstall.length} to install).',
);
return await bgUpdateCheck(taskId, {
'toCheck': toRetry
@ -2482,7 +2486,9 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
});
} else {
// If there are no more update checks, call the function in install mode
logs.add('BG update task: Done checking for updates.');
logs.add(
'BG update task: Done checking for updates (${toRetry.length} to retry, ${toInstall.length} to install).',
);
return await bgUpdateCheck(taskId, {
'toCheck': [],
'toInstall': toInstall
@ -2493,6 +2499,7 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
} else {
// In install mode...
// If you haven't explicitly been given updates to install, grab all available silent updates
logs.add('BG install task: Started (${toInstall.length}).');
if (toInstall.isEmpty && !networkRestricted && !chargingRestricted) {
var temp = appsProvider.findExistingUpdates(installedOnly: true);
for (var i = 0; i < temp.length; i++) {
@ -2504,7 +2511,6 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
}
}
if (toInstall.isNotEmpty) {
logs.add('BG install task: Started (${toInstall.length}).');
var tempObtArr = toInstall.where((element) => element.key == obtainiumId);
if (tempObtArr.isNotEmpty) {
// Move obtainium to the end of the list as it must always install last

View File

@ -498,4 +498,13 @@ class SettingsProvider with ChangeNotifier {
prefs?.setBool('shizukuPretendToBeGooglePlay', val);
notifyListeners();
}
bool get useFGService {
return prefs?.getBool('useFGService') ?? false;
}
set useFGService(bool val) {
prefs?.setBool('useFGService', val);
notifyListeners();
}
}

View File

@ -104,10 +104,10 @@ packages:
dependency: "direct main"
description:
name: battery_plus
sha256: a0409fe7d21905987eb1348ad57c634f913166f14f0c8936b73d3f5940fac551
sha256: fb794c34cee2e4ea31005fb17ff15e1d904951ec7f15eedead741021870ee834
url: "https://pub.dev"
source: hosted
version: "6.2.1"
version: "6.2.2"
battery_plus_platform_interface:
dependency: transitive
description:
@ -216,18 +216,18 @@ packages:
dependency: "direct main"
description:
name: device_info_plus
sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53"
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
url: "https://pub.dev"
source: hosted
version: "11.4.0"
version: "11.5.0"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
url: "https://pub.dev"
source: hosted
version: "7.0.2"
version: "7.0.3"
dynamic_color:
dependency: "direct main"
description:
@ -377,6 +377,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.1"
flutter_foreground_task:
dependency: "direct main"
description:
name: flutter_foreground_task
sha256: "9f1b25a81db95d7119d2c5cffc654048cbdd49d4056183e1beadc1a6a38f3e29"
url: "https://pub.dev"
source: hosted
version: "9.1.0"
flutter_keyboard_visibility:
dependency: transitive
description:
@ -995,10 +1003,10 @@ packages:
dependency: transitive
description:
name: synchronized
sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6"
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
url: "https://pub.dev"
source: hosted
version: "3.3.1"
version: "3.4.0"
term_glyph:
dependency: transitive
description:
@ -1201,4 +1209,4 @@ packages:
version: "6.3.0"
sdks:
dart: ">=3.8.1 <4.0.0"
flutter: ">=3.27.0"
flutter: ">=3.29.0"

View File

@ -16,7 +16,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.1.58+2315
version: 1.2.0+2316
environment:
sdk: ^3.8.1
@ -94,6 +94,7 @@ dependencies:
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^6.0.0
flutter_foreground_task: ^9.1.0
flutter_launcher_icons:
android: "ic_launcher"