@@ -19,14 +19,12 @@ import com.pravera.flutter_foreground_task.FlutterForegroundTaskLifecycleListene
1919import com.pravera.flutter_foreground_task.RequestCode
2020import com.pravera.flutter_foreground_task.models.*
2121import com.pravera.flutter_foreground_task.utils.ForegroundServiceUtils
22- import com.pravera.flutter_foreground_task.utils.PluginUtils
2322import kotlinx.coroutines.*
2423import kotlinx.coroutines.flow.MutableStateFlow
2524import kotlinx.coroutines.flow.asStateFlow
2625import kotlinx.coroutines.flow.update
2726import java.util.*
2827
29-
3028/* *
3129 * A service class for implementing foreground service.
3230 *
@@ -37,31 +35,52 @@ class ForegroundService : Service() {
3735 companion object {
3836 private val TAG = ForegroundService ::class .java.simpleName
3937
40- private const val ACTION_RECEIVE_DATA = " onReceiveData"
41- private const val ACTION_NOTIFICATION_BUTTON_PRESSED = " onNotificationButtonPressed"
4238 private const val ACTION_NOTIFICATION_PRESSED = " onNotificationPressed"
4339 private const val ACTION_NOTIFICATION_DISMISSED = " onNotificationDismissed"
44- private const val INTENT_DATA_FIELD_NAME = " data"
40+ private const val ACTION_NOTIFICATION_BUTTON_PRESSED = " onNotificationButtonPressed"
41+ private const val ACTION_RECEIVE_DATA = " onReceiveData"
42+ private const val INTENT_DATA_NAME = " intentData"
4543
4644 private val _isRunningServiceState = MutableStateFlow (false )
4745 val isRunningServiceState = _isRunningServiceState .asStateFlow()
4846
49- private var foregroundTask : ForegroundTask ? = null
47+ private var task : ForegroundTask ? = null
5048 private var taskLifecycleListeners = ForegroundTaskLifecycleListeners ()
5149
52- fun sendData (data : Any? ) {
53- if (isRunningServiceState.value) {
54- foregroundTask?.invokeMethod(ACTION_RECEIVE_DATA , data)
55- }
56- }
57-
5850 fun addTaskLifecycleListener (listener : FlutterForegroundTaskLifecycleListener ) {
5951 taskLifecycleListeners.addListener(listener)
6052 }
6153
6254 fun removeTaskLifecycleListener (listener : FlutterForegroundTaskLifecycleListener ) {
6355 taskLifecycleListeners.removeListener(listener)
6456 }
57+
58+ fun handleNotificationContentIntent (intent : Intent ? ) {
59+ if (intent == null ) return
60+
61+ try {
62+ // Check if the given intent is a LaunchIntent.
63+ val isLaunchIntent = (intent.action == Intent .ACTION_MAIN ) &&
64+ intent.categories.contains(Intent .CATEGORY_LAUNCHER )
65+ if (! isLaunchIntent) {
66+ // Log.d(TAG, "not LaunchIntent")
67+ return
68+ }
69+
70+ val data = intent.getStringExtra(INTENT_DATA_NAME )
71+ if (data == ACTION_NOTIFICATION_PRESSED ) {
72+ task?.invokeMethod(data, null )
73+ }
74+ } catch (e: Exception ) {
75+ Log .e(TAG , e.message, e)
76+ }
77+ }
78+
79+ fun sendData (data : Any? ) {
80+ if (isRunningServiceState.value) {
81+ task?.invokeMethod(ACTION_RECEIVE_DATA , data)
82+ }
83+ }
6584 }
6685
6786 private lateinit var foregroundServiceStatus: ForegroundServiceStatus
@@ -80,22 +99,20 @@ class ForegroundService : Service() {
8099 // A broadcast receiver that handles intents that occur in the foreground service.
81100 private var broadcastReceiver = object : BroadcastReceiver () {
82101 override fun onReceive (context : Context ? , intent : Intent ? ) {
83- try {
84- // No intent ??
85- if (intent == null ) {
86- throw Exception (" Intent is null." )
87- }
102+ if (intent == null ) return
88103
104+ try {
89105 // This intent has not sent from the current package.
90106 val iPackageName = intent.`package`
91107 val cPackageName = packageName
92108 if (iPackageName != cPackageName) {
93- throw Exception (" This intent has not sent from the current package. ($iPackageName != $cPackageName )" )
109+ Log .d(TAG , " This intent has not sent from the current package. ($iPackageName != $cPackageName )" )
110+ return
94111 }
95112
96113 val action = intent.action ? : return
97- val data = intent.getStringExtra(INTENT_DATA_FIELD_NAME )
98- foregroundTask ?.invokeMethod(action, data)
114+ val data = intent.getStringExtra(INTENT_DATA_NAME )
115+ task ?.invokeMethod(action, data)
99116 } catch (e: Exception ) {
100117 Log .e(TAG , e.message, e)
101118 }
@@ -284,43 +301,40 @@ class ForegroundService : Service() {
284301 }
285302
286303 private fun createNotification (): Notification {
287- // notification
288- val channelId = notificationOptions.channelId
289-
290304 // notification icon
291305 val icon = notificationContent.icon
292306 val iconResId = getIconResId(icon)
293307 val iconBackgroundColor = icon?.backgroundColorRgb?.let (::getRgbColor)
294308
295309 // notification intent
296- val pendingIntent = getPendingIntent ()
297- val deletePendingIntent = getDeletePendingIntent ()
310+ val contentIntent = getContentIntent ()
311+ val deleteIntent = getDeleteIntent ()
298312
299- // notification action
300- var needsUpdateButtons = false
313+ // notification actions
314+ var needsRebuildButtons = false
301315 val prevButtons = prevNotificationContent?.buttons
302316 val currButtons = notificationContent.buttons
303317 if (prevButtons != null ) {
304318 if (prevButtons.size != currButtons.size) {
305- needsUpdateButtons = true
319+ needsRebuildButtons = true
306320 } else {
307321 for (i in currButtons.indices) {
308322 if (prevButtons[i] != currButtons[i]) {
309- needsUpdateButtons = true
323+ needsRebuildButtons = true
310324 break
311325 }
312326 }
313327 }
314328 } else {
315- needsUpdateButtons = true
329+ needsRebuildButtons = true
316330 }
317331
318332 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
319- val builder = Notification .Builder (this , channelId)
333+ val builder = Notification .Builder (this , notificationOptions. channelId)
320334 builder.setOngoing(true )
321335 builder.setShowWhen(notificationOptions.showWhen)
322336 builder.setSmallIcon(iconResId)
323- builder.setContentIntent(pendingIntent )
337+ builder.setContentIntent(contentIntent )
324338 builder.setContentTitle(notificationContent.title)
325339 builder.setContentText(notificationContent.text)
326340 builder.style = Notification .BigTextStyle ()
@@ -333,21 +347,21 @@ class ForegroundService : Service() {
333347 builder.setForegroundServiceBehavior(Notification .FOREGROUND_SERVICE_IMMEDIATE )
334348 }
335349 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .UPSIDE_DOWN_CAKE ) {
336- builder.setDeleteIntent(deletePendingIntent )
350+ builder.setDeleteIntent(deleteIntent )
337351 }
338352
339- val actions = buildNotificationActions(notificationContent.buttons, needsUpdateButtons )
353+ val actions = buildNotificationActions(currButtons, needsRebuildButtons )
340354 for (action in actions) {
341355 builder.addAction(action)
342356 }
343357
344358 return builder.build()
345359 } else {
346- val builder = NotificationCompat .Builder (this , channelId)
360+ val builder = NotificationCompat .Builder (this , notificationOptions. channelId)
347361 builder.setOngoing(true )
348362 builder.setShowWhen(notificationOptions.showWhen)
349363 builder.setSmallIcon(iconResId)
350- builder.setContentIntent(pendingIntent )
364+ builder.setContentIntent(contentIntent )
351365 builder.setContentTitle(notificationContent.title)
352366 builder.setContentText(notificationContent.text)
353367 builder.setStyle(NotificationCompat .BigTextStyle ().bigText(notificationContent.text))
@@ -364,7 +378,7 @@ class ForegroundService : Service() {
364378 }
365379 builder.priority = notificationOptions.priority
366380
367- val actions = buildNotificationCompatActions(notificationContent.buttons, needsUpdateButtons )
381+ val actions = buildNotificationCompatActions(currButtons, needsRebuildButtons )
368382 for (action in actions) {
369383 builder.addAction(action)
370384 }
@@ -427,7 +441,7 @@ class ForegroundService : Service() {
427441 private fun createForegroundTask () {
428442 destroyForegroundTask()
429443
430- foregroundTask = ForegroundTask (
444+ task = ForegroundTask (
431445 context = this ,
432446 serviceStatus = foregroundServiceStatus,
433447 taskData = foregroundTaskData,
@@ -437,12 +451,12 @@ class ForegroundService : Service() {
437451 }
438452
439453 private fun updateForegroundTask () {
440- foregroundTask ?.update(taskEventAction = foregroundTaskOptions.eventAction)
454+ task ?.update(taskEventAction = foregroundTaskOptions.eventAction)
441455 }
442456
443457 private fun destroyForegroundTask () {
444- foregroundTask ?.destroy()
445- foregroundTask = null
458+ task ?.destroy()
459+ task = null
446460 }
447461
448462 private fun getIconResId (icon : NotificationIcon ? ): Int {
@@ -469,27 +483,32 @@ class ForegroundService : Service() {
469483 }
470484 }
471485
472- private fun getPendingIntent (): PendingIntent {
473- return if (Build .VERSION .SDK_INT < Build .VERSION_CODES .Q || PluginUtils .canDrawOverlays(applicationContext)) {
474- val pIntent = Intent (ACTION_NOTIFICATION_PRESSED ).apply {
475- setPackage(packageName)
476- }
477- PendingIntent .getBroadcast(
478- this , RequestCode .NOTIFICATION_PRESSED_BROADCAST , pIntent, PendingIntent .FLAG_IMMUTABLE )
479- } else {
480- val pm = applicationContext.packageManager
481- val lIntent = pm.getLaunchIntentForPackage(applicationContext.packageName)
482- PendingIntent .getActivity(
483- this , RequestCode .NOTIFICATION_PRESSED , lIntent, PendingIntent .FLAG_IMMUTABLE )
486+ private fun getContentIntent (): PendingIntent {
487+ val packageManager = applicationContext.packageManager
488+ val packageName = applicationContext.packageName
489+ val intent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
490+ putExtra(INTENT_DATA_NAME , ACTION_NOTIFICATION_PRESSED )
491+ }
492+
493+ var flags = PendingIntent .FLAG_UPDATE_CURRENT
494+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .S ) {
495+ flags = flags or PendingIntent .FLAG_IMMUTABLE
484496 }
497+
498+ return PendingIntent .getActivity(this , RequestCode .NOTIFICATION_PRESSED , intent, flags)
485499 }
486500
487- private fun getDeletePendingIntent (): PendingIntent {
488- val dIntent = Intent (ACTION_NOTIFICATION_DISMISSED ).apply {
501+ private fun getDeleteIntent (): PendingIntent {
502+ val intent = Intent (ACTION_NOTIFICATION_DISMISSED ).apply {
489503 setPackage(packageName)
490504 }
491- return PendingIntent .getBroadcast(
492- this , RequestCode .NOTIFICATION_DISMISSED_BROADCAST , dIntent, PendingIntent .FLAG_IMMUTABLE )
505+
506+ var flags = PendingIntent .FLAG_UPDATE_CURRENT
507+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .S ) {
508+ flags = flags or PendingIntent .FLAG_IMMUTABLE
509+ }
510+
511+ return PendingIntent .getBroadcast(this , RequestCode .NOTIFICATION_DISMISSED , intent, flags)
493512 }
494513
495514 private fun getRgbColor (rgb : String ): Int? {
@@ -513,16 +532,16 @@ class ForegroundService : Service() {
513532
514533 private fun buildNotificationActions (
515534 buttons : List <NotificationButton >,
516- needsUpdate : Boolean = false
535+ needsRebuild : Boolean = false
517536 ): List <Notification .Action > {
518537 val actions = mutableListOf<Notification .Action >()
519538 for (i in buttons.indices) {
520539 val intent = Intent (ACTION_NOTIFICATION_BUTTON_PRESSED ).apply {
521540 setPackage(packageName)
522- putExtra(INTENT_DATA_FIELD_NAME , buttons[i].id)
541+ putExtra(INTENT_DATA_NAME , buttons[i].id)
523542 }
524543 var flags = PendingIntent .FLAG_IMMUTABLE
525- if (needsUpdate ) {
544+ if (needsRebuild ) {
526545 flags = flags or PendingIntent .FLAG_CANCEL_CURRENT
527546 }
528547 val textColor = buttons[i].textColorRgb?.let (::getRgbColor)
@@ -542,16 +561,16 @@ class ForegroundService : Service() {
542561
543562 private fun buildNotificationCompatActions (
544563 buttons : List <NotificationButton >,
545- needsUpdate : Boolean = false
564+ needsRebuild : Boolean = false
546565 ): List <NotificationCompat .Action > {
547566 val actions = mutableListOf<NotificationCompat .Action >()
548567 for (i in buttons.indices) {
549568 val intent = Intent (ACTION_NOTIFICATION_BUTTON_PRESSED ).apply {
550569 setPackage(packageName)
551- putExtra(INTENT_DATA_FIELD_NAME , buttons[i].id)
570+ putExtra(INTENT_DATA_NAME , buttons[i].id)
552571 }
553572 var flags = PendingIntent .FLAG_IMMUTABLE
554- if (needsUpdate ) {
573+ if (needsRebuild ) {
555574 flags = flags or PendingIntent .FLAG_CANCEL_CURRENT
556575 }
557576 val textColor = buttons[i].textColorRgb?.let (::getRgbColor)
0 commit comments