Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9e74394 authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

Merge branch '3720-fg_src_hide_channel' into 'main'

feat:3720: hide foreground service notification programatically

See merge request !25
parents 7e57557c ec7b774c
Loading
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:sharedUserId="android.uid.sytem"
    xmlns:tools="http://schemas.android.com/tools">
    xmlns:tools="http://schemas.android.com/tools">


    <!-- Permissions -->
    <!-- Permissions -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <!-- For instant delivery foregrounds service -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/> <!-- For instant delivery foregrounds service on SDK >= 34 -->
    <uses-permission android:name="android.permission.WAKE_LOCK"/> <!-- To keep foreground service awake; soon not needed anymore -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <!-- To restart service on reboot -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <!-- To restart service on reboot -->
    <uses-permission android:name="android.permission.VIBRATE"/> <!-- Incoming notifications should be able to vibrate the phone -->
    <uses-permission android:name="android.permission.VIBRATE"/> <!-- Incoming notifications should be able to vibrate the phone -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/> <!-- Only required on SDK <= 28 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/> <!-- Only required on SDK <= 28 -->
+25 −42
Original line number Original line Diff line number Diff line
package io.heckel.ntfy.service
package io.heckel.ntfy.service


import android.app.*
import android.app.AlarmManager
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.BroadcastReceiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
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 android.os.SystemClock
import android.os.SystemClock
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import foundation.e.notificationsreceiver.bridges.androidinterfaces.NotificationChannelHider
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.app.Application
@@ -18,8 +24,6 @@ import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationDispatcher
import io.heckel.ntfy.msg.NotificationDispatcher
import io.heckel.ntfy.ui.Colors
import io.heckel.ntfy.ui.MainActivity
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.topicUrl
import io.heckel.ntfy.util.topicUrl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineScope
@@ -88,6 +92,19 @@ class SubscriberService : Service() {


        Log.init(this) // Init logs in all entry points
        Log.init(this) // Init logs in all entry points
        Log.d(TAG, "Subscriber service has been created")
        Log.d(TAG, "Subscriber service has been created")

        notificationManager = createNotificationChannel()
        serviceNotification = createNotification()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            startForeground(
                NOTIFICATION_SERVICE_ID,
                serviceNotification!!,
                ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
            )
        } else {
            startForeground(NOTIFICATION_SERVICE_ID, serviceNotification)
        }
    }
    }


    override fun onDestroy() {
    override fun onDestroy() {
@@ -206,34 +223,6 @@ class SubscriberService : Service() {
            val connection = connections.remove(connectionId)
            val connection = connections.remove(connectionId)
            connection?.close()
            connection?.close()
        }
        }

        // Update foreground service notification popup
        if (connections.size > 0) {
            val title = getString(R.string.channel_subscriber_notification_title)
            val text = if (BuildConfig.FIREBASE_AVAILABLE) {
                when (instantSubscriptions.size) {
                    1 -> getString(R.string.channel_subscriber_notification_instant_text_one)
                    2 -> getString(R.string.channel_subscriber_notification_instant_text_two)
                    3 -> getString(R.string.channel_subscriber_notification_instant_text_three)
                    4 -> getString(R.string.channel_subscriber_notification_instant_text_four)
                    5 -> getString(R.string.channel_subscriber_notification_instant_text_five)
                    6 -> getString(R.string.channel_subscriber_notification_instant_text_six)
                    else -> getString(R.string.channel_subscriber_notification_instant_text_more, instantSubscriptions.size)
                }
            } else {
                when (instantSubscriptions.size) {
                    1 -> getString(R.string.channel_subscriber_notification_noinstant_text_one)
                    2 -> getString(R.string.channel_subscriber_notification_noinstant_text_two)
                    3 -> getString(R.string.channel_subscriber_notification_noinstant_text_three)
                    4 -> getString(R.string.channel_subscriber_notification_noinstant_text_four)
                    5 -> getString(R.string.channel_subscriber_notification_noinstant_text_five)
                    6 -> getString(R.string.channel_subscriber_notification_noinstant_text_six)
                    else -> getString(R.string.channel_subscriber_notification_noinstant_text_more, instantSubscriptions.size)
                }
            }
            serviceNotification = createNotification(title, text)
            notificationManager?.notify(NOTIFICATION_SERVICE_ID, serviceNotification)
        }
    }
    }


    private fun onStateChanged(subscriptionIds: Collection<Long>, state: ConnectionState) {
    private fun onStateChanged(subscriptionIds: Collection<Long>, state: ConnectionState) {
@@ -269,24 +258,18 @@ class SubscriberService : Service() {
                it
                it
            }
            }
            notificationManager.createNotificationChannel(channel)
            notificationManager.createNotificationChannel(channel)
            NotificationChannelHider(this, GlobalScope).hideChannel(NOTIFICATION_CHANNEL_ID)
            return notificationManager
            return notificationManager
        }
        }
        return null
        return null
    }
    }


    private fun createNotification(title: String, text: String): Notification {
    private fun createNotification(): Notification {
        val pendingIntent: PendingIntent = Intent(this, MainActivity::class.java).let { notificationIntent ->
            PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
        }
        return NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
        return NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notification_instant)
            .setSmallIcon(foundation.e.notificationsreceiver.R.drawable.ic_unified_push)
            .setColor(ContextCompat.getColor(this, Colors.notificationIcon(this)))
            .setContentTitle(getString(foundation.e.notificationsreceiver.R.string.foreground_service_notification_title))
            .setContentTitle(title)
            .setContentText(text)
            .setContentIntent(pendingIntent)
            .setSound(null)
            .setSound(null)
            .setShowWhen(false) // Don't show date/time
            .setShowWhen(false) // Don't show date/time
            .setOngoing(true) // Starting SDK 33 / Android 13, foreground notifications can be swiped away
            .setGroup(NOTIFICATION_GROUP_ID) // Do not group with other notifications
            .setGroup(NOTIFICATION_GROUP_ID) // Do not group with other notifications
            .build()
            .build()
    }
    }
