florent37 / Flutter-AssetsAudioPlayer

Play simultaneously music/audio from assets/network/file directly from Flutter, compatible with android / ios / web / macos, displays notifications
https://pub.dartlang.org/packages/assets_audio_player
Apache License 2.0
739 stars 336 forks source link

[New Feature][iOS] Ability to change icons in notification center #196

Closed colinricardo closed 4 years ago

colinricardo commented 4 years ago

It would be good to have the ability to change the icons used in the notificationSettings.

For example, currently we can change the customPrevAction to be "rewind by 15 seconds", but we cannot change the icon itself.

florent37 commented 4 years ago

it can be possible on android, I'll add this but it'll be icons to add on android project & on AndroidManifest.xml

because the android code for notification require resources identifiers

florent37 commented 4 years ago

for ios sorry I don't think it will be possible

florent37 commented 4 years ago
  /**
         * Add an action to this notification. Actions are typically displayed by
         * the system as a button adjacent to the notification content.
         * <br>
         * Action buttons won't appear on platforms prior to Android 4.1. Action
         * buttons depend on expanded notifications, which are only available in Android 4.1
         * and later. To ensure that an action button's functionality is always available, first
         * implement the functionality in the {@link android.app.Activity} that starts when a user
         * clicks the  notification (see {@link #setContentIntent setContentIntent()}), and then
         * enhance the notification by implementing the same functionality with
         * {@link #addAction addAction()}.
         *
         * @param icon Resource ID of a drawable that represents the action.
         * @param title Text describing the action.
         * @param intent {@link android.app.PendingIntent} to be fired when the action is invoked.
         */
        public Builder addAction(int icon, CharSequence title, PendingIntent intent) {
            mActions.add(new Action(icon, title, intent));
            return this;
        }

the method only take an integer, this is why I have to put it in AndroidManifest

colinricardo commented 4 years ago

Hi Florent, thanks for the quick response.

Is this a limitation of iOS?

For example, below we can see two different types of prev/next icons:

Image from iOS (4)

Image from iOS (3)

Is it possible to specify those directly?

To clarify, I don't mean the ability to upload any icon there -- but rather, to choose from a preset list of prev/next icons.

Sorry, the original issue was unclear.

florent37 commented 4 years ago

it seems to be "native" icons named MPSkipIntervalCommandEvent

https://stackoverflow.com/questions/20591156/is-there-a-public-way-to-force-mpnowplayinginfocenter-to-show-podcast-controls

MPSkipIntervalCommand *skipBackwardIntervalCommand = [rcc skipBackwardCommand];
[skipBackwardIntervalCommand setEnabled:YES];
[skipBackwardIntervalCommand addTarget:self action:@selector(skipBackwardEvent:)];
skipBackwardIntervalCommand.preferredIntervals = @[@(42)];  // Set your own interval

MPSkipIntervalCommand *skipForwardIntervalCommand = [rcc skipForwardCommand];
skipForwardIntervalCommand.preferredIntervals = @[@(42)];  // Max 99
[skipForwardIntervalCommand setEnabled:YES];
[skipForwardIntervalCommand addTarget:self action:@selector(skipForwardEvent:)];
florent37 commented 4 years ago

I added the possibility to change the icons for android in manifest, see #197

<meta-data
            android:name="assets.audio.player.notification.icon.play"
            android:resource="@drawable/ic_music_custom"/>
        <meta-data
            android:name="assets.audio.player.notification.icon.pause"
            android:resource="@drawable/ic_music_custom"/>
        <meta-data
            android:name="assets.audio.player.notification.icon.stop"
            android:resource="@drawable/ic_music_custom"/>
        <meta-data
            android:name="assets.audio.player.notification.icon.next"
            android:resource="@drawable/ic_music_custom"/>
        <meta-data
            android:name="assets.audio.player.notification.icon.prev"
            android:resource="@drawable/ic_music_custom"/>

I published it in 2.0.2+2

florent37 commented 4 years ago

For iOS I did not touch anything, because, I don't think it's the same action

it's not setting a custom icon, it's setting a forwad/rewind action & I don't know how I can make it compatible with the flutter

maybe

settings: NotificationSettings(
    prev: NotificationActionsPrev.seek(by: 15),
    playPause: NotificationActions.playPause(),
    next: NotificationActionsNext.seek(30),
    stop: null, //to disable it
) 

