Improve FetchPushForegroundService's reliability (#6757)

* Improve `FetchPushForegroundService`'s reliability

- Don't use DI, we can just create the notification channel. This should speed up the creation of the service and reduce the number of `ForegroundServiceDidNotStartInTimeException` received. Also use `MainScope` instead of the app's coroutine scope.
- Move the wakelock releasing mechanism to `onDestroy` so it's always used. Previously, this would only happen when `stopService` was called, which would only happen when `stopSelf()` is called, but not when the OS or the service manager stops the service.

* Add fallback value for the notification channel title

* Replace the wrong string for the notification/channel title

---------

Co-authored-by: Benoit Marty <benoitm@element.io>
This commit is contained in:
Jorge Martin Espinosa 2026-05-12 11:40:46 +02:00 committed by GitHub
parent 4975f61eb8
commit 108498777b
22 changed files with 60 additions and 62 deletions

View file

@ -1,17 +0,0 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.push.impl.di
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesTo
import io.element.android.libraries.push.impl.push.FetchPushForegroundService
@ContributesTo(AppScope::class)
interface PushBindings {
fun inject(fetchPushForegroundService: FetchPushForegroundService)
}

View file

@ -13,17 +13,14 @@ import android.content.pm.ServiceInfo
import android.os.Build import android.os.Build
import android.os.IBinder import android.os.IBinder
import android.os.PowerManager import android.os.PowerManager
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.ServiceCompat import androidx.core.app.ServiceCompat
import dev.zacsweers.metro.Inject
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.push.impl.di.PushBindings
import io.element.android.libraries.push.impl.notifications.channels.NotificationChannels
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@ -34,6 +31,12 @@ private const val NOTIFICATION_ID = 1001
// This kind of foreground service can only last up to 3 minutes before onTimeout is called // This kind of foreground service can only last up to 3 minutes before onTimeout is called
private val wakelockTimeout = 3.minutes.inWholeMilliseconds private val wakelockTimeout = 3.minutes.inWholeMilliseconds
// The channel ID to use for the notification of the foreground service.
private const val CHANNEL_ID = "fetch_push_notification_channel"
// The tag to use for the wakelock, this is used for debugging purposes and should be unique to this service.
private const val WAKELOCK_TAG = "FetchPushService:WakeLock"
/** /**
* Foreground service used to ensure the device stays awake while we handle the pushes and schedule and run the work to fetch the notification content. * Foreground service used to ensure the device stays awake while we handle the pushes and schedule and run the work to fetch the notification content.
*/ */
@ -42,28 +45,35 @@ class FetchPushForegroundService : Service() {
return null return null
} }
@Inject lateinit var notificationChannels: NotificationChannels
@Inject @AppCoroutineScope lateinit var coroutineScope: CoroutineScope
private val wakelock: PowerManager.WakeLock by lazy { private val wakelock: PowerManager.WakeLock by lazy {
val powerManager = getSystemService(POWER_SERVICE) as PowerManager val powerManager = getSystemService(POWER_SERVICE) as PowerManager
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "FetchPushService:WakeLock").apply { powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG).apply {
setReferenceCounted(false) setReferenceCounted(false)
} }
} }
private var isOnForeground = false private var isOnForeground = false
private fun ensureNotificationChannelExists() {
NotificationManagerCompat.from(this).createNotificationChannelsCompat(
listOf(
NotificationChannelCompat.Builder(CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_LOW)
.setName(getString(CommonStrings.common_fetching_notifications_title_android).ifEmpty { "Syncing notifications…" })
.setVibrationEnabled(false)
.setSound(null, null)
.build()
)
)
}
override fun onCreate() { override fun onCreate() {
Timber.d("Creating FetchPushForegroundService") Timber.i("Creating FetchPushForegroundService to handle incoming push, acquiring wakelock for up to $wakelockTimeout ms")
ensureNotificationChannelExists()
bindings<PushBindings>().inject(this)
Timber.d("Starting FetchPushForegroundService with wakelock timeout of $wakelockTimeout ms")
// Start the foreground service as soon as possible // Start the foreground service as soon as possible
val notificationCompat = NotificationCompat.Builder(this, notificationChannels.getSilentChannelId()) val notificationCompat = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(CommonDrawables.ic_notification) .setSmallIcon(CommonDrawables.ic_notification)
.setContentTitle(getString(CommonStrings.common_android_fetching_notifications_title)) .setContentTitle(getString(CommonStrings.common_fetching_notifications_title_android).ifEmpty { "Syncing notifications…" })
.setProgress(0, 0, true) .setProgress(0, 0, true)
.setVibrate(longArrayOf(0)) .setVibrate(longArrayOf(0))
.setSound(null) .setSound(null)
@ -103,7 +113,7 @@ class FetchPushForegroundService : Service() {
// The timeout is not automatic before Android 15, so we need to schedule it ourselves // The timeout is not automatic before Android 15, so we need to schedule it ourselves
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
coroutineScope.launch { MainScope().launch {
delay(wakelockTimeout) delay(wakelockTimeout)
onTimeoutAction(calledByTheSystem = false) onTimeoutAction(calledByTheSystem = false)
} }
@ -112,13 +122,18 @@ class FetchPushForegroundService : Service() {
return START_NOT_STICKY return START_NOT_STICKY
} }
override fun stopService(intent: Intent?): Boolean { override fun onDestroy() {
if (isOnForeground) { super.onDestroy()
wakelock.release()
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
}
return super.stopService(intent) if (isOnForeground) {
Timber.i("Destroying FetchPushForegroundService, releasing wakelock and stopping foreground")
if (wakelock.isHeld) {
wakelock.release()
}
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
} else {
Timber.w("Destroying FetchPushForegroundService that was not running in foreground, this is unexpected")
}
} }
override fun onTimeout(startId: Int) { override fun onTimeout(startId: Int) {
@ -127,9 +142,9 @@ class FetchPushForegroundService : Service() {
} }
private fun onTimeoutAction(calledByTheSystem: Boolean) { private fun onTimeoutAction(calledByTheSystem: Boolean) {
Timber.d("onTimeoutAction, calledByTheSystem: $calledByTheSystem, isOnForeground: $isOnForeground") Timber.w("onTimeoutAction, calledByTheSystem: $calledByTheSystem, isOnForeground: $isOnForeground")
if (isOnForeground) { if (isOnForeground) {
Timber.d("Wakelock timeout reached, stopping FetchPushForegroundService") Timber.w("Wakelock timeout reached, stopping FetchPushForegroundService")
stopSelf() stopSelf()
} }
} }

View file

@ -198,7 +198,6 @@
<string name="common_advanced_settings">"Pokročilá nastavení"</string> <string name="common_advanced_settings">"Pokročilá nastavení"</string>
<string name="common_an_image">"obrázek"</string> <string name="common_an_image">"obrázek"</string>
<string name="common_analytics">"Analytika"</string> <string name="common_analytics">"Analytika"</string>
<string name="common_android_fetching_notifications_title">"Synchronizace oznámení…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Opustili jste místnost"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Opustili jste místnost"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Byli jste odhlášeni z relace"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Byli jste odhlášeni z relace"</string>
<string name="common_appearance">"Vzhled"</string> <string name="common_appearance">"Vzhled"</string>
@ -242,6 +241,7 @@ Důvod: %1$s."</string>
<string name="common_failed">"Selhalo"</string> <string name="common_failed">"Selhalo"</string>
<string name="common_favourite">"Oblíbené"</string> <string name="common_favourite">"Oblíbené"</string>
<string name="common_favourited">"Oblíbené"</string> <string name="common_favourited">"Oblíbené"</string>
<string name="common_fetching_notifications_title_android">"Synchronizace oznámení…"</string>
<string name="common_file">"Soubor"</string> <string name="common_file">"Soubor"</string>
<string name="common_file_deleted">"Soubor smazán"</string> <string name="common_file_deleted">"Soubor smazán"</string>
<string name="common_file_saved">"Soubor uložen"</string> <string name="common_file_saved">"Soubor uložen"</string>

View file

@ -198,7 +198,6 @@
<string name="common_advanced_settings">"Avancerede indstillinger"</string> <string name="common_advanced_settings">"Avancerede indstillinger"</string>
<string name="common_an_image">"et billede"</string> <string name="common_an_image">"et billede"</string>
<string name="common_analytics">"Analyse-værktøj"</string> <string name="common_analytics">"Analyse-værktøj"</string>
<string name="common_android_fetching_notifications_title">"Synkroniserer notifikationer…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Du forlod rummet"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Du forlod rummet"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Du blev logget ud af sessionen"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Du blev logget ud af sessionen"</string>
<string name="common_appearance">"Udseende"</string> <string name="common_appearance">"Udseende"</string>
@ -244,6 +243,7 @@
<string name="common_failed">"Mislykkedes"</string> <string name="common_failed">"Mislykkedes"</string>
<string name="common_favourite">"Favorit"</string> <string name="common_favourite">"Favorit"</string>
<string name="common_favourited">"Favoritmarkeret"</string> <string name="common_favourited">"Favoritmarkeret"</string>
<string name="common_fetching_notifications_title_android">"Synkroniserer notifikationer…"</string>
<string name="common_file">"Fil"</string> <string name="common_file">"Fil"</string>
<string name="common_file_deleted">"Fil slettet"</string> <string name="common_file_deleted">"Fil slettet"</string>
<string name="common_file_saved">"Fil gemt"</string> <string name="common_file_saved">"Fil gemt"</string>

View file

@ -192,7 +192,6 @@
<string name="common_advanced_settings">"Erweiterte Einstellungen"</string> <string name="common_advanced_settings">"Erweiterte Einstellungen"</string>
<string name="common_an_image">"ein Bild"</string> <string name="common_an_image">"ein Bild"</string>
<string name="common_analytics">"Analysedaten"</string> <string name="common_analytics">"Analysedaten"</string>
<string name="common_android_fetching_notifications_title">"Benachrichtigungen werden synchronisiert…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Du hast den Chat verlassen"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Du hast den Chat verlassen"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Du wurdest aus der Sitzung abgemeldet."</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Du wurdest aus der Sitzung abgemeldet."</string>
<string name="common_appearance">"Erscheinungsbild"</string> <string name="common_appearance">"Erscheinungsbild"</string>
@ -236,6 +235,7 @@ Grund: %1$s."</string>
<string name="common_failed">"Fehlgeschlagen"</string> <string name="common_failed">"Fehlgeschlagen"</string>
<string name="common_favourite">"Favorit"</string> <string name="common_favourite">"Favorit"</string>
<string name="common_favourited">"Favorisiert"</string> <string name="common_favourited">"Favorisiert"</string>
<string name="common_fetching_notifications_title_android">"Benachrichtigungen werden synchronisiert…"</string>
<string name="common_file">"Datei"</string> <string name="common_file">"Datei"</string>
<string name="common_file_deleted">"Datei wurde gelöscht"</string> <string name="common_file_deleted">"Datei wurde gelöscht"</string>
<string name="common_file_saved">"Datei gespeichert"</string> <string name="common_file_saved">"Datei gespeichert"</string>

View file

@ -192,7 +192,6 @@
<string name="common_advanced_settings">"Ρυθμίσεις για προχωρημένους"</string> <string name="common_advanced_settings">"Ρυθμίσεις για προχωρημένους"</string>
<string name="common_an_image">"μια εικόνα"</string> <string name="common_an_image">"μια εικόνα"</string>
<string name="common_analytics">"Στατιστικά στοιχεία"</string> <string name="common_analytics">"Στατιστικά στοιχεία"</string>
<string name="common_android_fetching_notifications_title">"Συγχρονισμός ειδοποιήσεων…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Αποχωρήσατε από την αίθουσα"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Αποχωρήσατε από την αίθουσα"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Αποσυνδεθήκατε από την περίοδο λειτουργίας"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Αποσυνδεθήκατε από την περίοδο λειτουργίας"</string>
<string name="common_appearance">"Εμφάνιση"</string> <string name="common_appearance">"Εμφάνιση"</string>
@ -236,6 +235,7 @@
<string name="common_failed">"Απέτυχε"</string> <string name="common_failed">"Απέτυχε"</string>
<string name="common_favourite">"Αγαπημένο"</string> <string name="common_favourite">"Αγαπημένο"</string>
<string name="common_favourited">"Είναι αγαπημένο"</string> <string name="common_favourited">"Είναι αγαπημένο"</string>
<string name="common_fetching_notifications_title_android">"Συγχρονισμός ειδοποιήσεων…"</string>
<string name="common_file">"Αρχείο"</string> <string name="common_file">"Αρχείο"</string>
<string name="common_file_deleted">"Το αρχείο διαγράφηκε"</string> <string name="common_file_deleted">"Το αρχείο διαγράφηκε"</string>
<string name="common_file_saved">"Το αρχείο αποθηκεύτηκε"</string> <string name="common_file_saved">"Το αρχείο αποθηκεύτηκε"</string>

View file

@ -197,7 +197,6 @@
<string name="common_advanced_settings">"Täiendavad seadistused"</string> <string name="common_advanced_settings">"Täiendavad seadistused"</string>
<string name="common_an_image">"pilt"</string> <string name="common_an_image">"pilt"</string>
<string name="common_analytics">"Analüütika"</string> <string name="common_analytics">"Analüütika"</string>
<string name="common_android_fetching_notifications_title">"Sünkroonin teavitusi…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Sina lahkusid jututoast"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Sina lahkusid jututoast"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Sa olid sessioonist väljaloginud"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Sa olid sessioonist väljaloginud"</string>
<string name="common_appearance">"Välimus"</string> <string name="common_appearance">"Välimus"</string>
@ -242,6 +241,7 @@ Põhjus: %1$s."</string>
<string name="common_failed">"Ei õnnestunud"</string> <string name="common_failed">"Ei õnnestunud"</string>
<string name="common_favourite">"Lemmik"</string> <string name="common_favourite">"Lemmik"</string>
<string name="common_favourited">"Märgitud lemmikuks"</string> <string name="common_favourited">"Märgitud lemmikuks"</string>
<string name="common_fetching_notifications_title_android">"Sünkroonin teavitusi…"</string>
<string name="common_file">"Fail"</string> <string name="common_file">"Fail"</string>
<string name="common_file_deleted">"Fail on kustutatud"</string> <string name="common_file_deleted">"Fail on kustutatud"</string>
<string name="common_file_saved">"Fail on salvestatud"</string> <string name="common_file_saved">"Fail on salvestatud"</string>

View file

@ -193,7 +193,6 @@
<string name="common_advanced_settings">"Edistyneet asetukset"</string> <string name="common_advanced_settings">"Edistyneet asetukset"</string>
<string name="common_an_image">"kuva"</string> <string name="common_an_image">"kuva"</string>
<string name="common_analytics">"Analytiikka"</string> <string name="common_analytics">"Analytiikka"</string>
<string name="common_android_fetching_notifications_title">"Synkronoidaan ilmoituksia…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Poistuit huoneesta"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Poistuit huoneesta"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Sinut kirjattiin ulos istunnosta"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Sinut kirjattiin ulos istunnosta"</string>
<string name="common_appearance">"Ulkoasu"</string> <string name="common_appearance">"Ulkoasu"</string>
@ -237,6 +236,7 @@ Syy: %1$s."</string>
<string name="common_failed">"Epäonnistui"</string> <string name="common_failed">"Epäonnistui"</string>
<string name="common_favourite">"Lisää suosikkeihin"</string> <string name="common_favourite">"Lisää suosikkeihin"</string>
<string name="common_favourited">"Lisätty suosikkeihin"</string> <string name="common_favourited">"Lisätty suosikkeihin"</string>
<string name="common_fetching_notifications_title_android">"Synkronoidaan ilmoituksia…"</string>
<string name="common_file">"Tiedosto"</string> <string name="common_file">"Tiedosto"</string>
<string name="common_file_deleted">"Tiedosto poistettu"</string> <string name="common_file_deleted">"Tiedosto poistettu"</string>
<string name="common_file_saved">"Tiedosto tallennettu"</string> <string name="common_file_saved">"Tiedosto tallennettu"</string>

View file

@ -198,7 +198,6 @@
<string name="common_advanced_settings">"Paramètres avancés"</string> <string name="common_advanced_settings">"Paramètres avancés"</string>
<string name="common_an_image">"une image"</string> <string name="common_an_image">"une image"</string>
<string name="common_analytics">"Statistiques dutilisation"</string> <string name="common_analytics">"Statistiques dutilisation"</string>
<string name="common_android_fetching_notifications_title">"Synchronisation des notifications…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Vous avez quitté le salon"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Vous avez quitté le salon"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Vous avez été déconnecté de la session"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Vous avez été déconnecté de la session"</string>
<string name="common_appearance">"Apparence"</string> <string name="common_appearance">"Apparence"</string>
@ -244,6 +243,7 @@ Raison : %1$s."</string>
<string name="common_failed">"Échec"</string> <string name="common_failed">"Échec"</string>
<string name="common_favourite">"Favori"</string> <string name="common_favourite">"Favori"</string>
<string name="common_favourited">"Ajouté aux favoris"</string> <string name="common_favourited">"Ajouté aux favoris"</string>
<string name="common_fetching_notifications_title_android">"Synchronisation des notifications…"</string>
<string name="common_file">"Fichier"</string> <string name="common_file">"Fichier"</string>
<string name="common_file_deleted">"Fichier supprimé"</string> <string name="common_file_deleted">"Fichier supprimé"</string>
<string name="common_file_saved">"Fichier enregistré"</string> <string name="common_file_saved">"Fichier enregistré"</string>

View file

@ -200,7 +200,6 @@
<string name="common_advanced_settings">"Napredne postavke"</string> <string name="common_advanced_settings">"Napredne postavke"</string>
<string name="common_an_image">"slika"</string> <string name="common_an_image">"slika"</string>
<string name="common_analytics">"Analitika"</string> <string name="common_analytics">"Analitika"</string>
<string name="common_android_fetching_notifications_title">"Sinkronizacija obavijesti…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Napustili ste sobu"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Napustili ste sobu"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Odjavljeni ste iz sesije"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Odjavljeni ste iz sesije"</string>
<string name="common_appearance">"Izgled"</string> <string name="common_appearance">"Izgled"</string>
@ -246,6 +245,7 @@ Razlog: %1$s ."</string>
<string name="common_failed">"Nije uspjelo"</string> <string name="common_failed">"Nije uspjelo"</string>
<string name="common_favourite">"Favorit"</string> <string name="common_favourite">"Favorit"</string>
<string name="common_favourited">"Označeno kao favorit"</string> <string name="common_favourited">"Označeno kao favorit"</string>
<string name="common_fetching_notifications_title_android">"Sinkronizacija obavijesti…"</string>
<string name="common_file">"Datoteka"</string> <string name="common_file">"Datoteka"</string>
<string name="common_file_deleted">"Datoteka je izbrisana"</string> <string name="common_file_deleted">"Datoteka je izbrisana"</string>
<string name="common_file_saved">"Datoteka je spremljena"</string> <string name="common_file_saved">"Datoteka je spremljena"</string>

View file

@ -199,7 +199,6 @@
<string name="common_advanced_settings">"Speciális beállítások"</string> <string name="common_advanced_settings">"Speciális beállítások"</string>
<string name="common_an_image">"egy kép"</string> <string name="common_an_image">"egy kép"</string>
<string name="common_analytics">"Elemzések"</string> <string name="common_analytics">"Elemzések"</string>
<string name="common_android_fetching_notifications_title">"Értesítések szinkronizálása…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Elhagyta a szobát"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Elhagyta a szobát"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Ki lett jelentkeztetve a munkamenetből"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Ki lett jelentkeztetve a munkamenetből"</string>
<string name="common_appearance">"Megjelenítés"</string> <string name="common_appearance">"Megjelenítés"</string>
@ -245,6 +244,7 @@ Ok: %1$s."</string>
<string name="common_failed">"Sikertelen"</string> <string name="common_failed">"Sikertelen"</string>
<string name="common_favourite">"Kedvenc"</string> <string name="common_favourite">"Kedvenc"</string>
<string name="common_favourited">"Kedvencnek jelölve"</string> <string name="common_favourited">"Kedvencnek jelölve"</string>
<string name="common_fetching_notifications_title_android">"Értesítések szinkronizálása…"</string>
<string name="common_file">"Fájl"</string> <string name="common_file">"Fájl"</string>
<string name="common_file_deleted">"Fájl törölve"</string> <string name="common_file_deleted">"Fájl törölve"</string>
<string name="common_file_saved">"A fájl mentve"</string> <string name="common_file_saved">"A fájl mentve"</string>

View file

@ -199,7 +199,6 @@
<string name="common_advanced_settings">"Impostazioni avanzate"</string> <string name="common_advanced_settings">"Impostazioni avanzate"</string>
<string name="common_an_image">"un\'immagine"</string> <string name="common_an_image">"un\'immagine"</string>
<string name="common_analytics">"Statistiche di utilizzo"</string> <string name="common_analytics">"Statistiche di utilizzo"</string>
<string name="common_android_fetching_notifications_title">"Sincronizzazione delle notifiche…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Hai lasciato la stanza"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Hai lasciato la stanza"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Sei stato disconnesso dalla sessione"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Sei stato disconnesso dalla sessione"</string>
<string name="common_appearance">"Aspetto"</string> <string name="common_appearance">"Aspetto"</string>
@ -245,6 +244,7 @@ Motivo:. %1$s"</string>
<string name="common_failed">"Fallito"</string> <string name="common_failed">"Fallito"</string>
<string name="common_favourite">"Preferiti"</string> <string name="common_favourite">"Preferiti"</string>
<string name="common_favourited">"Preferita"</string> <string name="common_favourited">"Preferita"</string>
<string name="common_fetching_notifications_title_android">"Sincronizzazione delle notifiche…"</string>
<string name="common_file">"File"</string> <string name="common_file">"File"</string>
<string name="common_file_deleted">"File eliminato"</string> <string name="common_file_deleted">"File eliminato"</string>
<string name="common_file_saved">"File salvato"</string> <string name="common_file_saved">"File salvato"</string>

View file

@ -197,7 +197,6 @@
<string name="common_advanced_settings">"高度な設定"</string> <string name="common_advanced_settings">"高度な設定"</string>
<string name="common_an_image">"画像"</string> <string name="common_an_image">"画像"</string>
<string name="common_analytics">"分析"</string> <string name="common_analytics">"分析"</string>
<string name="common_android_fetching_notifications_title">"通知を同期中…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"あなたがルームを退出"</string> <string name="common_android_shortcuts_remove_reason_left_room">"あなたがルームを退出"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"セッションからログアウトされました"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"セッションからログアウトされました"</string>
<string name="common_appearance">"テーマ"</string> <string name="common_appearance">"テーマ"</string>
@ -243,6 +242,7 @@
<string name="common_failed">"失敗"</string> <string name="common_failed">"失敗"</string>
<string name="common_favourite">"お気に入り"</string> <string name="common_favourite">"お気に入り"</string>
<string name="common_favourited">"お気に入り"</string> <string name="common_favourited">"お気に入り"</string>
<string name="common_fetching_notifications_title_android">"通知を同期中…"</string>
<string name="common_file">"ファイル"</string> <string name="common_file">"ファイル"</string>
<string name="common_file_deleted">"ファイルを削除しました"</string> <string name="common_file_deleted">"ファイルを削除しました"</string>
<string name="common_file_saved">"ファイルを保存しました"</string> <string name="common_file_saved">"ファイルを保存しました"</string>

View file

@ -190,7 +190,6 @@
<string name="common_advanced_settings">"고급 설정"</string> <string name="common_advanced_settings">"고급 설정"</string>
<string name="common_an_image">"이미지"</string> <string name="common_an_image">"이미지"</string>
<string name="common_analytics">"통계"</string> <string name="common_analytics">"통계"</string>
<string name="common_android_fetching_notifications_title">"알림 동기화 중…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"방을 떠남"</string> <string name="common_android_shortcuts_remove_reason_left_room">"방을 떠남"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"세션에서 로그아웃되었습니다."</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"세션에서 로그아웃되었습니다."</string>
<string name="common_appearance">"외관"</string> <string name="common_appearance">"외관"</string>
@ -234,6 +233,7 @@
<string name="common_failed">"실패"</string> <string name="common_failed">"실패"</string>
<string name="common_favourite">"즐겨찾기"</string> <string name="common_favourite">"즐겨찾기"</string>
<string name="common_favourited">"즐겨찾기 됨"</string> <string name="common_favourited">"즐겨찾기 됨"</string>
<string name="common_fetching_notifications_title_android">"알림 동기화 중…"</string>
<string name="common_file">"파일"</string> <string name="common_file">"파일"</string>
<string name="common_file_deleted">"파일 삭제됨"</string> <string name="common_file_deleted">"파일 삭제됨"</string>
<string name="common_file_saved">"파일 저장됨"</string> <string name="common_file_saved">"파일 저장됨"</string>

View file

@ -201,7 +201,6 @@
<string name="common_advanced_settings">"Ustawienia zaawansowane"</string> <string name="common_advanced_settings">"Ustawienia zaawansowane"</string>
<string name="common_an_image">"obraz"</string> <string name="common_an_image">"obraz"</string>
<string name="common_analytics">"Dane analityczne"</string> <string name="common_analytics">"Dane analityczne"</string>
<string name="common_android_fetching_notifications_title">"Synchronizuję powiadomienia…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Opuściłeś pokój"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Opuściłeś pokój"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Zostałeś wylogowany z sesji"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Zostałeś wylogowany z sesji"</string>
<string name="common_appearance">"Wygląd"</string> <string name="common_appearance">"Wygląd"</string>
@ -247,6 +246,7 @@ Powód: %1$s."</string>
<string name="common_failed">"Niepowodzenie"</string> <string name="common_failed">"Niepowodzenie"</string>
<string name="common_favourite">"Ulubione"</string> <string name="common_favourite">"Ulubione"</string>
<string name="common_favourited">"Ulubione"</string> <string name="common_favourited">"Ulubione"</string>
<string name="common_fetching_notifications_title_android">"Synchronizuję powiadomienia…"</string>
<string name="common_file">"Plik"</string> <string name="common_file">"Plik"</string>
<string name="common_file_deleted">"Plik usunięty"</string> <string name="common_file_deleted">"Plik usunięty"</string>
<string name="common_file_saved">"Plik zapisany"</string> <string name="common_file_saved">"Plik zapisany"</string>

View file

@ -195,7 +195,6 @@
<string name="common_advanced_settings">"Расширенные настройки"</string> <string name="common_advanced_settings">"Расширенные настройки"</string>
<string name="common_an_image">"изображение"</string> <string name="common_an_image">"изображение"</string>
<string name="common_analytics">"Аналитика"</string> <string name="common_analytics">"Аналитика"</string>
<string name="common_android_fetching_notifications_title">"Синхронизация уведомлений…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Вы покинули комнату"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Вы покинули комнату"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Вы вышли из сессии"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Вы вышли из сессии"</string>
<string name="common_appearance">"Внешний вид"</string> <string name="common_appearance">"Внешний вид"</string>
@ -239,6 +238,7 @@
<string name="common_failed">"Ошибка"</string> <string name="common_failed">"Ошибка"</string>
<string name="common_favourite">"Избранное"</string> <string name="common_favourite">"Избранное"</string>
<string name="common_favourited">"Избранное"</string> <string name="common_favourited">"Избранное"</string>
<string name="common_fetching_notifications_title_android">"Синхронизация уведомлений…"</string>
<string name="common_file">"Файл"</string> <string name="common_file">"Файл"</string>
<string name="common_file_deleted">"Файл удалён"</string> <string name="common_file_deleted">"Файл удалён"</string>
<string name="common_file_saved">"Файл сохранен"</string> <string name="common_file_saved">"Файл сохранен"</string>

View file

@ -201,7 +201,6 @@
<string name="common_advanced_settings">"Додаткові налаштування"</string> <string name="common_advanced_settings">"Додаткові налаштування"</string>
<string name="common_an_image">"зображення"</string> <string name="common_an_image">"зображення"</string>
<string name="common_analytics">"Аналітика"</string> <string name="common_analytics">"Аналітика"</string>
<string name="common_android_fetching_notifications_title">"Синхронізація сповіщень…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Ви вийшли з кімнати"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Ви вийшли з кімнати"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Ви вийшли з сеансу"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Ви вийшли з сеансу"</string>
<string name="common_appearance">"Тема"</string> <string name="common_appearance">"Тема"</string>
@ -247,6 +246,7 @@
<string name="common_failed">"Помилка"</string> <string name="common_failed">"Помилка"</string>
<string name="common_favourite">"Обране"</string> <string name="common_favourite">"Обране"</string>
<string name="common_favourited">"Обране"</string> <string name="common_favourited">"Обране"</string>
<string name="common_fetching_notifications_title_android">"Синхронізація сповіщень…"</string>
<string name="common_file">"Файл"</string> <string name="common_file">"Файл"</string>
<string name="common_file_deleted">"Файл видалено"</string> <string name="common_file_deleted">"Файл видалено"</string>
<string name="common_file_saved">"Файл збережено"</string> <string name="common_file_saved">"Файл збережено"</string>

View file

@ -193,7 +193,6 @@
<string name="common_advanced_settings">"Kengaytirilgan sozlamalar"</string> <string name="common_advanced_settings">"Kengaytirilgan sozlamalar"</string>
<string name="common_an_image">"rasm"</string> <string name="common_an_image">"rasm"</string>
<string name="common_analytics">"Analitika"</string> <string name="common_analytics">"Analitika"</string>
<string name="common_android_fetching_notifications_title">"Bildirishnomalar sinxronlanmoqda…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Siz xonani tark etdingiz"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Siz xonani tark etdingiz"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Siz sessiyadan chiqdingiz"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Siz sessiyadan chiqdingiz"</string>
<string name="common_appearance">"Ko\'rinish"</string> <string name="common_appearance">"Ko\'rinish"</string>
@ -237,6 +236,7 @@ Sababi:%1$s."</string>
<string name="common_failed">"Xatolikka uchradi"</string> <string name="common_failed">"Xatolikka uchradi"</string>
<string name="common_favourite">"Sevimli"</string> <string name="common_favourite">"Sevimli"</string>
<string name="common_favourited">"Sevimli"</string> <string name="common_favourited">"Sevimli"</string>
<string name="common_fetching_notifications_title_android">"Bildirishnomalar sinxronlanmoqda…"</string>
<string name="common_file">"Fayl"</string> <string name="common_file">"Fayl"</string>
<string name="common_file_deleted">"Fayl o\'chirildi"</string> <string name="common_file_deleted">"Fayl o\'chirildi"</string>
<string name="common_file_saved">"Fayl saqlandi"</string> <string name="common_file_saved">"Fayl saqlandi"</string>

View file

@ -191,7 +191,6 @@
<string name="common_advanced_settings">"Cài đặt nâng cao"</string> <string name="common_advanced_settings">"Cài đặt nâng cao"</string>
<string name="common_an_image">"một hình ảnh"</string> <string name="common_an_image">"một hình ảnh"</string>
<string name="common_analytics">"Phân tích"</string> <string name="common_analytics">"Phân tích"</string>
<string name="common_android_fetching_notifications_title">"Đang đồng bộ thông báo…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"Bạn rời phòng"</string> <string name="common_android_shortcuts_remove_reason_left_room">"Bạn rời phòng"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"Bạn đã bị đăng xuất"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"Bạn đã bị đăng xuất"</string>
<string name="common_appearance">"Giao diện"</string> <string name="common_appearance">"Giao diện"</string>
@ -235,6 +234,7 @@ Lý do: %1$s ."</string>
<string name="common_failed">"Thất bại"</string> <string name="common_failed">"Thất bại"</string>
<string name="common_favourite">"Yêu thích"</string> <string name="common_favourite">"Yêu thích"</string>
<string name="common_favourited">"Được yêu thích"</string> <string name="common_favourited">"Được yêu thích"</string>
<string name="common_fetching_notifications_title_android">"Đang đồng bộ thông báo…"</string>
<string name="common_file">"Tập tin"</string> <string name="common_file">"Tập tin"</string>
<string name="common_file_deleted">"Tệp đã bị xóa"</string> <string name="common_file_deleted">"Tệp đã bị xóa"</string>
<string name="common_file_saved">"Tệp đã được lưu"</string> <string name="common_file_saved">"Tệp đã được lưu"</string>

View file

@ -191,7 +191,6 @@
<string name="common_advanced_settings">"進階設定"</string> <string name="common_advanced_settings">"進階設定"</string>
<string name="common_an_image">"影像"</string> <string name="common_an_image">"影像"</string>
<string name="common_analytics">"分析"</string> <string name="common_analytics">"分析"</string>
<string name="common_android_fetching_notifications_title">"正在同步通知……"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"您離開聊天室"</string> <string name="common_android_shortcuts_remove_reason_left_room">"您離開聊天室"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"您已登出工作階段"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"您已登出工作階段"</string>
<string name="common_appearance">"外觀"</string> <string name="common_appearance">"外觀"</string>
@ -235,6 +234,7 @@
<string name="common_failed">"失敗"</string> <string name="common_failed">"失敗"</string>
<string name="common_favourite">"我的最愛"</string> <string name="common_favourite">"我的最愛"</string>
<string name="common_favourited">"我的最愛"</string> <string name="common_favourited">"我的最愛"</string>
<string name="common_fetching_notifications_title_android">"正在同步通知……"</string>
<string name="common_file">"檔案"</string> <string name="common_file">"檔案"</string>
<string name="common_file_deleted">"檔案已刪除"</string> <string name="common_file_deleted">"檔案已刪除"</string>
<string name="common_file_saved">"檔案已儲存"</string> <string name="common_file_saved">"檔案已儲存"</string>

View file

@ -196,7 +196,6 @@
<string name="common_advanced_settings">"高级设置"</string> <string name="common_advanced_settings">"高级设置"</string>
<string name="common_an_image">"一张图片"</string> <string name="common_an_image">"一张图片"</string>
<string name="common_analytics">"分析"</string> <string name="common_analytics">"分析"</string>
<string name="common_android_fetching_notifications_title">"正在同步通知…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"你离开了房间"</string> <string name="common_android_shortcuts_remove_reason_left_room">"你离开了房间"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"你已注销会话"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"你已注销会话"</string>
<string name="common_appearance">"外观"</string> <string name="common_appearance">"外观"</string>
@ -242,6 +241,7 @@
<string name="common_failed">"失败"</string> <string name="common_failed">"失败"</string>
<string name="common_favourite">"收藏"</string> <string name="common_favourite">"收藏"</string>
<string name="common_favourited">"已收藏"</string> <string name="common_favourited">"已收藏"</string>
<string name="common_fetching_notifications_title_android">"正在同步通知…"</string>
<string name="common_file">"文件"</string> <string name="common_file">"文件"</string>
<string name="common_file_deleted">"文件已删除"</string> <string name="common_file_deleted">"文件已删除"</string>
<string name="common_file_saved">"文件已保存"</string> <string name="common_file_saved">"文件已保存"</string>

View file

@ -199,7 +199,6 @@
<string name="common_advanced_settings">"Advanced settings"</string> <string name="common_advanced_settings">"Advanced settings"</string>
<string name="common_an_image">"an image"</string> <string name="common_an_image">"an image"</string>
<string name="common_analytics">"Analytics"</string> <string name="common_analytics">"Analytics"</string>
<string name="common_android_fetching_notifications_title">"Syncing notifications…"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"You left the room"</string> <string name="common_android_shortcuts_remove_reason_left_room">"You left the room"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"You were logged out of the session"</string> <string name="common_android_shortcuts_remove_reason_session_logged_out">"You were logged out of the session"</string>
<string name="common_appearance">"Appearance"</string> <string name="common_appearance">"Appearance"</string>
@ -245,6 +244,7 @@ Reason: %1$s."</string>
<string name="common_failed">"Failed"</string> <string name="common_failed">"Failed"</string>
<string name="common_favourite">"Favourite"</string> <string name="common_favourite">"Favourite"</string>
<string name="common_favourited">"Favourited"</string> <string name="common_favourited">"Favourited"</string>
<string name="common_fetching_notifications_title_android">"Syncing notifications…"</string>
<string name="common_file">"File"</string> <string name="common_file">"File"</string>
<string name="common_file_deleted">"File deleted"</string> <string name="common_file_deleted">"File deleted"</string>
<string name="common_file_saved">"File saved"</string> <string name="common_file_saved">"File saved"</string>