+1 −1
Original line number Original line Diff line number Diff line
@@ -55,7 +55,7 @@ class SubscriberServiceManager(private val context: Context) {
                Log.d(TAG, "ServiceStartWorker: Starting foreground service with action $action (work ID: ${id})")
                Log.d(TAG, "ServiceStartWorker: Starting foreground service with action $action (work ID: ${id})")
                Intent(context, SubscriberService::class.java).also {
                Intent(context, SubscriberService::class.java).also {
                    it.action = action.name
                    it.action = action.name
                    context.startService(it)
                    ContextCompat.startForegroundService(context, it)
                }
                }
            }
            }
            return Result.success()
            return Result.success()
+0 −26
Original line number Original line Diff line number Diff line
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="50dp"
    android:height="50dp"
    android:viewportWidth="50"
    android:viewportHeight="50">
  <path
      android:pathData="M7.8398,6.35C4.2598,6.35 1.1932,9.1672 1.1932,12.7486L1.1932,12.7512L1.2283,40.6182L0.3292,47.2529L12.5553,44.0051L35.9384,44.0051L36.5848,39.4849L11.8923,39.4849L5.6808,41.3618L5.7444,40.9954L5.7097,12.7486C5.7097,11.7821 6.5805,10.866 7.8398,10.866L42.9488,10.866L42.9519,10.866C44.2097,10.8673 45.0794,11.7828 45.0794,12.7486L45.0794,25.7395L49.5954,25.7395L49.5954,12.7481C49.5954,9.1677 46.5305,6.3517 42.9519,6.35L42.9488,6.35L7.8398,6.35zM49.5954,31.4735C45.6685,38.326 43.7215,41.7259 42.4176,44.0051L42.9488,44.0051C46.5288,44.0051 49.5954,41.1842 49.5954,37.6029L49.5954,31.4735z"
      android:strokeWidth="2.84985"
      android:fillColor="#FFFFFFFF"
      android:strokeColor="#00000000"/>
  <path
      android:pathData="m11.5278,32.0849l0,-3.346l7.0363,-3.721q0.3397,-0.1732 0.6551,-0.2596 0.3397,-0.1153 0.6066,-0.1732 0.2912,-0.0288 0.5823,-0.0576l0,-0.2308q-0.2912,-0.0288 -0.5823,-0.1153 -0.2669,-0.0576 -0.6066,-0.1443 -0.3154,-0.1153 -0.6551,-0.2884l-7.0363,-3.721l0,-3.3749l10.8699,5.9132l0,3.6056z"
      android:strokeWidth="0.525121"
      android:fillColor="#FFFFFFFF"
      android:strokeColor="#00000000"/>
  <path
      android:pathData="m10.9661,15.6112l0,4.8516l7.3742,3.9002c0.0157,0.0077 0.0305,0.0128 0.0461,0.0204 -0.0157,0.0077 -0.0305,0.0128 -0.0461,0.0204l-7.3742,3.9002l0,4.8267l0.7961,-0.4333 11.1995,-6.0969l0,-4.463zM12.0931,17.6933 L21.8346,22.9981l0,2.7446l-9.7414,5.2999l0,-1.8679l6.6912,-3.5416 0.0084,-0.0051c0.1961,-0.0992 0.3826,-0.1724 0.5531,-0.2191l0.0127,0l0.0167,-0.0051c0.2034,-0.0691 0.3777,-0.1209 0.5279,-0.1545l1.0684,-0.1046l0,-1.4644l-0.5154,-0.0497c-0.1632,-0.0153 -0.3288,-0.0505 -0.4944,-0.0997l-0.0167,-0.0051 -0.0167,-0.0051c-0.1632,-0.0352 -0.3552,-0.0811 -0.5656,-0.1344 -0.1802,-0.0668 -0.3706,-0.1479 -0.5698,-0.2492l-0.0084,-0.0051 -6.6912,-3.5416z"
      android:strokeWidth="0.525121"
      android:fillColor="#FFFFFFFF"
      android:strokeColor="#00000000"/>
  <path
      android:pathData="m41.6796,15.3498c-4.1394,7.2567 -7.8235,13.7146 -10.2159,17.9374h8.5829l-1.8531,12.962c1.2024,-2.1043 3.8969,-6.8095 10.2878,-17.9601h-8.6543z"
      android:strokeWidth="1"
      android:fillColor="#FFFFFFFF"
      android:strokeColor="#00000000"/>
