在android屏幕的通知栏中增加notification,以显示mediaplayer控制面板
点击控制面板的按钮将发送intent来控制mediaplayer
这些intent将以PendingIntent的形式绑定到控制面板上的按钮上


不能工作的代码:

public void sendNotification(int status) { if (playingFile != null) {    /**   * 给notification构建intent   */     //如下是在notification中给remoteview设置PendingIntent  //receiver按NOTIFICATION_ACTION进行过滤  //过滤之后按putExtra中设置的参数分辨命令  //  //陷阱是setAction()和PendingIntent.getBroadcast()以及FLAG_UPDATE_CURRENT  //如下代码,最终所有PendingIntent都会变成最后一个!  //猜测,无论从上到下生成多少个PendingIntent  //但同一条ACTION的PendingIntent.getBroadcast()背后只对应一个静态变量!  //也即这四个实际上是一个PendingIntent  //FLAG_UPDATE_CURRENT及另外几个参数的说明也非常不易懂,看得很晕  //  //解决方案是,设置receiver可以过滤出多条ACTION而不是一条  //不按putExtra里面设置的数据进行分辨  //而是直接根据不同的ACTION来分辨命令  //可以工作的代码在后面  Intent resultIntentLast = new Intent(this, PlayService.class);  resultIntentLast.setAction(LocalConst.NOTIFICATION_ACTION);  resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_last);  PendingIntent pendingIntentLast = PendingIntent.getBroadcast(this, 0,    resultIntentLast, PendingIntent.FLAG_UPDATE_CURRENT);  Intent resultIntentNext = new Intent(this, PlayService.class);  resultIntentNext.setAction(LocalConst.NOTIFICATION_ACTION);  resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_next);  PendingIntent pendingIntentNext = PendingIntent.getBroadcast(this, 0,    resultIntentNext, PendingIntent.FLAG_UPDATE_CURRENT);       Intent resultIntentPlay = new Intent(this, PlayService.class);  resultIntentPlay.setAction(LocalConst.NOTIFICATION_ACTION);  resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_play);  PendingIntent pendingIntentPlay = PendingIntent.getBroadcast(this, 0,    resultIntentPlay, PendingIntent.FLAG_UPDATE_CURRENT);  Intent resultIntentPause = new Intent(this, PlayService.class);  resultIntentPause.setAction(LocalConst.NOTIFICATION_ACTION);  resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_pause);  PendingIntent pendingIntentPause = PendingIntent.getBroadcast(this, 0,    resultIntentPause, PendingIntent.FLAG_UPDATE_CURRENT);  /**   * 给notification构建remoteView   */  RemoteViews notifyView = new RemoteViews(this.getPackageName(), R.layout.notification);    notifyView.setTextViewText(R.id.notification_name, playingFile.getName());  notifyView.setImageViewResource(R.id.notification_icon, R.drawable.icon);    notifyView.setOnClickPendingIntent(R.id.notification_b1, pendingIntentLast);  notifyView.setOnClickPendingIntent(R.id.notification_b2, pendingIntentNext);  notifyView.setOnClickPendingIntent(R.id.notification_b3, pendingIntentPlay);  notifyView.setOnClickPendingIntent(R.id.notification_b4, pendingIntentPause);         NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)    .setSmallIcon(R.drawable.bottom)    .setContentTitle(playingFile.getName())    .setContentText(getResources().getString(R.string.notification_back_msg))    //这是另外一个陷阱    //上面三个设置是不显示的,但是仅仅设置remoteView是不够的    //得有前面三个设置(或许部分设置),否则不能显示notification    .setContent(notifyView);      Intent resultIntent = new Intent(this, DirPlayerActivity.class);  PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,    resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);  mBuilder.setContentIntent(resultPendingIntent);  // Sets an ID for the notification  int mNotificationId = 001;  // Gets an instance of the NotificationManager service  NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);  // Builds the notification and issues it.  mNotifyMgr.notify(mNotificationId, mBuilder.build()); }}



可以工作的代码:

public void sendNotification(int status) {  if (playingFile != null) {    /**   * 给notification构建remoteView   */  RemoteViews notifyView = new RemoteViews(this.getPackageName(), R.layout.notification);    notifyView.setTextViewText(R.id.notification_name, playingFile.getName());  notifyView.setImageViewResource(R.id.notification_icon, R.drawable.icon);    //采用多条ACTION并且精简后的代码  notifyView.setOnClickPendingIntent(R.id.notification_goto_pause,     PendingIntent.getBroadcast(this, 0,      new Intent(LocalConst.NOTIFICATION_GOTO_PAUSE),      PendingIntent.FLAG_UPDATE_CURRENT));     notifyView.setOnClickPendingIntent(R.id.notification_goto_last,     PendingIntent.getBroadcast(this, 0,      new Intent(LocalConst.NOTIFICATION_GOTO_LAST),      PendingIntent.FLAG_UPDATE_CURRENT));  notifyView.setOnClickPendingIntent(R.id.notification_goto_next,     PendingIntent.getBroadcast(this, 0,      new Intent(LocalConst.NOTIFICATION_GOTO_NEXT),      PendingIntent.FLAG_UPDATE_CURRENT));  notifyView.setOnClickPendingIntent(R.id.notification_goto_play,     PendingIntent.getBroadcast(this, 0,      new Intent(LocalConst.NOTIFICATION_GOTO_PLAY),      PendingIntent.FLAG_UPDATE_CURRENT));      NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)         .setSmallIcon(R.drawable.bottom)    .setContentTitle(playingFile.getName())    .setContentText(getResources().getString(R.string.notification_back_msg))           /**     * 非常奇怪,上面三个set不能省略,否则notification就不显示     * 但上面三项并不显示,因为使用了remoteView及其布局     */        .setContent(notifyView);      Intent resultIntent = new Intent(this, DirPlayerActivity.class);  PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,    resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);  mBuilder.setContentIntent(resultPendingIntent);  // Sets an ID for the notification  int mNotificationId = 001;  // Gets an instance of the NotificationManager service  NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);  // Builds the notification and issues it.  mNotifyMgr.notify(mNotificationId, mBuilder.build());   }}



最后一个陷阱是注册receiver不能使用LocalBroadcastManager
因为notification不在app进程之中
如下代码不能工作

/** * notification上面的按键将发送intent给service * notification上面其他部分被点击后发送pendingIntent给activity */        IntentFilter mNotificationIntentFilter = new IntentFilter(        LocalConst.NOTIFICATION_ACTION);           mNotificationInforReceiver =                new NotificationInforReceiver();        // Registers the DownloadStateReceiver and its intent filters        LocalBroadcastManager.getInstance(this).registerReceiver(        mNotificationInforReceiver,        mNotificationIntentFilter);

直接调用registerReceiver才能工作

/** * notification上面的按键将发送intent给service * notification上面其他部分被点击后发送pendingIntent给activity */        IntentFilter mNotificationIntentFilter = new IntentFilter();        mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_LAST);        mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_NEXT);        mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_PLAY);        mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_PAUSE);           mNotificationInforReceiver =                new NotificationInforReceiver();        /**         * 注意,使用LocalBroadcastManager注册的receiver只能接收本app内部的intent         * 但notification在本app之外         * 所以这里需要直接使用registerReceiver来注册         */        registerReceiver(        mNotificationInforReceiver,        mNotificationIntentFilter);


更多相关文章

  1. Android(安卓)自定义View(二)函数分析
  2. Android(安卓)单例模式与SharedPreferences一起使用
  3. Android(安卓)应用开发笔记 - 下拉列表(Spinner)
  4. AttachCurrentThread报错
  5. Android(安卓)premission 访问权限代码
  6. dalvik.vm 属性与android:largeHeap
  7. Android(安卓)Studio jcenter集成butterknife:8.x.0
  8. Android(安卓)使用Socket实现服务器与手机客户端的长连接四:使用
  9. Android项目中使用javacv和javacpp的代码混淆配置

随机推荐

  1. Android下使用配置文件(Preferences)
  2. android调用系统联系人列表
  3. Android:onNewIntent()触发机制及注意事项
  4. Android(安卓)Studio 3.0新建项目AAPT2
  5. ImageSpan的使用
  6. Android(安卓)HttpClient
  7. android 获取 图片 缩略图
  8. Android(安卓)Studio 安卓模拟器安装本地
  9. Android(安卓)gallery实现二级联动效果
  10. Android之Hello WebView