Android实战 - 音心播放器 (通知实现音乐的播放/暂停/下一曲控制)

来源:互联网 发布:数列相关书籍 知乎 编辑:程序博客网 时间:2024/05/19 10:36

1.背景

    通知 -> Service :

   上一篇的MusicService 中提高了通知是Service的前台显示,这篇将介绍通知(MusicNotification).通知在这里有四个作用:

    (1)显示当前音乐的信息

    (2)播放/暂停音乐

    (3)下一曲播放音乐

    (4)关闭通知栏(实际上也是停止音乐播放并关闭Service)

     Service -> 通知 :

    通知和Service是紧密相连的,当Service结束的时候,取消通知;当Service启动的时候,初始化通知/创建通知;当音乐状态发生改变的时候,更新通知;如下图所示 :

                                                       

  2.通知实现

      在这里单独的将通知单独的类中,方便使用;没有使用到通知的震动提醒/铃声提醒/闪光灯提醒,如果需要使用,可以看博客 : 

Android-Notification (通知实现).


   (1)通知布局实现

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="60dp" >    <ImageView        android:id="@+id/iv_notification_logo"        android:layout_width="60dp"        android:layout_height="match_parent"        android:layout_alignParentLeft="true"        android:layout_margin="5dp"        android:src="@drawable/logo" />    <TextView        android:id="@+id/tv_nofitication_singname"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:layout_toRightOf="@+id/iv_notification_logo"        android:maxLines="1"        android:textSize="12sp"        android:text="@string/item_notification_singname"        android:textColor="@color/text_color_whrit" />    <TextView        android:id="@+id/tv_nofitication_singer"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_marginBottom="10dp"         android:textSize="10sp"        android:layout_toRightOf="@+id/iv_notification_logo"        android:text="@string/item_notifiaction_singer"        android:textColor="@color/bg_color" />    <ImageView        android:id="@+id/iv_nofitication_kzhi_play"        android:layout_width="40dp"        android:layout_height="40dp"        android:layout_marginTop="20dp"        android:layout_marginBottom="10dp"        android:layout_toLeftOf="@+id/iv_nofitication_kzhi_next"        android:src="@android:drawable/ic_media_play" />    <ImageView        android:id="@+id/iv_nofitication_kzhi_next"        android:layout_width="40dp"        android:layout_height="40dp"         android:layout_marginTop="20dp"        android:layout_marginBottom="10dp"        android:layout_toLeftOf="@+id/iv_nofitication_kzhi_colse"        android:src="@android:drawable/ic_media_next" />    <ImageView        android:id="@+id/iv_nofitication_kzhi_colse"        android:layout_width="30dp"        android:layout_height="30dp"        android:layout_alignParentRight="true"        android:layout_marginTop="20dp"        android:layout_marginBottom="10dp"        android:layout_marginRight="10dp"        android:layout_marginLeft="10dp"        android:src="@android:drawable/ic_menu_close_clear_cancel"        android:textColor="@color/text_color_main" /></RelativeLayout>
    

       效果 :

                                                            

    (2)代码实现

             说明: 1)通知的实现是单例模式实现(恶汉式)( 

设计模式之单例模式(Singleton pattern)

);

                         2)通知中通过使用RemoteViews ,进行自定义布局实现;

                         3)通过PendingIntent来封装响应点击事件的Intent ;

                         4)第3条中的Intent,经过测试,只能每个响应事件,填充参数的Intent,只能对应一个点击事件 ,                         否则是得不到Intent中的参数的。但如果不需要区分的话,一个Intent就可以实现点击事件的响应;

                         5)通过PendingInetnt.getBroadcast() 方法来通知MusicService,进行响应事件的本质作用;

                         6)广播:如果MusicService想要接收到通知来的点击事件,那么需要在MusicServiceBroadcast中                         注册(IntentFiliter/addAction(xxx)),同时通知中的Inent需 要setAction(xxx), xxx 要一样;


   实现的通知源码分享 :

