flutter_foreground_task icon indicating copy to clipboard operation
flutter_foreground_task copied to clipboard

changing notification button texts for running service

Open dorjeduck opened this issue 1 year ago • 10 comments

Thanks for this great package and all the community information here.

Is it possible to change the text of the notification buttons in Android while a foreground service is running? I can't see it in the FlutterForegroundTask.updateService method. What i want is something similar to the timer notification of the standard Android Timer app, for which one button text changes between Pause and Resume when the button is pressed. Thx

dorjeduck avatar Nov 21 '23 11:11 dorjeduck

@dorjeduck It can be done—at least on Android, I don't know iOS. If you have a platform side plugin yourself, just add the following function:

private fun serverNotification(call: MethodCall, result: MethodChannel.Result) {
  val newTitle: String = call.argument<String?>("title")!!
  val newMessage: String = call.argument<String?>("message")!!
  val newButtonId: String = call.argument<String?>("buttonId")!!
  val newButtonText: String = call.argument<String?>("buttonText")!!

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val manager = getSystemService(NotificationManager::class.java)
    val builder = Notification.Builder(this, "your_channel_identifier")
    builder.setSmallIcon(your_package_identifier.R.drawable.ic_notification)
    if (newTitle.isNotEmpty())
      builder.setContentTitle(newTitle)
    if (newMessage.isNotEmpty())
      builder.setContentText(newTitle)
    if (newButtonId.isNotEmpty() && newButtonText.isNotEmpty()) {
      val buttonIntent = Intent("onNotificationButtonPressed").apply {
        putExtra("data", newButtonId)
      }
      val buttonAction = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val buttonPendingIntent = PendingIntent.getBroadcast(this, 1, buttonIntent, PendingIntent.FLAG_IMMUTABLE)
        Notification.Action.Builder(null, newButtonText, buttonPendingIntent).build()
      } else {
        val buttonPendingIntent = PendingIntent.getBroadcast(this, 1, buttonIntent, 0)
        Notification.Action.Builder(0, newButtonText, buttonPendingIntent).build()
      }
      builder.setActions(buttonAction)
    }
    manager.notify(119025, builder.build())
  }

  result.success(null)
}

Of course, you might want to modify parts. Here I only needed to send a replacement title, message or a single button but setActions() actually has a variable number of arguments. Also make sure you change the channel ID and the name of your icon as necessary. The 119025 in the last call is a completely arbitrary number, just pass it to the options when you set up your foreground task. As long as you use the same id, the system will replace the notification rather than create a new one.

FlutterForegroundTask.init(
  androidNotificationOptions: AndroidNotificationOptions(
    id: 119025,
    channelId: '...',

I contemplated creating a PR but as the current plugin works, I couldn't find an easy way to connect to the running instance and I didn't want to start a major refactoring. Our plugin author might decide whether and how it should be implemented best.

deakjahn avatar Dec 24 '23 17:12 deakjahn

Oh yes, forgot to add, it only works from API 26 while Flutter is capable of running on earlier phones. Well, that's Oreo, probably not that many around any more.

deakjahn avatar Dec 24 '23 17:12 deakjahn

I did the PR, after all. :-)

deakjahn avatar Dec 24 '23 22:12 deakjahn

thanks a lot - I can't try it right now as my laptop broke but hopefully can give you feedback once I get it fixed

dorjeduck avatar Dec 25 '23 14:12 dorjeduck

Hi. Back to flutter and the project for which i asked the question here. Thanks again for your reply deakjahn . Sorry a bit lost right now, can you help me to understand to which file/class i should add the function "serverNotification". Thanks

dorjeduck avatar Mar 03 '24 10:03 dorjeduck

@dorjeduck I added several changes to the plugin (see https://github.com/Dev-hwang/flutter_foreground_task/pull/195) and I've been using the modified version for quite some time now. I don't know if the plugin is still actively maintained or not and whether the PR will be accepted or I will need to keep my own local copy but if you want to use it, you can refer to my github repo directly: https://github.com/deakjahn/flutter_foreground_task

Basically, now that I looked back, it has three additions:

  • a notification function
  • a send message function
  • support for a callback when the engine starts, to make it possible to use platform calls from the front code

deakjahn avatar Mar 03 '24 12:03 deakjahn

thx again - i wont have the time right now to digg into your PR unfortunately which is a bit challenging for me without an example (no complain just saying) So no feedback from me for now it seems, but hopefully this functionality will be included into this project in the future. All the best

dorjeduck avatar Mar 04 '24 06:03 dorjeduck

It's up to you :-) but there's really not much need for an example. You get a new FlutterForegroundTask.notification() call that you can pass much of the same arguments as to the original call: title, text, icon, buttons.

deakjahn avatar Mar 04 '24 08:03 deakjahn

Thx for your patience :-) Gave it another try and finally I got it, works like a charm, and indeed pretty straight forward to use. The one thing which confused me is that id for AndroidNotificationOptions is an optional parameter which i never used and by that missed to understand what notificationId is about. But it should have been clear from your comments above ... Thx again for your help

dorjeduck avatar Mar 04 '24 14:03 dorjeduck

OK, nice if it works for you, too.

deakjahn avatar Mar 04 '24 22:03 deakjahn