Overhaul the notification system and add notification channels.

pull/71/head
Tom Hacohen 5 years ago
parent 64f8c5e1d2
commit 705df2a536

@ -24,7 +24,7 @@ public class AcraConfiguration {
builder.getPluginConfigurationBuilder(NotificationConfigurationBuilder.class)
.setResTitle(R.string.crash_title)
.setResText(R.string.crash_message)
.setChannelName("crash-notification")
.setResChannelName(R.string.notification_channel_crash_reports)
.setSendOnClick(true)
.setEnabled(true);

@ -33,6 +33,7 @@ import com.etesync.syncadapter.resource.LocalCalendar
import com.etesync.syncadapter.ui.AccountsActivity
import com.etesync.syncadapter.utils.HintManager
import com.etesync.syncadapter.utils.LanguageUtils
import com.etesync.syncadapter.utils.NotificationUtils
import io.requery.Persistable
import io.requery.android.sqlite.DatabaseSource
import io.requery.meta.EntityModel
@ -74,6 +75,8 @@ class App : Application() {
StrictMode.enableDefaults()
initPrefVersion()
NotificationUtils.createChannels(this)
appName = getString(R.string.app_name)
accountType = getString(R.string.account_type)
addressBookAccountType = getString(R.string.account_type_address_book)

@ -21,9 +21,9 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.syncadapter.SyncNotification
import com.etesync.syncadapter.R
import com.etesync.syncadapter.ui.AppSettingsActivity
import com.etesync.syncadapter.utils.NotificationUtils
import org.apache.commons.lang3.time.DateFormatUtils
import java.io.File
import java.io.IOException
@ -73,11 +73,10 @@ object Logger : SharedPreferences.OnSharedPreferenceChangeListener {
val nm = NotificationManagerCompat.from(context)
// log to external file according to preferences
if (logToFile) {
val builder = NotificationCompat.Builder(context)
val builder = NotificationUtils.newBuilder(context, NotificationUtils.CHANNEL_DEBUG)
builder.setSmallIcon(R.drawable.ic_sd_storage_light)
.setLargeIcon(App.getLauncherBitmap(context))
.setContentTitle(context.getString(R.string.logging_davdroid_file_logging))
.setChannelId(SyncNotification.CHANNEL_ID)
val logDir = debugDir(context) ?: return
val logFile = File(logDir,

@ -28,6 +28,7 @@ import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel
import com.etesync.syncadapter.ui.PermissionsActivity
import com.etesync.syncadapter.utils.NotificationUtils
import okhttp3.HttpUrl
import java.util.*
import java.util.logging.Level
@ -59,7 +60,7 @@ abstract class SyncAdapterService : Service() {
val intent = Intent(context, PermissionsActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val notify = NotificationCompat.Builder(context)
val notify = NotificationUtils.newBuilder(context, NotificationUtils.CHANNEL_SYNC_ERRORS)
.setSmallIcon(R.drawable.ic_error_light)
.setLargeIcon(App.getLauncherBitmap(context))
.setContentTitle(context.getString(R.string.sync_error_permissions))

@ -1,21 +1,17 @@
package com.etesync.syncadapter.syncadapter
import android.app.Activity
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.database.sqlite.SQLiteException
import android.net.Uri
import android.os.Build
import android.os.Bundle
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.Exceptions
@ -23,6 +19,7 @@ import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.ui.AccountSettingsActivity
import com.etesync.syncadapter.ui.DebugInfoActivity
import com.etesync.syncadapter.ui.WebViewActivity
import com.etesync.syncadapter.utils.NotificationUtils
import java.util.logging.Level
class SyncNotification(internal val context: Context, internal val notificationTag: String, internal val notificationId: Int) {
@ -79,12 +76,16 @@ class SyncNotification(internal val context: Context, internal val notificationT
@JvmOverloads
fun notify(title: String, content: String, bigText: String?, intent: Intent, _icon: Int = -1) {
var icon = _icon
createNotificationChannel()
val builder = NotificationCompat.Builder(context)
val category = if (throwable == null)
NotificationCompat.CATEGORY_STATUS
else
NotificationCompat.CATEGORY_ERROR
val category: String;
val channel: String;
if (throwable == null) {
category = NotificationCompat.CATEGORY_STATUS
channel = NotificationUtils.CHANNEL_SYNC_STATUS
} else {
category = NotificationCompat.CATEGORY_ERROR
channel = NotificationUtils.CHANNEL_SYNC_ERRORS
}
val builder = NotificationUtils.newBuilder(context, channel)
if (icon == -1) {
//Check if error was configured
if (throwable == null) {
@ -94,10 +95,8 @@ class SyncNotification(internal val context: Context, internal val notificationT
}
}
builder.setLargeIcon(App.getLauncherBitmap(context))
.setContentTitle(title)
builder .setContentTitle(title)
.setContentText(content)
.setChannelId(CHANNEL_ID)
.setAutoCancel(true)
.setCategory(category)
.setSmallIcon(icon)
@ -143,18 +142,4 @@ class SyncNotification(internal val context: Context, internal val notificationT
finish()
}
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = context.getString(R.string.notification_channel_name)
val channel = NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW)
val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager!!.createNotificationChannel(channel)
}
}
companion object {
val CHANNEL_ID = "EteSync_default"
}
}

@ -0,0 +1,78 @@
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package com.etesync.syncadapter.utils
import android.annotation.TargetApi
import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import com.etesync.syncadapter.App
import com.etesync.syncadapter.R
object NotificationUtils {
// notification IDs
const val NOTIFY_EXTERNAL_FILE_LOGGING = 1
const val NOTIFY_REFRESH_COLLECTIONS = 2
const val NOTIFY_SYNC_ERROR = 10
const val NOTIFY_INVALID_RESOURCE = 11
const val NOTIFY_OPENTASKS = 20
const val NOTIFY_PERMISSIONS = 21
const val NOTIFY_LICENSE = 100
// notification channels
const val CHANNEL_GENERAL = "general"
const val CHANNEL_DEBUG = "debug"
private const val CHANNEL_SYNC = "sync"
const val CHANNEL_SYNC_ERRORS = "syncProblems"
const val CHANNEL_SYNC_WARNINGS = "syncWarnings"
const val CHANNEL_SYNC_STATUS = "syncStatus"
fun createChannels(context: Context) {
@TargetApi(Build.VERSION_CODES.O)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
nm.createNotificationChannelGroup(NotificationChannelGroup(CHANNEL_SYNC, context.getString(R.string.notification_channel_sync)))
nm.createNotificationChannels(listOf(
NotificationChannel(CHANNEL_DEBUG, context.getString(R.string.notification_channel_debugging), NotificationManager.IMPORTANCE_HIGH),
NotificationChannel(CHANNEL_GENERAL, context.getString(R.string.notification_channel_general), NotificationManager.IMPORTANCE_DEFAULT),
NotificationChannel(CHANNEL_SYNC_ERRORS, context.getString(R.string.notification_channel_sync_errors), NotificationManager.IMPORTANCE_DEFAULT).apply {
description = context.getString(R.string.notification_channel_sync_errors_desc)
group = CHANNEL_SYNC
},
NotificationChannel(CHANNEL_SYNC_WARNINGS, context.getString(R.string.notification_channel_sync_warnings), NotificationManager.IMPORTANCE_LOW).apply {
description = context.getString(R.string.notification_channel_sync_warnings_desc)
group = CHANNEL_SYNC
},
NotificationChannel(CHANNEL_SYNC_STATUS, context.getString(R.string.notification_channel_sync_status), NotificationManager.IMPORTANCE_LOW).apply {
description = context.getString(R.string.notification_channel_sync_status_desc)
group = CHANNEL_SYNC
}
))
}
}
fun newBuilder(context: Context, channel: String): NotificationCompat.Builder {
val builder = NotificationCompat.Builder(context, channel)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
builder.setLargeIcon(App.getLauncherBitmap(context))
return builder
}
}

@ -21,6 +21,17 @@
<string name="please_wait">Please wait …</string>
<string name="send">Send</string>
<string name="notification_channel_crash_reports">Crash Reports</string>
<string name="notification_channel_debugging">Debugging</string>
<string name="notification_channel_general">Other important messages</string>
<string name="notification_channel_sync">Synchronization</string>
<string name="notification_channel_sync_errors">Synchronization errors</string>
<string name="notification_channel_sync_errors_desc">Important errors which stop synchronization like unexpected server replies</string>
<string name="notification_channel_sync_warnings">Synchronization warnings</string>
<string name="notification_channel_sync_warnings_desc">Non-fatal synchronization problems like dismissed changes of read-only collections</string>
<string name="notification_channel_sync_status">Status messages</string>
<string name="notification_channel_sync_status_desc">Informational status messages like the sync change summary</string>
<!-- Crash -->
<string name="crash_title">EteSync has crashed!</string>
<string name="crash_message">Please send stack trace to developers.</string>

Loading…
Cancel
Save