package cn.labelnet.framework;import com.android.volley.toolbox.ImageLoader.ImageListener;import android.R.anim;import android.annotation.SuppressLint;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.os.Build;import android.widget.RemoteViews;import cn.labelnet.maskmusic.R;import cn.labelnet.model.MusicModel;import cn.labelnet.net.VolleyHttpRequest;public class MusicNotification extends Notification {/** * Music播放控制 的  Notification  * 动态的显示后台的MusicService的前台展示 *//** * 恶汉式实现单例模式加载 */private static MusicNotification notifyInstance = null;// 通知idprivate final int NOTIFICATION_ID = 10001;// 通知private Notification musicNotifi = null;// 管理通知private NotificationManager manager = null;// 界面实现private Builder builder = null;// 上下文private Context context;// 布局private RemoteViews remoteViews;private final int REQUEST_CODE = 30000;// 给Service 发送广播private final String MUSIC_NOTIFICATION_ACTION_PLAY = "musicnotificaion.To.PLAY";private final String MUSIC_NOTIFICATION_ACTION_NEXT = "musicnotificaion.To.NEXT";private final String MUSIC_NOTIFICATION_ACTION_CLOSE = "musicnotificaion.To.CLOSE";private final String MUSIC_NOTIFICAION_INTENT_KEY = "type";private final int MUSIC_NOTIFICATION_VALUE_PLAY = 30001;private final int MUSIC_NOTIFICATION_VALUE_NEXT = 30002;private final int MUSIC_NOTIFICATION_VALUE_CLOSE =30003;private Intent play=null,next=null,close = null;private PendingIntent musicPendIntent = null;// 给进度条页面广播// 待实现// 网络 : 加载图片实现private ImageListener imageListener = null;public void setManager(NotificationManager manager) {this.manager = manager;}public void setContext(Context context) {this.context = context;}private MusicNotification() {// 初始化操作remoteViews = new RemoteViews("cn.labelnet.maskmusic",R.layout.list_item_notification);builder = new Builder(context);// 初始化控制的Intentplay = new Intent();play.setAction(MUSIC_NOTIFICATION_ACTION_PLAY);next = new Intent();next.setAction(MUSIC_NOTIFICATION_ACTION_NEXT);    close = new Intent();close.setAction(MUSIC_NOTIFICATION_ACTION_CLOSE);}/** * 恶汉式实现 通知 *  * @return */public static MusicNotification getMusicNotification() {if (notifyInstance == null) {notifyInstance = new MusicNotification();}return notifyInstance;}/** * 创建通知 * 初始化通知 */@SuppressLint("NewApi")public void onCreateMusicNotifi() {// 设置点击事件// 1.注册控制点击事件play.putExtra("type",MUSIC_NOTIFICATION_VALUE_PLAY);PendingIntent pplay = PendingIntent.getBroadcast(context, REQUEST_CODE,play, NOTIFICATION_ID);remoteViews.setOnClickPendingIntent(R.id.iv_nofitication_kzhi_play,pplay);// 2.注册下一首点击事件next.putExtra("type",MUSIC_NOTIFICATION_VALUE_NEXT);PendingIntent pnext = PendingIntent.getBroadcast(context, REQUEST_CODE,next, NOTIFICATION_ID);remoteViews.setOnClickPendingIntent(R.id.iv_nofitication_kzhi_next,pnext);// 3.注册关闭点击事件close.putExtra("type",MUSIC_NOTIFICATION_VALUE_CLOSE);PendingIntent pclose = PendingIntent.getBroadcast(context, REQUEST_CODE,  close, NOTIFICATION_ID);remoteViews.setOnClickPendingIntent(R.id.iv_nofitication_kzhi_colse,pclose);builder.setContent(remoteViews).setWhen(System.currentTimeMillis())// 通知产生的时间,会在通知信息里显示//.setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级.setOngoing(true).setTicker("播放新的一首歌").setSmallIcon(R.drawable.logo);// 兼容性实现musicNotifi = builder.getNotification();//if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {//musicNotifi = builder.getNotification();//} else {//musicNotifi = builder.build();//}musicNotifi.flags = Notification.FLAG_ONGOING_EVENT;manager.notify(NOTIFICATION_ID, musicNotifi);}/** * 更新通知 */public void onUpdataMusicNotifi(MusicModel mm, boolean isplay) {// 设置添加内容remoteViews.setTextViewText(R.id.tv_nofitication_singname,(mm.getSongname()!=null?mm.getSongname():"什么东东") + "");remoteViews.setTextViewText(R.id.tv_nofitication_singer,(mm.getSingername()!=null?mm.getSingername():"未知") + "");//判断是否播放if (isplay) {remoteViews.setImageViewResource(R.id.iv_nofitication_kzhi_play,android.R.drawable.ic_media_pause);} else {remoteViews.setImageViewResource(R.id.iv_nofitication_kzhi_play,android.R.drawable.ic_media_play);}onCreateMusicNotifi();}/** * 取消通知栏 */public void onCancelMusicNotifi(){manager.cancel(NOTIFICATION_ID);}}

   (3)广播的基本使用图解   

                             


3.总结

   通知的更新控制是在音乐状态发生改变的时候,就会更新通知的内容;相反通知也可以控制音乐当前的状态;后面还有音乐播放界面的控制,省去了很多事,简单的在Service 中调用就可以实现。
   MusicService 与 MusicNotification 的基本控制图 ,如下图所示 :
                                
       音乐的播放/暂停/上一曲/下一曲/停止 基本控制 是在MusicService中实现的,所以请看 

Android实战 - 音心播放器 (Music Service 实现);



2 0
原创粉丝点击