快速更新Android通知

x33g5p2x  于 2022-11-03  发布在  Android
关注(0)|答案(2)|浏览(119)

我为Android编写了简单的音频播放器。我编写了基本的功能,现在我想创建控制音频播放器的通知。我使用Android类服务和通知和RemoteViews的大小通知。这工作很好,但是,当我使用快速翻转的音轨我的通知不更新与名称音轨的文本。我为演示问题创建了简单的视频:
you-tube.com
我使用C#和Xamarin Forms,但这并不重要,因为代码与Java非常相似。

[Service]
public class PlayerService : Service, IPlayerService
{
    private const string ACTION_SHOW_PLAYER = "music.player.ACTION.SHOW_PLAYER";
    private const string ACTION_PLAY_PAUSE = "music.player.ACTION.PLAY_PAUSE";
    private const string ACTION_PLAY_PREW = "music.player.ACTION.PLAY_PREW";
    private const string ACTION_PLAY_NEXT = "music.player.ACTION.PLAY_NEXT";
    private const string ACTION_STOP_SERVICE = "music.player.ACTION.STOP_SERVICE";
    private const string ANDROID_CHANNEL_ID = "com.companyname.homeremotecontroller";
    private const int NOTIFICATION_ID = 46;

    private RemoteViews _remoteViewsBig = null;
    private RemoteViews _remoteViewsSmall = null;
    private NotificationManager _notificationManager = null;
    private NotificationCompat.Builder _builder = null;

    private static IPlayerService _instance = null;
    private static bool _isActiveBackgroundService = false;
    private static bool _isBeenStartBackgroundService= false;

    public IPlayerService GetInstance()
    {
        return _instance;
    }

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override void OnCreate()
    {
        base.OnCreate();
        _instance = this;

        MusicPlaylistModel.GetInstance().ChangeSound += () =>
        {
            UpdateSound(MusicPlaylistModel.GetInstance().CurrentSound.SoundName);
        };
        MusicPlaylistModel.GetInstance().MusicPlayer.TimeSound += (start, end) =>
        {
            // TODO: empty
        };
        MusicPlaylistModel.GetInstance().MusicPlayer.TickCurrentSound += (curr) =>
        {
            UpdateProgressSound(curr);
        };
        MusicPlaylistModel.GetInstance().PlayingStatus += (status) =>
        {
            UpdatePlayPauseStatus(status);
        };

        _notificationManager = ((NotificationManager)GetSystemService(NotificationService));
        _notificationManager.CreateNotificationChannel(new NotificationChannel(ANDROID_CHANNEL_ID, "Audio player", NotificationImportance.High));

        Intent notificationIntent = new Intent(MainActivity.Activity, typeof(MainActivity));

        _remoteViewsSmall = GetSmallContentView();
        _remoteViewsBig = GetBigContentView();

        CreateBuilderNotification();
    }

    public override void OnDestroy()
    {
        base.OnDestroy();
    }

    public void CreateBuilderNotification()
    {
        _builder = new NotificationCompat.Builder(MainActivity.Activity, ANDROID_CHANNEL_ID)
                .SetCategory(Notification.ExtraMediaSession)
                .SetCustomBigContentView(_remoteViewsBig)
                .SetCustomContentView(_remoteViewsSmall)
                .SetSmallIcon(Resource.Mipmap.icon)
                .SetOngoing(true)
                .SetSilent(true)
                .SetPriority((int)NotificationPriority.Max)
                .SetVisibility(NotificationCompat.VisibilityPublic)
                .SetAutoCancel(true)
                .SetStyle(new NotificationCompat.DecoratedCustomViewStyle());
    }

    public Notification RecreateNotification()
    {
        return _builder.Build();
    }

    private RemoteViews GetBigContentView()
    {
        RemoteViews mContentViewBig = new RemoteViews(MainActivity.Activity.PackageName, Resource.Layout.player_notify_big);
        Intent closeIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        closeIntent.SetAction(ACTION_STOP_SERVICE);
        PendingIntent pcloseIntent = PendingIntent.GetService(MainActivity.Activity, 0, closeIntent, 0);
        Intent playPauseIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        playPauseIntent.SetAction(ACTION_PLAY_PAUSE);
        PendingIntent pPlayPauseIntent = PendingIntent.GetService(MainActivity.Activity, 0, playPauseIntent, 0);
        Intent nextIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        nextIntent.SetAction(ACTION_PLAY_NEXT);
        PendingIntent pNextIntent = PendingIntent.GetService(MainActivity.Activity, 0, nextIntent, 0);
        Intent prewIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        prewIntent.SetAction(ACTION_PLAY_PREW);
        PendingIntent pPrewIntent = PendingIntent.GetService(MainActivity.Activity, 0, prewIntent, 0);

        mContentViewBig.SetOnClickPendingIntent(Resource.Id.btnWidgetPlayPauseMusicBig, pPlayPauseIntent);
        mContentViewBig.SetOnClickPendingIntent(Resource.Id.btnWidgetCloseService, pcloseIntent);
        mContentViewBig.SetOnClickPendingIntent(Resource.Id.playNextBig, pNextIntent);
        mContentViewBig.SetOnClickPendingIntent(Resource.Id.playPrevBig, pPrewIntent);

        return mContentViewBig;
    }

