Android音乐播放器的简单实现

1、MusicService

音乐播放器的Service,里面获取音乐文件,封装了MediaPlayer,实现播放上一首和下一首,播放,停止,封装成方法供Activity调用,获取音乐的当前进度,总长度、名字,通过发送广播的方式发给Activity

package com.example.musicplayer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;

public class MusicService extends Service {

    private List<File> musicList;
    private MediaPlayer player;
    //选择把媒体播放器放在服务
    public static final String MFILTER = "broadcast.intent.action.text";
    public final static String NAME = "name";
    public final static String TOTALTIME = "totaltime";
    public final static String CURTIME = "curtime";
    public int curPage;

    class MyBinder extends Binder {
        public MusicService getMusicService() {
            return MusicService.this;
        }

        public MediaPlayer getPlayer() {
            return player;
        }
        public void seekTo(int position)
        {
            if(player!=null)
            {
                player.seekTo(position);
            }
        }
    }
    //获取当前播放进度
    public int getMusicCurTime()
    {
        int curTime=0;
        if(player!=null)
        {
            curTime=player.getCurrentPosition();
        }
        return curTime;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return new MyBinder();
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        musicList = new ArrayList<File>();
        // Environment.getExternalStorageDirectory()是获取sd中的内容的
        Log.d(null, "1s");
        File rootFile = Environment.getExternalStorageDirectory();
        Log.d(null, "2s");
        fillMusicList(rootFile);
        Log.d(null, "3s");
        player = new MediaPlayer();
        if (musicList.size() != 0) {
            startPlay();
        }
        Log.d(null, "4s");
        //监听事件,网络流媒体播放结束监听 
        player.setOnCompletionListener(new OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                // 重置 MediaPlayer 对象 
                mp.reset();
                curPage=curPage==musicList.size()-1 ? (curPage-1)%musicList.size(): curPage+1;
                startPlay();
            }
        });

    }
    public void playNext()
    {
        curPage=curPage==musicList.size()-1?(curPage+1)%musicList.size():curPage+1;
        player.reset();
        startPlay();
    }

    public void playPre()
    {
        curPage=curPage==0?0:curPage-1;
        player.reset();
        startPlay();
    }
    public void parse(){
        player.pause();
    }
    public void reStart()
    {
        player.start();
    }
    public void startPlay() {
        mSendBroadCast(NAME, musicList.get(curPage).getName());
        try{
            //设置播放的文件
            player.setDataSource(musicList.get(curPage).getAbsolutePath());
            player.prepare();
            player.start();
            player.getDuration();
            mSendBroadCast(TOTALTIME, player.getDuration());
            Timer timer=new Timer();
            //将当前进度随着当地播放器的进度发广播到activity
            timer.schedule(new TimerTask() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    mSendBroadCast(CURTIME, player.getCurrentPosition());
                }
            },0, 1000);//这里缺少0,delay毫秒后重复的执行task,周期是period毫秒


        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void mSendBroadCast(String key, String value) {
        Intent intent = new Intent(MFILTER);
        intent.putExtra(key, value);
        sendBroadcast(intent);
    }
    private void mSendBroadCast(String key, int value) {
        Intent intent = new Intent(MFILTER);
        intent.putExtra(key, value);
        sendBroadcast(intent);
    }

    /* 迭代获取的音乐文件 */
    public void fillMusicList(File musicFile) {
        File[] sources = musicFile.listFiles();
        for (File file : sources) {
            // 判断是不是目录,否则是文件
            if (file.isDirectory()) {
                fillMusicList(file);
            } else {
                String name = file.getName();
                if (name.endsWith(".mp3") || name.endsWith(".acc")) {
                    musicList.add(file);
                }
            }
        }
    }

}

2、MusicActivity

主要是组件功能的实现,直接通过Service获取各种信息,相关播放功能

package com.example.musicplayer;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.http.util.EncodingUtils;

import com.example.musicplayer.MusicService.MyBinder;
import com.example.musicplayer.MusicService;

