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

1.背景

    通知 -> Service :

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

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

    (2)播放/暂停音乐

    (3)下一曲播放音乐

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

     Service -> 通知 :

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

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

  2.通知实现

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

Android-Notification (通知实现).


   (1)通知布局实现




    

    

    

    

    

    

    

       效果 :

                                                            

    (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;

	// 通知id
	private 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);

		// 初始化控制的Intent
		play = 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)广播的基本使用图解   

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


3.总结

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

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



你可能感兴趣的:(android,实战,安卓实战音心APP开发)