diff --git a/app/src/main/java/io/bartek/service/ForegroundNotificationFactory.kt b/app/src/main/java/io/bartek/service/ForegroundNotificationFactory.kt new file mode 100644 index 0000000..6107904 --- /dev/null +++ b/app/src/main/java/io/bartek/service/ForegroundNotificationFactory.kt @@ -0,0 +1,69 @@ +package io.bartek.service + +import android.annotation.SuppressLint +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import io.bartek.MainActivity +import io.bartek.R + +class ForegroundNotificationFactory(private val context: Context) { + private val oreo: Boolean + get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + + fun createForegroundNotification(port: Int): Notification { + createNotificationChannel() + + val pendingIntent = createPendingIntent() + + return buildNotification(port, pendingIntent) + } + + @Suppress("DEPRECATION") + private fun buildNotification(port: Int, pendingIntent: PendingIntent?) = + provideNotificationBuilder() + .setContentTitle(context.resources.getString(R.string.service_notification_title)) + .setContentText(context.resources.getString(R.string.service_notification_text, port)) + .setContentIntent(pendingIntent) + .setSmallIcon(R.drawable.ic_foreground_service) + .setTicker(context.getString(R.string.service_notification_text)) + .setPriority(Notification.PRIORITY_HIGH) // for under android 26 compatibility + .build() + + @SuppressLint("NewApi") + private fun createNotificationChannel() { + if (oreo) { + val manager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val channel = NotificationChannel( + NOTIFICATION_CHANNEL_ID, + context.resources.getString(R.string.service_notification_category_name), + NotificationManager.IMPORTANCE_HIGH + ).let { + it.description = + context.resources.getString(R.string.service_notification_category_description) + it + } + manager.createNotificationChannel(channel) + } + } + + private fun createPendingIntent() = + Intent(context, MainActivity::class.java).let { notificationIntent -> + PendingIntent.getActivity(context, 0, notificationIntent, 0) + } + + @Suppress("DEPRECATION") + @SuppressLint("NewApi") + private fun provideNotificationBuilder() = + if (oreo) Notification.Builder(context, NOTIFICATION_CHANNEL_ID) + else Notification.Builder(context) + + companion object { + private const val NOTIFICATION_CHANNEL_ID = "TTSService.NOTIFICATION_CHANNEL" + } +} \ No newline at end of file diff --git a/app/src/main/java/io/bartek/service/ForegroundService.kt b/app/src/main/java/io/bartek/service/ForegroundService.kt index 5437814..52af31e 100644 --- a/app/src/main/java/io/bartek/service/ForegroundService.kt +++ b/app/src/main/java/io/bartek/service/ForegroundService.kt @@ -1,15 +1,11 @@ package io.bartek.service -import android.app.* +import android.app.Service import android.content.Context import android.content.Intent import android.content.SharedPreferences -import android.graphics.Color -import android.os.Build import android.os.PowerManager import androidx.preference.PreferenceManager -import io.bartek.MainActivity -import io.bartek.R import io.bartek.preference.PreferenceKey import io.bartek.web.TTSServer @@ -21,50 +17,12 @@ class ForegroundService : Service() { private var ttsServer: TTSServer? = null private val port: Int get() = preferences.getInt(PreferenceKey.PORT, 8080) + private val notificationFactory = ForegroundNotificationFactory(this) override fun onCreate() { super.onCreate() preferences = PreferenceManager.getDefaultSharedPreferences(this) - startForeground(1, createNotification()) - } - - private fun createNotification(): Notification { - // depending on the Android API that we're dealing with we will have - // to use a specific method to create the notification - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager; - val channel = NotificationChannel( - NOTIFICATION_CHANNEL_ID, - resources.getString(R.string.service_notification_category_name), - NotificationManager.IMPORTANCE_HIGH - ).let { - it.description = resources.getString(R.string.service_notification_category_description) - it.enableLights(true) - it.lightColor = Color.RED - it.enableVibration(true) - it.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400) - it - } - notificationManager.createNotificationChannel(channel) - } - - val pendingIntent: PendingIntent = Intent(this, MainActivity::class.java).let { notificationIntent -> - PendingIntent.getActivity(this, 0, notificationIntent, 0) - } - - val builder: Notification.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) Notification.Builder( - this, - NOTIFICATION_CHANNEL_ID - ) else Notification.Builder(this) - - return builder - .setContentTitle(resources.getString(R.string.service_notification_title)) - .setContentText(resources.getString(R.string.service_notification_text, port)) - .setContentIntent(pendingIntent) - .setSmallIcon(R.drawable.ic_foreground_service) - .setTicker("Ticker text") - .setPriority(Notification.PRIORITY_HIGH) // for under android 26 compatibility - .build() + startForeground(1, notificationFactory.createForegroundNotification(port)) } override fun onBind(intent: Intent) = null @@ -116,7 +74,7 @@ class ForegroundService : Service() { // to check whether the service is already running // than to place it as a static field var state = ServiceState.STOPPED - private const val NOTIFICATION_CHANNEL_ID = "TTSService.NOTIFICATION_CHANNEL" + private const val WAKELOCK_TAG = "ForegroundService::lock" const val CHANGE_STATE = "io.bartek.service.CHANGE_STATE" const val STATE = "STATE"