diff --git a/app/build.gradle b/app/build.gradle index d34de50..2f42134 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { minSdkVersion 21 targetSdkVersion 33 - versionCode 29 - versionName "1.15.0" + versionCode 31 + versionName "1.15.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -44,10 +44,12 @@ android { play { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'true' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'true' + buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'false' } fdroid { buildConfigField 'boolean', 'FIREBASE_AVAILABLE', 'false' buildConfigField 'boolean', 'RATE_APP_AVAILABLE', 'false' + buildConfigField 'boolean', 'INSTALL_PACKAGES_AVAILABLE', 'true' } } @@ -64,12 +66,29 @@ android { } } +// Disables GoogleServices tasks for F-Droid variant android.applicationVariants.all { variant -> def shouldProcessGoogleServices = variant.flavorName == "play" def googleTask = tasks.findByName("process${variant.name.capitalize()}GoogleServices") googleTask.enabled = shouldProcessGoogleServices } +// Strips out REQUEST_INSTALL_PACKAGES permission for Google Play variant +android.applicationVariants.all { variant -> + def shouldStripInstallPermission = variant.flavorName == "play" + if (shouldStripInstallPermission) { + variant.outputs.each { output -> + def processManifest = output.getProcessManifestProvider().get() + processManifest.doLast { task -> + def outputDir = task.getMultiApkManifestOutputDirectory().get().asFile + def manifestOutFile = file("$outputDir/AndroidManifest.xml") + def newFileContents = manifestOutFile.collect { s -> s.contains("android.permission.REQUEST_INSTALL_PACKAGES") ? "" : s }.join("\n") + manifestOutFile.write(newFileContents, 'UTF-8') + } + } + } +} + dependencies { // AndroidX, The Basics implementation "androidx.appcompat:appcompat:1.5.1" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8120b56..0950b40 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + @@ -8,10 +9,17 @@ - + + + Unit, private val onLongClick: (Notification) -> Unit) : ListAdapter(TopicDiffCallback) { val selected = mutableSetOf() // Notification IDs @@ -371,6 +371,12 @@ class DetailAdapter(private val activity: Activity, private val lifecycleScope: } private fun openFile(context: Context, attachment: Attachment): Boolean { + if (!canOpenAttachment(attachment)) { + Toast + .makeText(context, context.getString(R.string.detail_item_cannot_open_apk), Toast.LENGTH_LONG) + .show() + return true + } Log.d(TAG, "Opening file ${attachment.contentUri}") try { val contentUri = Uri.parse(attachment.contentUri) diff --git a/app/src/main/java/io/heckel/ntfy/util/Util.kt b/app/src/main/java/io/heckel/ntfy/util/Util.kt index d987e41..078bf27 100644 --- a/app/src/main/java/io/heckel/ntfy/util/Util.kt +++ b/app/src/main/java/io/heckel/ntfy/util/Util.kt @@ -25,6 +25,7 @@ import android.view.Window import android.widget.ImageView import android.widget.Toast import androidx.appcompat.app.AppCompatDelegate +import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R import io.heckel.ntfy.db.* import io.heckel.ntfy.msg.MESSAGE_ENCODING_BASE64 @@ -321,6 +322,8 @@ fun formatBytes(bytes: Long, decimals: Int = 1): String { return java.lang.String.format("%.${decimals}f %cB", value / 1024.0, ci.current()) } +const val androidAppMimeType = "application/vnd.android.package-archive" + fun mimeTypeToIconResource(mimeType: String?): Int { return if (mimeType?.startsWith("image/") == true) { R.drawable.ic_file_image_red_24dp @@ -328,7 +331,7 @@ fun mimeTypeToIconResource(mimeType: String?): Int { R.drawable.ic_file_video_orange_24dp } else if (mimeType?.startsWith("audio/") == true) { R.drawable.ic_file_audio_purple_24dp - } else if (mimeType == "application/vnd.android.package-archive") { + } else if (mimeType == androidAppMimeType) { R.drawable.ic_file_app_gray_24dp } else { R.drawable.ic_file_document_blue_24dp @@ -339,6 +342,15 @@ fun supportedImage(mimeType: String?): Boolean { return listOf("image/jpeg", "image/png").contains(mimeType) } +// Google Play doesn't allow us to install received .apk files anymore. +// See https://github.com/binwiederhier/ntfy/issues/531 +fun canOpenAttachment(attachment: Attachment?): Boolean { + if (attachment?.type == androidAppMimeType && !BuildConfig.INSTALL_PACKAGES_AVAILABLE) { + return false + } + return true +} + // Check if battery optimization is enabled, see https://stackoverflow.com/a/49098293/1440785 fun isIgnoringBatteryOptimizations(context: Context): Boolean { val powerManager = context.applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager @@ -443,6 +455,10 @@ fun String.readBitmapFromUriOrNull(context: Context): Bitmap? { } } +fun Long.nullIfZero(): Long? { + return if (this == 0L) return null else this +} + // TextWatcher that only implements the afterTextChanged method class AfterChangedTextWatcher(val afterTextChangedFn: (s: Editable?) -> Unit) : TextWatcher { override fun afterTextChanged(s: Editable?) { diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 197ea54..fc6777e 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -327,4 +327,5 @@ Относно Адрес на темата Копирано в междинната памет + Даряване 💸 \ No newline at end of file diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 646024f..d44c7f0 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -327,4 +327,5 @@ Povolit nyní WebSockets jsou doporučenou metodou připojení k vašemu serveru, která může zlepšit zvýšit výdrž baterie, ale může vyžadovat další konfiguraci v proxy serveru. Metodu připojení lze přepnout v Nastavení. Zvolit URL služby + Přispět 💸 \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 029f961..2d4f08c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -327,4 +327,5 @@ Themen-URL Über In Zwischenablage kopiert + Spenden 💸 \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 436b898..56ad002 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -327,4 +327,5 @@ Borrar la URL del servicio Cambiar a WebSockets es la forma recomendada para conectarse a su servidor, y podría mejorar la vida de la batería, pero puede requerir configuración adicional en su proxy. Esto se puede cambiar en la Configuración. Habilitar ahora + Donar 💸 \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 4e2b23c..fda4855 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -6,7 +6,7 @@ Notifikasi (prioritas min) Notifikasi (prioritas rendah) Layanan Langganan - Mendengarkan untuk notifikasi masuk + Mendengarkan notifikasi masuk Berlangganan ke topik pengiriman instan Berlangganan ke satu topik pengiriman instan Berlangganan ke dua topik pengiriman instan @@ -23,7 +23,7 @@ Notifikasi dibisukan Notifikasi dibisukan sampai %1$s Pengaturan - Laporkan sebuah bug + Laporkan kutu Baca dokumentasi Beri nilai aplikasi ⭐ Batalkan langganan @@ -327,4 +327,5 @@ Disalin ke papan klip Tentang URL Topik + Donasi 💸 \ No newline at end of file diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 8fb0788..dabff91 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -15,7 +15,7 @@ מחק/י לצמיתות ביטול התראת %1$d - התראות %1$d + %1$d התראות אתמול הוספת רישום נראה שלא נרשמת לאף נושא עדיין. @@ -39,4 +39,20 @@ מתחבר מחדש… לחצ\\י על + על מנת ליצור או להירשם אל מול נושא מסוים. לאחר מכן תקבל\\י התראות במכשירך כשתשלח\\י התראות דרך PUT או POST. הוראות מפורטות זמינות ב-ntfy.sh, ובדוקומנטציה. - + תרום 💸 + רשום לשני נושאים במשלוח מהיר + רשום לשלושה נושאים במשלוח מהיר + רשום לנושאים במשלוח מהיר + רשום לנושא אחד במשלוח מהיר + רשום לארבעה נושאים במשלוח מהיר + רשום לחמישה נושאים במשלוח מהיר + רשום לשישה נושאים במשלוח מהיר + רשום ל%1$d נושאים במשלוח מהיר + רשום לנושאים + רשום לנושא אחד + רשום לשני נושאים + רשום לשלושה נושאים + רשום לארבעה נושאים + רשום לחמישה נושאים + רשום לשישה נושאים + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 0731eb9..6d05912 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -327,4 +327,5 @@ About トピックのURL クリップボードにコピーしました + 寄付する💸 \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index bc95a63..10983c4 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -77,7 +77,7 @@ Tags: %1$s Notificação deletada Desfazer - Fazer download do arquivo + Baixar arquivo Cancelar o download Não foi possível abrir o anexo: %1$s Não foi possível abrir o anexo: O arquivo pode ter sido deletado, ou não existe app instalado que consiga abrir o arquivo. @@ -258,4 +258,74 @@ Modo claro Modo escuro Usar o padrão do sistema + Doar 💸 + Recuperação falhou %1$s + Avançado + Messagens de broadcast + Os aplicativos não podem receber notificações por broadcast + Os aplicativos já podem receber notificações por broadcast + Copiar para área de transferência + Copiar para área de transferência (censurado) + Carregar e copiar link + Carregando logs … + Logs enviados e URL copiada + Use um stream de JSON através de HTTP para se conectar ao servidor. Este método foi testado na pratica, mas pode consumir mais bateria. + ntfy %1$s (%2$s) + As notificações são entregues utilizando o Firebase. A entrega pode atrasar, mas consome menos bateria. + Aparência + Ícone de assinatura + Defina um ícone para ser exibido nas notificações + Ícone de assinatura (toque para remover) + Defina um nome de exibição personalizado para esta assinatura. Deixe em branco para o padrão (%1$s). + %1$s (padrão) + Usar configuração global + usar configuração global + Sobre + URL do tópico + Copiado para a área de transferência + Adicionar usuário + Recuperar do arquivo + Importar configurações, notificações e usuários + Restauração concluída + Registros (ate 1000 registros) para o dispositivo … + Ative o log para que seja possível compartilhar mais tarde os registros para diagnostico. + Logs de registros + Copiar/carregar logs + Copie os logs para a área de transferência ou faça o upload para nopaste.net (propriedade do autor do ntfy). Hostnames e tópicos podem ser censurados, as notificações não. + Carregar e copiar link (censurado) + Logs copiado para área de transferência + Esses tópicos/hostnames foram substituídos por nomes de frutas, então você pode compartilhar o log sem se preocupar: +\n +\n%1$s +\n +\nAs senhas são retiradas e não são listadas aqui. + Não foi possível carregar os logs: %1$s + OK + Nenhum tópico/hostname foi editado. Talvez você não tenha nenhuma assinatura\? + Limpar logs + Logs excluídos + Protocolo de conexão + Exclua os logs gravados anteriormente e comece de novo + Use WebSockets para se conectar ao servidor. Este é o método recomendado, mas pode exigir configuração adicional em seu proxy. + Stream JSON através de HTTP + Sobre + Versão + Web Sockets + Entrega instantânea + As notificações são entregues instantaneamente. Requer um serviço que roda em primeiro plano e consome mais bateria. + Copiado para área de transferência + Não foi possível salvar o ícone: %1$s + Ícone exibido nas notificações deste tópico + Nome de exibição + Você pode editar o nome de usuário/senha do usuário selecionado ou excluí-lo. + URL do serviço + Editar usuário + Você pode adicionar um usuário aqui. Todos os tópicos para o servidor fornecido usarão esse usuário. + Nome do usuário + Senha + Senha (se deixada em branco não será alterada) + Cancelar + Adicionar usuário + Deletar usuário + Salvar \ No newline at end of file diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index c9e4078..24ede8f 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -99,4 +99,28 @@ Användarnamn Lösenord Kan inte skicka meddelande: Anonym publicering är inte tillåten. + Notifikation borttagen + URL kopierad till urklipp + Kopiera notifikation + Notifikation kopierad till urklipp + Kan inte öppna URL: %1$s + Rensa alla notifikationer + Skicka testnotifikation + Kopiera + Ta bort + Ta bort permanent + Avbryt + Prenumerationsinställningar + Dela + Dela + Donera 💸 + Ångra + Öppna fil + Ta bort fil + Ladda ner fil + Avbryt nedladdning + Spara fil + Kopiera URL + nedladdning misslyckad + Prenumerationsinställningar \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index dbf2453..393ec47 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -327,4 +327,5 @@ Hakkında Konu URL\'si Panoya kopyalandı + Bağış yap 💸 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f6efd9c..c0012bc 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -327,4 +327,5 @@ 关于 话题 URL 已复制到剪贴板 + 捐赠 💸 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 77089bc..82f1d79 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -153,6 +153,7 @@ Cannot open attachment: %1$s Cannot open attachment: The file may have been deleted, or no installed app can open the file. Cannot open URL: %1$s + Apps cannot be installed anymore. Download via browser instead. See issue #531 for details. Cannot save attachment: %1$s Cannot delete attachment: %1$s Could not download attachment: %1$s diff --git a/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt b/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt index 1a367ab..830b92d 100644 --- a/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt +++ b/app/src/play/java/io/heckel/ntfy/firebase/FirebaseService.kt @@ -14,6 +14,7 @@ import io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.NotificationDispatcher import io.heckel.ntfy.msg.NotificationParser import io.heckel.ntfy.service.SubscriberService +import io.heckel.ntfy.util.nullIfZero import io.heckel.ntfy.util.toPriority import io.heckel.ntfy.util.topicShortUrl import io.heckel.ntfy.work.PollWorker @@ -94,8 +95,8 @@ class FirebaseService : FirebaseMessagingService() { val encoding = data["encoding"] val attachmentName = data["attachment_name"] ?: "attachment.bin" val attachmentType = data["attachment_type"] - val attachmentSize = data["attachment_size"]?.toLongOrNull() - val attachmentExpires = data["attachment_expires"]?.toLongOrNull() + val attachmentSize = data["attachment_size"]?.toLongOrNull()?.nullIfZero() + val attachmentExpires = data["attachment_expires"]?.toLongOrNull()?.nullIfZero() val attachmentUrl = data["attachment_url"] val truncated = (data["truncated"] ?: "") == "1" if (id == null || topic == null || message == null || timestamp == null) { diff --git a/fastlane/metadata/android/en-US/changelog/29.txt b/fastlane/metadata/android/en-US/changelog/31.txt similarity index 89% rename from fastlane/metadata/android/en-US/changelog/29.txt rename to fastlane/metadata/android/en-US/changelog/31.txt index 805d904..c807459 100644 --- a/fastlane/metadata/android/en-US/changelog/29.txt +++ b/fastlane/metadata/android/en-US/changelog/31.txt @@ -12,6 +12,8 @@ Bug fixes + maintenance: * Fix topics do not re-subscribe to Firebase after restoring from backup (#511) * Fix crashes from large images (#474, thanks to @daedric7 for reporting) * Fix notification click opens wrong subscription (#261, thanks to @SMAW for reporting) +* Fix Firebase-only "link expired" issue (#529) +* Remove "Install .apk" feature in Google Play variant due to policy change (#531) * Add donate button (no ticket) Additional translations: