扣丁音乐(五)——service实现歌曲播放功能

本文出自:http://blog.csdn.net/dt235201314/article/details/51341104

一丶MediaPlayer

参考博文加强:扣丁学堂——MediaPlay(音乐播放)

二丶演示

丶创建MusicService服务

这里贴出了后面涉及到的部分代码

/**
 * 实现功能:
 * 1、点击列表上的某首歌播放
 * 2、点击播放按钮,从暂停转为播放状态
 * 3、点击暂停按钮,从播放状态转为暂停状态
 * 4、上一首
 * 5、下一首
 * 6、播放进度显示
 * 7、播放模式
 */
public class  MusicPlayService extends Service implements MediaPlayer.OnCompletionListener,MediaPlayer.OnErrorListener{

    private MediaPlayer mediaPlayer;
    private ArrayList<Mp3Info> mp3Infos;
    private int currentPosition;//列表当前位置
    private MusicUpdateListener musicUpdateListener;//设置属性
    private boolean isPause = false;

    //顺序播放、单曲循环、随机播放
    public static final int ORDER_PLAY = 1;
    public static final int RANDOM_PLAY = 2;
    public static final int SINGLE_PLAY = 3;
    public int play_mode = ORDER_PLAY;

    //用于设置或者获得播放模式
    public int getPlay_mode() {
        return play_mode;
    }

    public void setPlay_mode(int play_mode) {
        this.play_mode = play_mode;
    }

    //在fragment或者activity中轻松获得状态
    public boolean isPause(){
        return isPause;
    }

    //开启线程池
    private ExecutorService es = Executors.newSingleThreadExecutor();

    Runnable updateStatusRunnable = new Runnable() {
        @Override
        public void run() {
            while (true){
                if(musicUpdateListener!=null){
                    musicUpdateListener.onPublish(getCurrentProgress());
                }
            }
        }
    };

    public MusicPlayService() {

    }

    Random random = new Random();
    //用于监听当前歌曲播放完后,下一首该如何播放
    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        switch (play_mode){
            case ORDER_PLAY:
                next();
                break;
            case RANDOM_PLAY:
                play(random.nextInt(mp3Infos.size()));
                break;
            case SINGLE_PLAY:
                play(currentPosition);
                break;
            default:
                break;
        }
    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
        mediaPlayer.reset();
        return false;
    }

    class PlayBinder extends Binder{
        public MusicPlayService getMusicPlayService(){
            return MusicPlayService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mediaPlayer = new MediaPlayer();
        mp3Infos = MediaUtils.getMp3Infos(this);
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setOnErrorListener(this);
        //在进入每一个绑定service时,就监听进度改变事件,而状态改变监听则是在启动播放的时候
        es.execute(updateStatusRunnable);
    }

    //启动线程就得销毁
    @Override
    public void onDestroy() {
        super.onDestroy();
        if(es!=null && es.isTerminated()){
            es.shutdown();
            es = null;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new PlayBinder();
    }

    //点击列表上的某首歌播放
    public void play(int position){
        if(position>=0 && position<mp3Infos.size()){
            Mp3Info mp3Info = mp3Infos.get(position);
            try {
                mediaPlayer.reset();
                mediaPlayer.setDataSource(this, Uri.parse(mp3Info.getUrl()));
                mediaPlayer.prepare();
                mediaPlayer.start();
                currentPosition = position;
            }catch (IOException e){
                e.printStackTrace();
            }
            if(musicUpdateListener!=null){
                musicUpdateListener.onChange(currentPosition);
            }
        }
    }

    //点击播放按钮,从暂停转为播放状态
    public void start(){
        if(mediaPlayer!=null && !mediaPlayer.isPlaying()){
            mediaPlayer.start();
        }
    }

    //点击暂停按钮,从播放状态转为暂停状态
    public void pause(){
        if(mediaPlayer.isPlaying()){
            mediaPlayer.pause();
            isPause = true;
        }
    }

    //下一首
    public void next(){
        if(currentPosition >= mp3Infos.size()-1){
            currentPosition = 0;
        }else{
            currentPosition++;
        }
        play(currentPosition);
    }

    //上一首
    public void previous(){
        if(currentPosition<=0){
            currentPosition = mp3Infos.size()-1;
        }else{
            currentPosition--;
        }
        play(currentPosition);
    }

    //更新状态的接口
    public interface MusicUpdateListener{
        public void onPublish(int progress);
        public void onChange(int position);
    }

    public void setMusicUpdateListener(MusicUpdateListener musicUpdateListener) {
        this.musicUpdateListener = musicUpdateListener;
    }

    //在音乐播放中,获得播放的位置信息
    public int getDuration(){
        return mediaPlayer.getDuration();
    }

    //到目前为止,我都不知道这是干什么用的
    public void seekTo(int msec){
        mediaPlayer.seekTo(msec);
    }

    //返回当前的位置
    public int getCurrentPosition(){
        return currentPosition;
    }

    //获得当前位置
    public int getCurrentProgress(){
        if(mediaPlayer!=null && mediaPlayer.isPlaying()){
            return mediaPlayer.getCurrentPosition();
        }
        return 0;
    }

    //反馈状态
    public boolean isPlaying(){
        if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
            return mediaPlayer.isPlaying();
        }
        return false;
    }

}

