Notify about foreground service errors rather than crashing
Change-Id: I30043d02a4756b9310d1382a1cda015364a235a1
This commit is contained in:
parent
11a1a2072c
commit
419aff08d1
@ -241,4 +241,10 @@
|
|||||||
|
|
||||||
<string name="settings_integrations_scalar_warning">⚠️ This setting by default (unless overridden by your homeserver\'s configuration) enables access to \"scalar\", Element\'s integration manager which is unfortunately proprietary, i.e. its source code is not open and can not be checked by the public or the SchildiChat developers.</string>
|
<string name="settings_integrations_scalar_warning">⚠️ This setting by default (unless overridden by your homeserver\'s configuration) enables access to \"scalar\", Element\'s integration manager which is unfortunately proprietary, i.e. its source code is not open and can not be checked by the public or the SchildiChat developers.</string>
|
||||||
|
|
||||||
|
<string name="notification_channel_app_errors">Application errors</string>
|
||||||
|
<string name="notification_sync_service_failed_title">Cannot sync notifications</string>
|
||||||
|
<string name="notification_sync_service_failed_summary">Consider setting up UnifiedPush and disabling battery restrictions for SchildiChat in your system settings.</string>
|
||||||
|
<string name="notification_foreground_service_failed_title">Failed to start foreground service</string>
|
||||||
|
<string name="notification_foreground_service_failed_summary">You may need to exempt SchildiChat from battery restrictions in your system settings.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ package im.vector.app.fdroid.service
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import im.vector.app.core.extensions.startForegroundCompat
|
||||||
import im.vector.app.core.services.VectorAndroidService
|
import im.vector.app.core.services.VectorAndroidService
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
import im.vector.lib.strings.CommonStrings
|
import im.vector.lib.strings.CommonStrings
|
||||||
@ -27,7 +28,7 @@ class GuardAndroidService : VectorAndroidService() {
|
|||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
val notificationSubtitleRes = CommonStrings.notification_listening_for_notifications
|
val notificationSubtitleRes = CommonStrings.notification_listening_for_notifications
|
||||||
val notification = notificationUtils.buildForegroundServiceNotification(notificationSubtitleRes, false)
|
val notification = notificationUtils.buildForegroundServiceNotification(notificationSubtitleRes, false)
|
||||||
startForeground(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE, notification)
|
startForegroundCompat(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE, notification, errorNotificationTitle = getString(CommonStrings.notification_sync_service_failed_title), errorNotificationSummary = getString(CommonStrings.notification_sync_service_failed_summary))
|
||||||
return START_STICKY
|
return START_STICKY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,12 +7,59 @@
|
|||||||
|
|
||||||
package im.vector.app.core.extensions
|
package im.vector.app.core.extensions
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.ForegroundServiceStartNotAllowedException
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.ServiceInfo
|
import android.content.pm.ServiceInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
|
import im.vector.lib.strings.CommonStrings
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
/** SC wrapper around [startForegroundCompatUpstream] which catches [ForegroundServiceStartNotAllowedException].
|
||||||
|
* Come on Element, don't you care about these crashes spamming your rageshake inbox from FDroid users?
|
||||||
|
* */
|
||||||
fun Service.startForegroundCompat(
|
fun Service.startForegroundCompat(
|
||||||
|
id: Int,
|
||||||
|
notification: Notification,
|
||||||
|
provideForegroundServiceType: (() -> Int)? = null,
|
||||||
|
errorNotificationTitle: String = getString(CommonStrings.notification_foreground_service_failed_title),
|
||||||
|
errorNotificationSummary: String = getString(CommonStrings.notification_foreground_service_failed_summary),
|
||||||
|
) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
try {
|
||||||
|
startForegroundCompatUpstream(id, notification, provideForegroundServiceType)
|
||||||
|
Timber.tag("SchildiService").d("Started foreground service $id successfully on >= S")
|
||||||
|
} catch (e: ForegroundServiceStartNotAllowedException) {
|
||||||
|
Timber.tag("SchildiService").e(e, "Failed to start foreground service")
|
||||||
|
val notificationManager = NotificationManagerCompat.from(this)
|
||||||
|
val errorNotification = NotificationCompat.Builder(this, NotificationUtils.SC_APP_ERRORS_CHANNEL_ID)
|
||||||
|
.setSmallIcon(R.drawable.ic_status_bar_sc)
|
||||||
|
.setContentTitle(errorNotificationTitle)
|
||||||
|
.setContentText(errorNotificationSummary)
|
||||||
|
.setColor(ThemeUtils.getColor(this, android.R.attr.colorPrimary))
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
||||||
|
.build()
|
||||||
|
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Timber.tag("SchildiService").w("Not allowed to notify.")
|
||||||
|
} else {
|
||||||
|
notificationManager.notify("FAILED_FG_SERVICE_TAG", id, errorNotification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
startForegroundCompatUpstream(id, notification, provideForegroundServiceType)
|
||||||
|
Timber.tag("SchildiService").d("Started foreground service $id successfully on < S")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Service.startForegroundCompatUpstream(
|
||||||
id: Int,
|
id: Int,
|
||||||
notification: Notification,
|
notification: Notification,
|
||||||
provideForegroundServiceType: (() -> Int)? = null
|
provideForegroundServiceType: (() -> Int)? = null
|
||||||
|
|||||||
@ -101,6 +101,8 @@ class NotificationUtils @Inject constructor(
|
|||||||
const val SILENT_NOTIFICATION_CHANNEL_ID = "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID_V2"
|
const val SILENT_NOTIFICATION_CHANNEL_ID = "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID_V2"
|
||||||
private const val CALL_NOTIFICATION_CHANNEL_ID = "CALL_NOTIFICATION_CHANNEL_ID_V2"
|
private const val CALL_NOTIFICATION_CHANNEL_ID = "CALL_NOTIFICATION_CHANNEL_ID_V2"
|
||||||
|
|
||||||
|
const val SC_APP_ERRORS_CHANNEL_ID = "SC_APP_ERRORS_CHANNEL_ID"
|
||||||
|
|
||||||
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O)
|
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O)
|
||||||
fun supportNotificationChannels() = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
fun supportNotificationChannels() = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||||
|
|
||||||
@ -208,6 +210,20 @@ class NotificationUtils @Inject constructor(
|
|||||||
enableLights(true)
|
enableLights(true)
|
||||||
lightColor = accentColor
|
lightColor = accentColor
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// SC
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(
|
||||||
|
SC_APP_ERRORS_CHANNEL_ID,
|
||||||
|
stringProvider.getString(CommonStrings.notification_channel_app_errors).ifEmpty { "Application errors" },
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT
|
||||||
|
)
|
||||||
|
.apply {
|
||||||
|
description = stringProvider.getString(CommonStrings.notification_channel_app_errors)
|
||||||
|
setSound(null, null)
|
||||||
|
enableLights(false)
|
||||||
|
lightColor = accentColor
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getChannel(channelId: String): NotificationChannel? {
|
fun getChannel(channelId: String): NotificationChannel? {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user