使用Android前台服务为MediaPlayer创建通知

4

这里是问题:

我目前正在开发一款应用程序,必须提供以下功能:

一个无线电播放器(来自url的AAC实时流媒体) 和一个播客播放器(来自url的MP3流媒体)

该应用程序必须能够在后台运行(Android服务),并通过通知栏(Android前台服务)向用户展示持久通知

(每个问题只涉及一个问题,所以在此我将询问关于通知的问题)

由于我有几个用于管理播放器的类,因此我认为创建一个通知的通用类是一个好主意。这是我想创建的视图:

enter image description here .

这是我现在的通知类:

public class StreamingNotification extends NotificationCompat {
    /**
     * PRIVATE ATTRIBUTES
     */
    // log
    private static final String         TAG             = StreamingNotification.class.getSimpleName();
    // notification
    private NotificationManager         _notificationManager;
    private NotificationCompat.Builder  _builder        = null;
    private Notification                _notification;
    // data
    public static final int             NOTIFICATION_ID = 1;
    private Class                       _notifActivity;
    private Context                     _context;
    private String                      _notifTitle;
    private String                      _notifText;
    private int                         _notifLayout;

    public StreamingNotification(String _notifActivity, Context _context, String _notifTitle, String _notifText, int _notifLayout) {

        super();
        try {
            this._notifActivity = Class.forName(_notifActivity);
        }
        catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        this._context = _context;
        this._notifTitle = _notifTitle;
        this._notifText = _notifText;
        this._notifLayout = _notifLayout;
        // manager
        _notificationManager = (NotificationManager)_context.getSystemService(Context.NOTIFICATION_SERVICE);
        // notif builder
        _builder = new NotificationCompat.Builder(_context);
        buildSimpleNotification();
    }

    private void buildSimpleNotification() {

        // notif intent
        final Intent notificationIntent = new Intent(_context, _notifActivity);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        // remote view
        RemoteViews contentView = new RemoteViews(_context.getPackageName(), _notifLayout);
        // pending intent
        final PendingIntent contentIntent = PendingIntent.getActivity(_context, NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        _builder.setContentIntent(contentIntent).setContent(contentView).setOngoing(true).setWhen(System.currentTimeMillis()).setAutoCancel(false).setContentTitle(_notifTitle)
            .setContentText(_notifText);
        // notification build
        _notification = _builder.getNotification();
        _notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_NO_CLEAR;
        _notificationManager.notify(NOTIFICATION_ID, _notification);
    }
    [GETTERS AND SETTERS]
}

我是否做得对?如何管理RemoteViews自定义通知?


请给我提供一个建议。我使用RemoteView构建了一个通知大视图,以控制播放/暂停,就像这个链接(stackoverflow.com/questions/14508369/…)中所示的那样。一切都没问题,但是当我点击设备的返回按钮并从应用程序退出后,点击事件(播放/暂停/前进/关闭)按钮就不起作用了。请帮助我。 - Helal Khan
首先,你的链接不完整。然后你的意思是:当你完成应用程序的根活动时,你的通知不再响应了吗? - An-droid
1个回答

5
在这种情况下,要求一个权威来源有些困难,因为大多数音乐播放器都是闭源的,而且几乎没有人使用那种扩展控件显示通知的方式。
从风格上讲,我会将其委派给NotificationCompat而不是扩展它。这样,您可以在内部提供更简单的API,而不是暴露整个NotificationCompat。
至于RemoteViews,我不太确定你具体在问什么。无论你怎么做,只要保持Notification实例,就可以保留RemoteViews(或各个视图)的实例并根据需要更新它们。如果您选择代理而不是继承,则会变得更加清晰,因为以“此字段是通知,此字段是其视图”的方式是有意义的。
顺便说一句,从纯语法角度来看,请尝试使用框架命名指南。最值得注意的是,字段以“m”为前缀,并使用驼峰式命名法(例如,mNotifTitle)。最后,私有字段是良好测试的致命弱点。

谢谢您的回复。您在许多方面都是正确的,我需要重新设计我的库。请问为什么您说“私有字段是好测试的克林贡石”呢?我通常用它们来进行一些安全性操作(即使没有真正的安全性)。最后,您知道一些有关此类通知的教程/详细文档吗?(除了我经常使用的官方文档之外) - An-droid
私有/公共/受保护与安全绝对没有任何关系 - 您可以使用反射在运行时更改字段的访问级别。这是关于组件以及它们应该知道的内容。个人而言,除非我绝对必须指定它,否则我会将字段保留为包可见性(即没有限定符)。这使得测试变得更加容易,因为我可以将测试放在与被测试代码相同的包中,并且可以自由地检查单元测试的内部状态(这也减少了要阅读的文本量)。使用私有字段无法做到这一点(除非您使用getter泄漏所有字段)。 - Delyan
很好的解释,谢谢 =)。请问一下我的第二个问题呢? - An-droid
1
很抱歉,我无法为您提供教程。我不从教程中学习,因此也不会跟踪它们。从文档来看,这并不难 - 您需要两个RemoteViews,一个用于折叠的通知,另一个用于展开的通知。使用NotificiationCompat构建折叠通知。然后,在创建的通知上设置bigContentView即可(确保在正确的API级别之后执行)。跟踪所有按钮、文本字段和图像是一件麻烦而费力的事情,但这是良好用户体验的代价。 :) - Delyan
您需要在服务中拥有BroacastReceiver,并使用意图管理单击事件。很抱歉回复晚了。 - An-droid
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接