基类BaseActivity(实现Demo中所有服务的绑定和解绑)

/**
 * 自定义基础activity,用来让其他activity继承,作为工具activity,用于绑定服务
 */
public abstract class BaseActivity extends FragmentActivity {

    protected MusicPlayService musicPlayService;
    private boolean isBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            MusicPlayService.PlayBinder playBinder = (MusicPlayService.PlayBinder)iBinder;
            musicPlayService = playBinder.getMusicPlayService();
            musicPlayService.setMusicUpdateListener(musicUpdateListener);
            //绑定成功后调用监听onChange方法
            musicUpdateListener.onChange(musicPlayService.getCurrentPosition());
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            musicPlayService = null;
            isBound = false;
        }
    };

    private MusicPlayService.MusicUpdateListener musicUpdateListener = new MusicPlayService.MusicUpdateListener(){
        @Override
        public void onPublish(int progress) {
            publish(progress);
        }

        @Override
        public void onChange(int position) {
            change(position);
        }
    };

    public abstract void publish(int progress);
    public abstract void change(int position);

    //绑定服务
    public void bindMusicPlayService(){
        if(!isBound){
            Intent intent = new Intent(this,MusicPlayService.class);
            bindService(intent,conn,BIND_AUTO_CREATE);
            isBound = true;
        }

    }

    //解除绑定服务
    public void unbindMusicPlayService(){
        if(isBound){
            unbindService(conn);
            isBound = false;
        }

    }
}

欢迎页面中启动服务(启动页面出代码已贴出)

LocalSongsActivity实现监听,点击不同音乐播放不同歌曲

public class LocalSongsActivity extends BaseActivity implements View.OnClickListener,AdapterView.OnItemClickListener{

