1.所需工具
进度条:
GitHub 获取:
MaskProgressView : https://github.com/iammert/MaskProgressView
也可以免积分下载 音乐播放器进度条library :
2.效果演示
实现功能:
(1) 音乐播放 (音乐播放地址URL)
(2) 进度条 (MaskProgressView)
(3) 拖动进度条音乐跟踪
(4) 音乐播放service服务实现
(5) 播放暂停控制
(6) 自动获取音乐时间 (MediaPlay 返回值)
(7) Notification 自定义布局通知
(8) 加载专辑图片,歌手图片 , 和加载进度条
待完善功能 :
(1) Notification 点击控制
(2) 歌词滚动显示
(3) 上一曲,下一曲控制实现
183 : 是MediaPlay 返回的 歌曲时间 (秒)
3.布局实现
//1. activity_tbmusic.xml
说明 : com.joooonho.SelectableRoundedImageView 是 圆型图片,可以换成ImageView , 那样就是正方形的.
如果想使用的话,可以到Github 上搜所SelectableRoundedImageView 集成就可以了.
或者 :
compile ‘com.joooonho:selectableroundedimageview:1.0.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="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#221725">
<RelativeLayout
android:id="@+id/layoutHeader"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#36223b">
<com.joooonho.SelectableRoundedImageView
android:id="@+id/imageviewHeader"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="center"
android:src="@drawable/logo"
app:sriv_border_color="#eee"
app:sriv_border_width="2dip"
app:sriv_left_bottom_corner_radius="48dip"
app:sriv_left_top_corner_radius="16dip"
app:sriv_oval="true"
app:sriv_right_bottom_corner_radius="16dip"
app:sriv_right_top_corner_radius="0dip"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/imageviewHeader"
android:gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp">
<TextView
android:id="@+id/textSinger"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:text="Linkin Park - Bleed It Out"/>
<TextView
android:id="@+id/textPublisher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textSinger"
android:layout_marginTop="2dp"
android:textColor="#80FFFFFF"
android:text="submitted by Bruce Diaz"/>
</RelativeLayout>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:layout_alignParentRight="true"
android:background="@drawable/icon_menu"/>
</RelativeLayout>
<co.mobiwise.library.MaskProgressView
android:id="@+id/maskProgressView"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_centerHorizontal="true"
android:layout_below="@+id/layoutHeader"
app:progressEmptyColor="#4e3c51"
app:progressLoadedColor="#e91e64"
app:coverMaskColor="#80000000"
app:durationTextColor="#FFFFFF"
app:durationTextSize="15sp"
app:coverImage="@drawable/cover"
app:progressHeight="4dp"
app:maxProgress="100"
app:currentProgress="0"
app:placeHolder="@drawable/cover"/>
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_below="@+id/layoutHeader"
android:background="@drawable/shadow"/>
<RelativeLayout
android:id="@+id/tb_music_other"
android:layout_width="match_parent"
android:layout_below="@+id/tb_music_kongzhi"
android:layout_centerVertical="true"
android:layout_marginTop="10dp"
android:layout_height="25dp">
<TextView
android:id="@+id/tb_music_like"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="2333"
android:textColor="@color/white"
android:layout_alignParentLeft="true"
android:layout_marginLeft="20dp"
android:drawablePadding="3dp"
android:drawableLeft="@drawable/ic_favorite_outline_red_400_24dp"/>
<TextView
android:id="@+id/tb_music_ci"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="词"
android:layout_marginRight="20dp"
android:textSize="20sp"
android:textColor="@color/white"
android:layout_alignParentRight="true"
android:layout_marginLeft="20dp"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/tb_music_kongzhi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/maskProgressView"
android:layout_centerVertical="true">
<Button
android:id="@+id/buttonControl"
android:layout_width="70dp"
android:layout_height="70dp"
android:background="@drawable/icon_play"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
<Button
android:id="@+id/buttonNext"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@drawable/icon_next"
android:layout_toRightOf="@+id/buttonControl"
android:layout_marginLeft="50dp"
android:layout_centerVertical="true"/>
<Button
android:id="@+id/buttonPrevious"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@drawable/icon_previous"
android:layout_toLeftOf="@+id/buttonControl"
android:layout_marginRight="50dp"
android:layout_centerVertical="true"/>
</RelativeLayout>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tb_progress_tbmusic"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
//2. shadow.xml
阴影效果,drawable 下, 其他的控制按钮 ,我就不上传了.自己可以到Github 找.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="@color/color_black_50" android:centerColor="@color/color_black_25" android:endColor="@color/color_transparent" android:angle="270"/>
</shape>
// 3. notification_music_layout.xml
通知栏布局实现,其中的控制按钮,自己实现吧
<?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="64dp"
android:gravity="center_horizontal"
android:background="@color/transparent"
android:padding="10dp">
<ImageView
android:id="@+id/notification_music_logo"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:src="@drawable/labelnet" />
<TextView
android:id="@+id/notification_music_name"
android:layout_toRightOf="@+id/notification_music_logo"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="海阔天空 (Live)"
android:textColor="@color/white_pressed"
android:textSize="12sp" />
<TextView
android:id="@+id/notification_music_singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/notification_music_logo"
android:layout_below="@+id/notification_music_name"
android:layout_marginTop="5dp"
android:layout_marginLeft="10dp"
android:text="原明卓"
android:textColor="@color/switch_thumb_normal_material_dark"
android:textSize="10sp" />
<Button
android:id="@+id/notification_music_Previous"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/icon_previous"
android:layout_toLeftOf="@+id/notification_music_Control"
android:layout_marginRight="20dp"
android:layout_centerVertical="true"/>
<Button
android:id="@+id/notification_music_Control"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerInParent="true"
android:layout_toLeftOf="@+id/notification_music_Next"
android:background="@drawable/icon_play" />
<Button
android:id="@+id/notification_music_Next"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/icon_next"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
4.TbMusicActivity.java 实现
这里我想说下 BroadCastReceiver 实现 :
使用的时候,需要先注册registerReceiver(musicReceiver, filter);
其中 Filter 是 标识别 是那个 BroadCastReceiver .
在销毁的时候,需要 unregisterReceiver
package labelnet.cn.ledou;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;
import com.joooonho.SelectableRoundedImageView;
import co.mobiwise.library.AnimationCompleteListener;
import co.mobiwise.library.MaskProgressView;
import co.mobiwise.library.OnProgressDraggedListener;
import labelnet.cn.ledou.model.MusicModel;
import labelnet.cn.ledou.net.NetManager;
import labelnet.cn.ledou.net.NetManagerImp;
import labelnet.cn.ledou.service.MusicService;
/**
* Created by yuan on 15-11-10.
* 播放音乐
*/
public class TbMusicActivity extends AppCompatActivity implements
OnProgressDraggedListener,
AnimationCompleteListener,
View.OnClickListener {
/**
* UI
*/
private Button buttonPlayPause, buttonNext, buttonPrevious;
private MaskProgressView maskProgressView;
private SelectableRoundedImageView imageviewHeader;
private TextView textSinger, textPublisher, tb_music_ci, tb_music_like;
private ProgressBar tb_progress_tbmusic;
//对象
private NetManager manager;
private MusicModel musicModel = new MusicModel();
//一些数据
private static final String MUSIC_URL = "url";
private static final String MUSIC_MSG_STATE = "MSG";
private static final String MUSIC_CURRENTTIME = "currentTime";
//test数据
private String test_url = "http://ws.stream.qqmusic.qq.com/104897799.m4a?fromtag=46";
private int test_second = 208;
private String test_music_picture = "http://i.gtimg.cn/music/photo/mid_album_300/2/3/001CqGRZ4cQN23.jpg";
private String test_music_name = "海阔天空 (Live)";
private String test_art_name = "汪小敏";
private String test_art_picture = "http://i.gtimg.cn/music/photo/mid_album_90/2/3/001CqGRZ4cQN23.jpg";
//最后时间
private int currentTime = 0;
//是否是暂停状态
private boolean isPause = false;
private Intent intent, serviceIntent;
//通知
private NotificationManager notificationManager;
private Bitmap notification_bitmap = null;
/**
* BroadCastReceiver
*/
private MusicBroadcastReceiver musicReceiver;
private final static String BROADCASTRECEIVER_MUSICACTIVITY_GETTIME = "labelnet.cn.ledou.TbMusicActivity.MusicBroadcastReceiver";
//这是Service的 boardcast
private final static String BROADCASTRECEIVER_MUSICSERVICE = "labelnet.cn.ledou.service.MusicService.MusicSerciceBroadCastRevicer";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tbmusic);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager = new NetManagerImp();
intent = new Intent(TbMusicActivity.this, MusicService.class);
//初始化serviceIntent : 目的是给 MusicService 的BroadCast 发送信息
serviceIntent = new Intent();
serviceIntent.setAction(BROADCASTRECEIVER_MUSICSERVICE);
loadMusicModel();
initView();
initBordcast();
}
//初始化 通知栏
private void initNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
RemoteViews remoteView = new RemoteViews(getPackageName(), R.layout.notification_music_layout);
remoteView.setTextViewText(R.id.notification_music_name, musicModel.getMusic_name());
remoteView.setTextViewText(R.id.notification_music_singer, musicModel.getArtist());
if (notification_bitmap != null) {
//设置imageView
remoteView.setImageViewBitmap(R.id.notification_music_logo, notification_bitmap);
}
serviceIntent.putExtra("type", 2);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, serviceIntent, PendingIntent.FLAG_CANCEL_CURRENT);
remoteView.setOnClickPendingIntent(R.id.notification_music_Control, pendingIntent);
builder.setContent(remoteView)
.setWhen(System.currentTimeMillis())// 通知产生的时间,会在通知信息里显示
.setTicker("正在播放")
.setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级
.setOngoing(true)
.setSmallIcon(R.drawable.labelnet);
Notification notify = builder.build();
notify.flags = Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(1, notify);
}
/**
* 初始话数据
*/
private void loadMusicModel() {
musicModel.setMusic_url(test_url);
musicModel.setMusic_seconds(test_second);
musicModel.setArtist(test_art_name);
musicModel.setArtist_picture(test_art_picture);
musicModel.setMusic_picture(test_music_picture);
musicModel.setMusic_name(test_music_name);
musicModel.setLike(1000203);
}
/**
* 动态注册
* 初始化 bordcastRecycler
*/
private void initBordcast() {
musicReceiver = new MusicBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCASTRECEIVER_MUSICACTIVITY_GETTIME);
registerReceiver(musicReceiver, filter);
}
/**
* 初始化 界面
*/
private void initView() {
buttonPlayPause = (Button) findViewById(R.id.buttonControl);
buttonNext = (Button) findViewById(R.id.buttonNext);
buttonPrevious = (Button) findViewById(R.id.buttonPrevious);
buttonPlayPause.setOnClickListener(this);
buttonNext.setOnClickListener(this);
buttonPrevious.setOnClickListener(this);
imageviewHeader = (SelectableRoundedImageView) findViewById(R.id.imageviewHeader);
textSinger = (TextView) findViewById(R.id.textSinger);
textPublisher = (TextView) findViewById(R.id.textPublisher);
tb_progress_tbmusic = (ProgressBar) findViewById(R.id.tb_progress_tbmusic);
tb_music_like = (TextView) findViewById(R.id.tb_music_like);
tb_music_ci = (TextView) findViewById(R.id.tb_music_ci);
tb_music_ci.setOnClickListener(this);
maskProgressView = (MaskProgressView) findViewById(R.id.maskProgressView);
maskProgressView.setOnProgressDraggedListener(this);
maskProgressView.setAnimationCompleteListener(this);
//初始化界面
maskProgressView.setmMaxSeconds(musicModel.getMusic_seconds()); //初始化时间,从service获得
new maskProgressViewImage().execute(musicModel.getMusic_picture());
textSinger.setText(musicModel.getMusic_name());
textPublisher.setText(musicModel.getArtist());
manager.loadImage(musicModel.getArtist_picture(), imageviewHeader);
tb_music_like.setText(musicModel.getLike()+"");
}
/**
* 加载专辑图片
*/
private class maskProgressViewImage extends AsyncTask<String, Void, Bitmap> {
@Override
protected Bitmap doInBackground(String... params) {
return manager.getBitmap(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if(bitmap==null){
bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.logo);
}
maskProgressView.setCoverImage(bitmap);
notification_bitmap = bitmap;
//隐藏进度条
tb_progress_tbmusic.setVisibility(View.GONE);
}
}
/**
* 滑动拖动 进度条
*
* @param position
*/
@Override
public void onProgressDragged(int position) {
currentTime = position * 1000;
Log.e("Ledou", MUSIC_CURRENTTIME + "3 : " + currentTime);
}
@Override
public void onProgressDragging(int position) {
//拖动中 , 监听事件
Log.v("TEST", "Current Second 1: " + position);
currentTime = position * 1000;
serviceIntent.putExtra("type", 0);
serviceIntent.putExtra(MUSIC_CURRENTTIME, currentTime);
sendBroadcast(serviceIntent);
Log.e("Ledou", MUSIC_CURRENTTIME + "2 : " + currentTime);
}
private boolean isCiShow = true;
/**
* 点击事件
*
* @param v
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonControl:
if (maskProgressView.isPlaying()) {
musicPause();
} else {
musicPlay();
}
break;
case R.id.buttonNext:
// musicNext();
showToast("暂时不支持");
break;
case R.id.buttonPrevious:
// musicPrevious();
showToast("暂时不支持");
break;
case R.id.tb_music_ci:
if (isCiShow) {
//显示歌词
tb_music_ci.setTextColor(getResources()
.getColor(R.color.fu_color));
showToast("歌词显示了");
isCiShow=false;
} else {
//隐藏歌词
tb_music_ci.setTextColor(getResources()
.getColor(R.color.white_color));
showToast("歌词关闭了");
isCiShow=true;
}
showToast("我是歌词");
break;
default:
break;
}
}
private void showToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
/**
* 暂停
*/
private void musicPause() {
buttonPlayPause.setBackgroundResource(R.drawable.icon_play);
maskProgressView.pause();
serviceIntent.putExtra("type", 1);
sendBroadcast(serviceIntent);
isPause = true;
}
/**
* 播放
*/
private void musicPlay() {
buttonPlayPause.setBackgroundResource(R.drawable.icon_pause);
if (isPause) {
//暂停状态下,使得继续
maskProgressView.start();
//暂停状态
serviceIntent.putExtra("type", 2);
sendBroadcast(serviceIntent);
} else {
//显示进度条
tb_progress_tbmusic.setVisibility(View.VISIBLE);
//播放状态
intent.putExtra(MUSIC_URL, test_url);
startService(intent);
initNotification();
}
}
/**
* 监听是否播放完毕
*/
@Override
public void onAnimationCompleted() {
buttonPlayPause.setBackgroundResource(R.drawable.icon_play);
}
/**
* 解注册 BroadCast
*/
@Override
protected void onDestroy() {
super.onDestroy();
//unregisterReceiver(musicReceiver);
}
/**
* 解除注册
*/
@Override
protected void onStop() {
super.onStop();
// unregisterReceiver(musicReceiver);
}
//Broadcast : 接收 来自MusicService 的 消息
private class MusicBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int type = intent.getIntExtra("type", -1);
switch (type) {
case 0:
String msg = intent.getStringExtra("msg");
showToast(msg);
maskProgressView.setmMaxSeconds(Integer.parseInt(msg));
maskProgressView.start();
//隐藏进度条
tb_progress_tbmusic.setVisibility(View.GONE);
Log.e("Ledou", msg);
break;
default:
showToast("MusicBroadcastReceiver : 怎么回事");
break;
}
}
}
}
5. MusicService.java实现
MediaPlayer 相关 方法 :
Mediaplayer:构造方法
create: 创建一个要播放的多媒体
getCurrentPosition:得到当前播放位置
getDuration: 得到文件的时间
prepare: 准备(同步)
prepareAsync:准备(异步)
seekTo: 指定播放的位置(以毫秒为单位)
setAudioStreamType: 设置流媒体的类型
setDataSource: 设置数据来源
setDisplay: 设置用SurfaceHolder来显示多媒体
setOnBufferingUpdateListener: 网络流媒体的缓冲监听
setOnErrorListener: 设置错误信息监听
setOnVideoSizeChangedListener:视频尺寸监听
setScreenOnWhilePlaying: 设置是否使用SurfaceHolder来显示
setVolume: 设置音量
//获取sd卡上的音频文件
setDataSource(“/sdcard/test.mp3”);
//装载资源中的音乐
MediaPlayer.create(Activity01.this,R.raw.test);
package labelnet.cn.ledou.service;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
/**
* Created by yuan on 15-11-10.
* <p/>
* 音乐后台播放 ,和 状态栏显示
*/
public class MusicService extends Service implements MediaPlayer.OnCompletionListener
, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener{
//控件
private MediaPlayer mediaPlayer;
//一些控制
//当前播放的长度
private int currentTime;
//地址
private String uriPath;
//broadCastReceiver
private final static String BROADCASTRECEIVER_MUSICACTIVITY_GETTIME = "labelnet.cn.ledou.TbMusicActivity.MusicBroadcastReceiver";
private final static String BROADCASTRECEIVER_MUSICSERVICE = "labelnet.cn.ledou.service.MusicService.MusicSerciceBroadCastRevicer";
private static final String MUSIC_CURRENTTIME = "currentTime";
private static final String MUSIC_SERVICE_TYPE = "type";
private MusicSerciceBroadCastRevicer musicSerciceBroadCastRevicer;
private Intent activityintent ;
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
//musicActivity
activityintent= new Intent();
activityintent.setAction(BROADCASTRECEIVER_MUSICACTIVITY_GETTIME);
//初始化musicSerciceBroadCastRevicer
musicSerciceBroadCastRevicer = new MusicSerciceBroadCastRevicer();
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCASTRECEIVER_MUSICSERVICE);
registerReceiver(musicSerciceBroadCastRevicer, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//通过状态来进行播放
uriPath = intent.getStringExtra("url");
play();
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
unregisterReceiver(musicSerciceBroadCastRevicer);
super.onDestroy();
}
/下面是MediaPlayer的监听接口实现//
/**
* 接口实现: 音乐播放完成
* 注册一个在播放过程中已达到的媒体源结束时调用的回调函数。
* @param mp
*/
@Override
public void onCompletion(MediaPlayer mp) {
//发送通知
currentTime=0;
showToast("播放完毕");
}
/**
* 音乐准备状态
*
* @param mp
*/
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start(); // 开始播放
if (currentTime > 0) { // 如果音乐不是从头播放 : currentTime 是毫秒为单位的
mediaPlayer.seekTo(currentTime);
}
//通知栏改变状态
}
/**
* 接口实现 : 出错的情况下
*
* @param mp
* @param what
* @param extra
* @return
*/
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
/MediaPlayer的播放控制方法实现///
/**
* 播放音乐
*/
private void play() {
try {
// 把各项参数恢复到初始状态
mediaPlayer.reset();
//设置地址
mediaPlayer.setDataSource(getApplication(), Uri.parse(uriPath));
// 进行缓冲
mediaPlayer.prepare();
// 注册一个监听器
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
//发送通知 : 目的是得到歌曲的时长
int durrent = mediaPlayer.getDuration() / 1000;
activityintent.putExtra("msg", String.valueOf(durrent));
activityintent.putExtra("type", 0);
sendBroadcast(activityintent);
} catch (Exception e) {
Log.e("Ledou", "MusicService play:" + e.getMessage());
}
}
/**
* 暂停音乐
*/
private void pause() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
currentTime=mediaPlayer.getCurrentPosition();
mediaPlayer.pause();
}
}
/**
* 继续播放
*/
private void resume() {
mediaPlayer.start();
Log.e("Ledou", MUSIC_CURRENTTIME + "5: " + currentTime);
if (currentTime > 0) {
mediaPlayer.seekTo(currentTime);
}
}
private void showToast(String msg) {
Toast.makeText(getApplication(), msg, Toast.LENGTH_SHORT).show();
}
/**
* 接收 TbmusicActivity 发送的通知
*/
private class MusicSerciceBroadCastRevicer extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int type = intent.getIntExtra(MUSIC_SERVICE_TYPE, -1);
switch (type) {
case 0:
//拖动改变进度
if(mediaPlayer.isPlaying()) {
currentTime = intent.getIntExtra(MUSIC_CURRENTTIME, 0);
resume();
}
// //改变播放状态
// activityintent.putExtra("type",1);
// sendBroadcast(activityintent);
break;
case 1:
//暂停
pause();
break;
case 2:
//继续播放
resume();
// Log.e("Ledou", MUSIC_CURRENTTIME + "4 : " + currentTime);
break;
default:
showToast("未知错误,乱发东西");
break;
}
// showToast("MUSIC type : "+type);
}
}
}
MediaPlayer 相关注意事项 :
1. 当一个MediaPlayer对象被创建或者调用reset()方法之后, 它处于空闲状态,调用release()方法后处于结束状态 ;
(1) 一个MediaPlayer对象调用了reset()方法后,再调用其它方法可能会触发OnErrorListener.onError()事件,未调用reset()方法则
不会触发 ;
(2) 当Mediaplayer对象不再被使用时,最好调用release()方法对其进行释放,使其处于结束状态,此时它不能被使用 ;
(3) Mediaplayer对象被创建时(调用构造方法)处于空闲状态,若使用create()方法创建后则处于准备状态。
2. 一般情况下,一些常用的播放控制操作可能因为音频、视频的格式不被支持或者质量较差以及流超时,
也有可能由于开发者的疏忽使得Mediaplayer对象处于无效状态等而导致错误。
此时可通过注册setOnErrorListener方法实现监控。
如果发生了错误,Mediaplayer对象将处于多雾状态,可以使用reset()方法来回复错误。
3. 任何Mediaplayer对象都必须先处于准备状态,然后才开始播放
4. 要开始播放Mediaplayer对象都必须成功调用start()方法,可通过isPlaying()方法来检测是否正在播放 .
5. 当Mediaplayer对象在播放时,可以进行暂停和停止操作,pause()方法暂停播放,stop()方法停止播放。处于暂停暂停时可通过start()方法恢复播放,但是处于停止状态时则必须先调用prepare()方法使其处于准备状态,再调用start()方法。
6.注册 MusicService
<!--注册musicService , 添加 BoradCast过滤-->
<service android:name=".service.MusicService">
<intent-filter>
<action android:name="labelnet.cn.ledou.service.MusicService.MusicSerciceBroadCastRevicer" />
</intent-filter>
</service>
7.BroadcastReceiver 在 Activity 和 Service 通信流程
在大纲图上进行了详细流程说明
8.参考资料
MediaPlayer 的各种属性 :
http://www.cnblogs.com/dyllove98/p/3192090.html
Service :
http://blog.csdn.net/LABLENET/article/details/48073093
http://www.android-doc.com/guide/components/services.html
BroadCast :
http://segmentfault.com/a/1190000002400391
Notification :
http://www.2cto.com/kf/201405/300991.html
RemoteViews官方资料
大神音乐播放器开发专栏 :
http://blog.csdn.net/column/details/simplebeautymusicpla.html