</vector>
+0 −6
Original line number Original line Diff line number Diff line
@@ -5,11 +5,6 @@
    <string name="channel_notifications_high_name">Hoog prioriteit</string>
    <string name="channel_notifications_high_name">Hoog prioriteit</string>
    <string name="channel_notifications_max_name">Hoogste prioriteit</string>
    <string name="channel_notifications_max_name">Hoogste prioriteit</string>
    <string name="channel_notifications_group_default_name">Verstek</string>
    <string name="channel_notifications_group_default_name">Verstek</string>
    <string name="channel_subscriber_notification_title">Luister na inkomende kennisgewings</string>
    <string name="channel_subscriber_notification_instant_text">Geskryf vir onmiddellike aflewering onderwerpe</string>
    <string name="channel_subscriber_notification_instant_text_one">Geskryf vir een onderwerp vir onmiddellike aflewering</string>
    <string name="channel_subscriber_notification_instant_text_three">Geskryf vir drie onderwerpe vir onmiddellike aflewering</string>
    <string name="channel_subscriber_notification_instant_text_four">Geskryf vir vier onderwerpe vir onmiddellike aflewering</string>
    <string name="settings_advanced_export_logs_entry_copy_original">Kopieer na knipbord</string>
    <string name="settings_advanced_export_logs_entry_copy_original">Kopieer na knipbord</string>
    <string name="settings_about_header">Oor</string>
    <string name="settings_about_header">Oor</string>
    <string name="settings_advanced_export_logs_scrub_dialog_button_ok">OK</string>
    <string name="settings_advanced_export_logs_scrub_dialog_button_ok">OK</string>
@@ -25,7 +20,6 @@
    <string name="user_dialog_title_edit">Wysig gebruiker</string>
    <string name="user_dialog_title_edit">Wysig gebruiker</string>
    <string name="user_dialog_description_add">Jy kan hier \'n gebruiker byvoeg. Alle onderwerpe vir die gegewe bediener sal hierdie gebruiker gebruik.</string>
    <string name="user_dialog_description_add">Jy kan hier \'n gebruiker byvoeg. Alle onderwerpe vir die gegewe bediener sal hierdie gebruiker gebruik.</string>
    <string name="user_dialog_description_edit">Jy kan die gebruikersnaam/wagwoord vir die gekose gebruiker wysig, of dit verwyder.</string>
    <string name="user_dialog_description_edit">Jy kan die gebruikersnaam/wagwoord vir die gekose gebruiker wysig, of dit verwyder.</string>
    <string name="channel_subscriber_notification_instant_text_two">Geskryf vir twee onderwerpe vir onmiddellike aflewering</string>
    <string name="user_dialog_password_hint_edit">Wagwoord (onveranderd indien leeg gelaat)</string>
    <string name="user_dialog_password_hint_edit">Wagwoord (onveranderd indien leeg gelaat)</string>
    <string name="channel_subscriber_service_name">Subskripsiediens</string>
    <string name="channel_subscriber_service_name">Subskripsiediens</string>
    <string name="user_dialog_username_hint">Gebruikersnaam</string>
    <string name="user_dialog_username_hint">Gebruikersnaam</string>
Loading