    private ListView lv_local_songs_list;
    private ArrayList<Mp3Info> mp3Infos;
    private LocalSongsListAdapter localSongsListAdapter;
    private ImageView iv_backtrack,iv_album,iv_previous,iv_play,iv_next;
    private TextView tv_song_name1,tv_song_artist1;
    private RelativeLayout rl_music_play_control;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_local_songs);
        lv_local_songs_list = (ListView)findViewById(R.id.lv_local_songs_list);
        iv_backtrack = (ImageView)findViewById(R.id.iv_backtrack);
        iv_album = (ImageView) findViewById(R.id.iv_album);
        iv_play = (ImageView)findViewById(R.id.iv_play);
        iv_next = (ImageView)findViewById(R.id.iv_next);
        iv_previous = (ImageView)findViewById(R.id.iv_previous);
        tv_song_name1 = (TextView)findViewById(R.id.tv_song_name1);
        tv_song_artist1 = (TextView)findViewById(R.id.tv_song_artist1);
        rl_music_play_control = (RelativeLayout)findViewById(R.id.rl_music_play_control);
        rl_music_play_control.setOnClickListener(this);
        iv_play.setOnClickListener(this);
        iv_backtrack.setOnClickListener(this);
        iv_next.setOnClickListener(this);
        iv_previous.setOnClickListener(this);
        lv_local_songs_list.setOnItemClickListener(this);
        initDate();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    @Override
    protected void onResume() {
        super.onResume();
        //绑定播放服务
        bindMusicPlayService();
    }

    @Override
    protected void onPause() {
        super.onPause();
        unbindMusicPlayService();
    }

    /**
     * 初始化本地音乐列表
     */
    private void initDate() {
        mp3Infos = MediaUtils.getMp3Infos(this);
        System.out.println(mp3Infos.size());
        localSongsListAdapter = new LocalSongsListAdapter(this,mp3Infos);
        localSongsListAdapter.notifyDataSetChanged();
        lv_local_songs_list.setAdapter(localSongsListAdapter);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.iv_backtrack:
                finish();
                break;
            case R.id.iv_play:
                if(this.musicPlayService.isPlaying()){
                    this.musicPlayService.pause();
                    iv_play.setImageResource(R.drawable.play);
                }else{
                    if(this.musicPlayService.isPause()){
                        this.musicPlayService.start();
                        iv_play.setImageResource(R.drawable.pause);
                    }else {
                        this.musicPlayService.play(0);
                        iv_play.setImageResource(R.drawable.pause);
                    }
                }

                break;
            case R.id.iv_next:
                this.musicPlayService.next();
                iv_play.setImageResource(R.drawable.pause);
                break;
            case R.id.iv_previous:
                this.musicPlayService.previous();
                iv_play.setImageResource(R.drawable.pause);
                break;
            case R.id.rl_music_play_control:
                Intent intent = new Intent(this,PlayUIActivity.class);
                startActivity(intent);
                overridePendingTransition(R.anim.abc_fade_in, R.anim.abc_fade_out);
                break;
        }
    }
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        musicPlayService.play(position);
        iv_play.setImageResource(R.drawable.pause);
    }
    @Override
    public void publish(int progress) {

    }
    @Override
    public void change(int position) {
        //切换状态播放位置
        changeUIStatus(position);
    }
    //回调播放状态下的UI设置
    public void changeUIStatus(int position){
        if(position>=0 && position<mp3Infos.size()){
            Mp3Info mp3Info = mp3Infos.get(position);
            tv_song_name1.setText(mp3Info.getTitle());
            tv_song_artist1.setText(mp3Info.getArtist());

            if(musicPlayService.isPlaying()){
                iv_play.setImageResource(R.drawable.pause);
            }else {
                iv_play.setImageResource(R.drawable.play);
            }
            //Bitmap albumBitmap =  MediaUtils.getArtwork(this, mp3Info.getTitle(),mp3Info.getId(), mp3Info.getAlbumId(),true);
            Bitmap albumBitmap =  MediaUtils.getArtwork(this,mp3Info.getId(), mp3Info.getAlbumId(),true,false);
            if(albumBitmap==null){
                iv_album.setImageResource(R.drawable.music_play);
            }else{
                iv_album.setImageBitmap(albumBitmap);
            }
        }
    }
}

到这里,LocalSongsActivity此处的音乐就能播放了,切实现上一曲,下一曲,暂停等功能

时间: 2024-11-09 00:02:26

扣丁音乐(五)——service实现歌曲播放功能的相关文章

扣丁音乐(三)——UI框架的实现

本文出自:http://blog.csdn.net/dt235201314/article/details/51341057 一丶PagerSlidingTabStrp运用 扣丁音乐1.0前部分(gif图大小限制)演示: 视频教程中是直接将PagerSlidingTabStrp例子的主页面拿来做主页面,并对相应用到的地方做出修改 修改一: activity_main.xml 保留如下,其余控件删除 <com.astuetz.PagerSlidingTabStrip android:id="

扣丁音乐(四)——本地音乐加载

本文出自:http://blog.csdn.net/dt235201314/article/details/51341078 一丶本地音乐加载相当于就是listVIew应用 扣丁音乐1.0前部分(gif图大小限制)演示: 实体类Mp3Info(歌曲相关数据及get和set方法) public class Mp3Info { private long id; private String title;//歌名 private String artist;//艺术家 private String a

Android基础(五) Service全解析----看不见的Activity

一.服务的介绍: 作为Android四大组件之中的一个,Service(服务)也常常运用于我们的日常使用中,它与Activity的差别在于:Service一直在后台执行.没实用户界面.所以绝不会到前台来.但Service被启动起来之后.它就和Activity一样.全然具有自己的生命周期. 在关于程序中是选择用Activity还是Service的一个选择标准就是:假设某个程序组件须要执行时向用户呈现某种用户界面.或者该程序须要与用户交互,就须要使用Activity,否则就该考虑使用Service.

在线教育遭遇瓶颈,扣丁引领教育O2O时代