import android.R.layout;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class MusicActivity extends Activity implements OnClickListener{

    public MusicService mService;
    public MyBinder myBinder;
    ServiceConnection conn;
    public boolean isStop;

    public SeekBar seekBar;
    TextView curTime;
    TextView totalTime;
    TextView title;
     public  double totalTimeInt;
     public  double curTimeInt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(null, "1");
        IntentFilter filter = new IntentFilter(MusicService.MFILTER);
        Log.d(null, "2");
        //广播动态注册
        registerReceiver(new MusicReceiver(), filter);

         conn = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                mService = null;
            }

            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                mService = ((MyBinder) service).getMusicService();
            }
        };


        init();

        setListener();
    }

    private void setListener() {
        // TODO Auto-generated method stub
        seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
                // fromUser判断是用户改变的滑块的值
                if(fromUser==true)
                {
                    myBinder.seekTo(progress);
                }

            }
        });
    }

    public void init()
    {
        Button previous = (Button) findViewById(R.id.previous);
        Button next = (Button) findViewById(R.id.next);
        Button stop = (Button) findViewById(R.id.stop);
        Button stopService = (Button) findViewById(R.id.stopService);
        seekBar = (SeekBar) findViewById(R.id.mSeekbar);
        curTime = (TextView) findViewById(R.id.curTime);
        totalTime = (TextView) findViewById(R.id.totalTime);
        title = (TextView) findViewById(R.id.title);

        previous.setOnClickListener(this);
        next.setOnClickListener(this);
        stop.setOnClickListener(this);
        stopService.setOnClickListener(this);

        //将歌曲的长度设置为播放进度条的最大值
//      seekBar.setMax((int)totalTimeInt);
    }

//  Handler handler=new Handler();
//  Runnable updateThread=new Runnable()
//  {
//      public void run() {
//          //获取歌曲现在播放位置并设置成播放进度条的值
//          seekBar.setProgress((int)curTimeInt);
//          //每次延迟1000毫秒再启动线程
//          handler.postDelayed(updateThread, 1000);
//      }
//  };


    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        Intent intent=new Intent(MusicActivity.this,MusicService.class);
        intent.setAction("com.intent.musicplayer.MusicService");
        Log.d(null, "3");
        bindService(intent, conn, BIND_AUTO_CREATE);
        Log.d(null, "4");
    }
     class MusicReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // 如果没有取到,默认值为0,不为0说明取到
            if(intent.getIntExtra(MusicService.CURTIME, 0)!=0)
            {
                curTimeInt=intent.getIntExtra(MusicService.CURTIME, 0);
                curTime.setText(transferMilliToTime((int)curTimeInt));
                 double result = curTimeInt/totalTimeInt*100;
                 seekBar.setProgress((int) Math.floor(result));

            }else if(intent.getIntExtra(MusicService.TOTALTIME, 0)!=0)
            {
                totalTimeInt=intent.getIntExtra(MusicService.TOTALTIME, 0);
                totalTime.setText(transferMilliToTime((int)totalTimeInt));
            }
            else if(!TextUtils.isEmpty(intent.getStringExtra(MusicService.NAME)))
            {
                String result=intent.getStringExtra(MusicService.NAME);
                try {
                    title.setText(EncodingUtils.getString(result.getBytes("GB2312"), "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    // 将毫秒转换为时间格式
    private String transferMilliToTime(int Millis) {
        SimpleDateFormat format = new SimpleDateFormat("mm:ss");
        String result = format.format(new Date(Millis));
        return result;

    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.previous:
            mService.playPre();
            break;
        case R.id.next:
            mService.playNext();
            break;
        case R.id.stop:
            if(isStop)
            {
                mService.reStart();
            }else
            {
                mService.parse();
            }
            isStop=!isStop;
            break;
        case R.id.stopService:
            Intent intent =new Intent("com.intent.musicplayer.MusicService");
            unbindService(conn);
            stopService(intent);
            break;
        default:
            break;
        }
    }
}

注册Service

注意(不用在配置文件注册广播,因为广播是通过registerReceiver(new MusicReceiver(), filter);动态注册了)

  <service android:name="com.example.musicplayer.MusicService" >
            <intent-filter>
                <action android:name="com.intent.musicplayer.MusicService" />
            </intent-filter>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值