    private RemoteViews GetSmallContentView()
    {
        RemoteViews mContentViewSmall = new RemoteViews(MainActivity.Activity.PackageName, Resource.Layout.player_notify_small);
        Intent closeIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        closeIntent.SetAction(ACTION_STOP_SERVICE);
        PendingIntent pcloseIntent = PendingIntent.GetService(MainActivity.Activity, 0, closeIntent, 0);
        Intent playPauseIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        playPauseIntent.SetAction(ACTION_PLAY_PAUSE);
        PendingIntent pPlayPauseIntent = PendingIntent.GetService(MainActivity.Activity, 0, playPauseIntent, 0);
        Intent nextIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        nextIntent.SetAction(ACTION_PLAY_NEXT);
        PendingIntent pNextIntent = PendingIntent.GetService(MainActivity.Activity, 0, nextIntent, 0);
        Intent prewIntent = new Intent(MainActivity.Activity, typeof(PlayerService));
        prewIntent.SetAction(ACTION_PLAY_PREW);
        PendingIntent pPrewIntent = PendingIntent.GetService(MainActivity.Activity, 0, prewIntent, 0);

        mContentViewSmall.SetOnClickPendingIntent(Resource.Id.btnWidgetCloseServiceSmall, pcloseIntent);
        mContentViewSmall.SetOnClickPendingIntent(Resource.Id.btnWidgetPlayPauseMusic, pPlayPauseIntent);
        mContentViewSmall.SetOnClickPendingIntent(Resource.Id.btnWidgetPlayNext, pNextIntent);
        mContentViewSmall.SetOnClickPendingIntent(Resource.Id.btnWidgetPlayPrevious, pPrewIntent);

        return mContentViewSmall;
    }

    public void RedrawNotification()
    {
        if(!_isActiveBackgroundService)
        {
            return;
        }
        var notification = RecreateNotification();
        notification.Flags = NotificationFlags.NoClear | NotificationFlags.OngoingEvent;
        _notificationManager.Notify(NOTIFICATION_ID, notification);
        StartForeground(NOTIFICATION_ID, notification);
    }

    public void Start()
    {
        MainActivity.Activity.StartForegroundService(new Intent(MainActivity.Activity, typeof(PlayerService)));
        _isActiveBackgroundService = true;
        _isBeenStartBackgroundService = true;
    }

    public void Stop()
    {
        MainActivity.Activity.StopService(new Intent(MainActivity.Activity, typeof(PlayerService)));
        _isActiveBackgroundService = false;
    }

    public void UpdateSound(string snd_name)
    {
        _remoteViewsSmall.SetTextViewText(Resource.Id.lblWidgetCurrentMusicName, snd_name);
        _remoteViewsBig.SetTextViewText(Resource.Id.lblWidgetCurrentMusicName, snd_name);
        _builder.SetCustomBigContentView(_remoteViewsBig)
                .SetCustomContentView(_remoteViewsSmall);
        RedrawNotification();
    }

    public void UpdateProgressSound(int currProgress)
    {
        // TODO: empty
    }

    public void UpdatePlayPauseStatus(bool status)
    {
        if(status)
        {
            _remoteViewsSmall.SetImageViewResource(Resource.Id.btnWidgetPlayPauseMusic, Resource.Drawable.play_off);
            _remoteViewsBig.SetImageViewResource(Resource.Id.btnWidgetPlayPauseMusicBig, Resource.Drawable.play_off);
        }
        else
        {
            _remoteViewsSmall.SetImageViewResource(Resource.Id.btnWidgetPlayPauseMusic, Resource.Drawable.pause_off);
            _remoteViewsBig.SetImageViewResource(Resource.Id.btnWidgetPlayPauseMusicBig, Resource.Drawable.pause_off);
        }
        _builder.SetCustomBigContentView(_remoteViewsBig)
                .SetCustomContentView(_remoteViewsSmall);
        RedrawNotification();
    }

    public override StartCommandResult OnStartCommand(Intent? intent, [GeneratedEnum] StartCommandFlags flags, int startId)
    {
        if (_isBeenStartBackgroundService)
        {
            UpdateSound(MusicPlaylistModel.GetInstance().CurrentSound.SoundName);
            UpdatePlayPauseStatus(false);
            RedrawNotification();
            _isBeenStartBackgroundService = false;
        }
        string action = intent.Action;
        if (action != null)
        {
            if (action == ACTION_STOP_SERVICE)
            {
                Stop();
            }
            else
            {
                new Task(async () =>
                {
                    if (action == ACTION_PLAY_PAUSE)
                    {
                        await MusicPlaylistModel.GetInstance().Play();
                        return;
                    }
                    else if (action == ACTION_PLAY_PREW)
                    {
                        await MusicPlaylistModel.GetInstance().Prew();
                        return;
                    }
                    else if (action == ACTION_PLAY_NEXT)
                    {
                        await MusicPlaylistModel.GetInstance().Next();
                        return;
                    }
                }).Start();
            }
        }
        return StartCommandResult.Sticky;
    }
}

为了显示通知,外部代码调用Start方法,为了隐藏通知,外部代码调用Stop方法。我检查调试。应用程序成功将在方法UpdateSound中命中,其中snd_name-是正确的。但通知中的文本不正确。
怎么修?

yvt65v4c

yvt65v4c1#

UpdateSound()中,您可以调用RedrawNotification()
RedrawNotification()中,您可以调用RecreateNotification()
RecreateNotification()中,您可以调用_builder.Build()
但是你从来没有在_builder中做过任何改变。

33qvvth1

33qvvth12#

解决方案:请使用Notification.MediaStyle类。

相关问题