2014年,在线教育的发展遇到了冷空气:梯子网.那好网关闭,传课网.91外教网被收购,多贝公开课转型--据不完全统计,2014年至少50家小有名气的在线教育企业倒闭或被收购,最短存活周期不超过3个月. 在互联网教育研究院院长吕森林看来,在线教育行业泡沫已经显现,而且这是继2005年前后在线教育的第二次泡沫.伴随着泡沫期同时出现的必定是一批在线教育企业的倒下,大多数在线教育企业会在未来2-3年内相继倒闭,2015年会是倒闭潮井喷期. 在线教育规模小  盈利成困局 据有关统计,2013年有数十亿资金

【扣丁学堂】给自己一个机会、人生才能华丽转身!

每日一课:扣丁学堂 毕业2年没有找到工作,在扣丁学堂学习4个月iOS开发,年薪15万. 我叫曾加,来自北方的坝上草原,08年毕业于张家口建筑学院,计算机系,由于是一个专科学校,加之学校学习的课程离企业开发相差甚远.辗转2年相继在张家口.北京.天津几个城市找工作都没有什么结果-, 直到2015年4月在网上无意中发现了扣丁学堂这个网站,上面专门是讲移动开发的,有iOS.Android和Cocos2d-x游戏开发等课程.课程很系统.很精细.这里提供了免费的视频课程. 因为找了两年工作了也很着急,俗话说

【扣丁学堂】威哥:Android会死,你还学吗?

每日一课:扣丁学堂 标题这个问题笔者被很多童鞋问了N次,不管是QQ里.微信里.微博里.还是更私密的电话里,我可以想像他们那一脸茫然的表情里,渴望从你那里得到一点点信息,或是表示惊讶,或是对自己即将要选择的路再给一次犹豫的机会来证明自己的慎重,再或是可以在家人同学朋友面前炫耀一下:"我对自己的未来是有长远考虑的".所以,写这篇文章的目的,我不是想讨论Android会不会真的死,你应不应该去学等这些问题,因为这就好像在讨论是先有鸡,还是先有蛋的问题,结果只是个人的片面理解而已,我只想给初入

.NET小项目之MyKtv(歌曲播放功能实现)

在KTV点歌系统中我们根据需求获取到歌手的歌曲信息,点击歌手的歌曲将其添加到一点歌曲列表中看似简单的一个操作其实涉及很多内容,这也是写这篇Blog的目的—分析歌曲播放的原理. 原理分析 我们应该清楚,在KTV中点歌后会将歌曲添加到已点列表中,已点列表,这时候播放器会根据已点列表里的歌曲顺序去播放歌曲.具体如何实现该功能,我们一步步来分析. 首先我们应该创建一个播放列表类,用来存储已点列表,以及已点列表操作相对应的方法. 创建Song类来保存歌曲对象, 枚举类SongPlayState歌曲的播放状

【扣丁学堂】月薪1700元退伍兵哥蜕变为月薪万元IT男

IT教程视频:扣丁学堂 季晓健,2007年中专毕业后,谋求到一份还算稳定的工作,在某市药品仓库当管理员,月薪1700元.这份工作在父母.亲戚看来还算不错,但小季心里却并不这么认为.他从即将退休的50多岁的老员工身上看见了自己的未来 -- 在一成不变且没有前途的工作中虚度时光,如果不做出改变,未来的自己也将是这样熬到退休!小季想想都觉得可怕,改变现状成为他内心深处的渴望! 在深思熟虑之后,小季做出了人生的第一次改变 --入伍当兵.2008年,小季应征入伍,这是一条可以改变命运的选择 -- 中国很多

【扣丁学堂】10个理由让你继续干IT

每日一课:扣丁学堂 作为iOS与Android培训领头羊的扣丁学堂,对iOS与Android的研究都是走在互联网发展的潮流最前沿,把最新最好的技术教导给学生. 在课程体系外,还有很多有趣的IT资讯分享给大家: 我曾在"正规"IT这个行当中几进几出.已经从挫折这所学校里面了解到了许多坚守下来的理由.说实话,或多或少地,上述每一条我都有做不到的地方.当你真正了解了干IT的基本理由之后,你就会知道,是IT而不是别的职业能够满足技术头脑的更多需求. 1.钱,钱,钱 对,我们努力工作就是为了赚钱