and

settings: NotificationSettings(
    prev: NotificationActionsPrev.prev(),
    playPause: null, //to disable it
    next: NotificationActionsNext.next(),
    stop: NotificationActions.stop(),
) 

but on Android you'll need to add the prevSeek & nextSeek icons in AndroidManifest, containing the text

florent37 commented 4 years ago

and to override actions :

settings: NotificationSettings(
    prev: NotificationActionsPrev.prev(
           customAction: (player) {
                //action
           }
     ),
    playPause: null, //to disable it
    next: NotificationActionsNext.next(),
    stop: NotificationActions.stop(),
)
florent37 commented 4 years ago

but, you cannot have previous & seek by 15 at same time, because it's not available on ios

the other option is to separate android & ios implem

settings: NotificationSettings(
    android: AndroidNotification(
        // because you can have up to 4 actions
        action1: NotificationActionsPrev.prev(
              customAction: (player) {
                        //action
              }
        ),
        action2:  NotificationActions.playPause(),
        action3:  NotificationActionsNext.next(),
        action4:  NotificationActions.stop(),
    ),
    ios: iOSNotification(
          prev: NotificationActionsPrev.prev(
                 customAction: (player) {
                        //action
                 }
           ),
          playPause: null, //to disable it
          next: NotificationActionsNext.next(),
          stop: NotificationActions.stop(),
    )
)
florent37 commented 4 years ago

its verbose

colinricardo commented 4 years ago

Thanks for the above, I understand.

but, you cannot have previous & seek by 15 at same time, because it's not available on ios

But you can have one or the other? (either previous OR seek by 15?)

florent37 commented 4 years ago

Yes, I just have to find how to make it ''usable'' from flutter :)

sumitkakshapati commented 4 years ago

@florent37 i think we can add notification icon from notification setting in android in this way. about ios i don't have much idea. i have done that and send a merge request.

198

florent37 commented 4 years ago

can you try to rebase this and merge with what I've done

  1. if present on notifsettings, use this
  2. if no, if present from androidmanifest, use this,
  3. use default
sumitkakshapati commented 4 years ago

can you try to rebase this and merge with what I've done

  1. if present on notifsettings, use this
  2. if no, if present from androidmanifest, use this,
  3. use default

yes we can do that. i will work in it.

florent37 commented 4 years ago

thanks

I keep this ticket opened to have a refact of notification, for android & ios

florent37 commented 4 years ago

not implemented yet, but thinking of this

Same interractions on Android & ios :

settings: NotificationSettings.multiplatform(
  prev: NotificationActionsPrev.prev(),
  playPause: null, //to disable it
  next: NotificationActionsNext.next(
      customAction: (player) {
           //action
      }
  ),
  stop: NotificationActions.stop(),
)

Custom notif on platforms

settings: NotificationSettings.perPlatform(
    android: AndroidNotification(

        // because you can have up to 4 actions

        action1: NotificationActionsPrev.prev(
              customAction: (player) {
                        //action
              }
        ),
        action2:  NotificationActions.playPause(),
        action3:  NotificationActionsNext.next(),
        action4:  NotificationActions.stop(),

        //eg: custom icon (heart)

        action1:  NotificationActions.custom(
          iconBuilder: (player, currentAudio) {
            if(isFavorite(currentAudio.path)){
              return AndroidDrawable("ic_fav_full");
            } else {
              return AndroidDrawable("ic_fav_empty");
            }
          }
          customAction: (player, currentAudio, notification) {
            //action
            toggleIsFavorite(currentAudio.path);
            notification.updateIcon(); //will call iconBuilder
          }
        ),

        //eg: seek

        action1:  NotificationActionsPrev.seek(by: Duration(seconds: 10)),

    ),
    ios: iOSNotification(
          prev: NotificationActionsPrev.prev(
                 customAction: (player) {
                        //action
                 }
           ),
          playPause: null, //to disable it
          next: NotificationActionsNext.next(),
          stop: NotificationActions.stop(),

          //eg: seek in place of prev
          prev: NotificationActionsPrev.seek(by: Duration(seconds: 10)),
    )
)
florent37 commented 4 years ago

I create a new issue for this one :) to "reset" & start a new feature

florent37 commented 4 years ago

https://github.com/florent37/Flutter-AssetsAudioPlayer/issues/243