Android 实战 - 个人APP乐逗项目(内部音乐播放器实现,开源MaskProgressView使用)

1.所需工具

进度条:
GitHub 获取:

MaskProgressView : https://github.com/iammert/MaskProgressView

也可以免积分下载 音乐播放器进度条library :

http://download.csdn.net/detail/lablenet/9262321

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值