您的位置:首页 > 移动开发 > Android开发

Android之多媒体MediaPlayer(一个简单的音乐播放器)

2015-09-09 20:13 507 查看

音乐播放器

MediaPlayer:

利用Environment.getExternalStorageDirectory()方法得到sdcard路径,然后用new File(得到的sdcard父路径,子路径)得到音乐存放路径。用File[]型的数组存放得到的所有音乐文件,接着就可以播放。

用MediaPlay需要在manifests中申请权限android.permission.READ_EXTERNAL_STORAGE。

本实例用于实现一个简单的音乐播放器,用ListView来显示音乐清单。

代码:

public class MainActivity extends Activity {
    private Button mButtonStart;
    private File[] mMusics;
    private ListView mMusicList;
    private MusicAdapter mAdapter;
    private LayoutInflater mInflater;
    private SeekBar mMusicSeekBar;
    private TextView mTimeText;

    private MusicReceiver mReceiver;
    private int duration;
    private int currentTime;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButtonStart = (Button) findViewById(R.id.button_start_music);
        mMusicList = (ListView) findViewById(R.id.list_view_musics);
        mMusicSeekBar = (SeekBar) findViewById(R.id.music_seek_bar);
        mTimeText = (TextView) findViewById(R.id.text_time);

        initMusicData();
        mInflater = getLayoutInflater();
        mAdapter = new MusicAdapter(mMusics,mInflater);
        mMusicList.setAdapter(mAdapter);

        mReceiver = new MusicReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.music.play");
        registerReceiver(mReceiver, filter);

        mMusicList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                changeMusic(mMusics[position]);
            }
        });

        mMusicSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                changeProgress();
            }
        });

    }
    //当拖动SeekBar进度条时调用此方法,向MusicService服务发送进度条的进度,服务器收到消息后会作出让当前播放音频进度同步于进度条的操作
    private void changeProgress() {
        Intent intent = new Intent(getApplicationContext(),MusicService.class);
        int progress = mMusicSeekBar.getProgress();
        intent.putExtra("type", Config.CHANGE_PROGRESS);
        intent.putExtra("progress",progress);
        startService(intent);
    }

    //当点击ListView时调用该方法,向MusicService发出要更换曲目的消息
    private void changeMusic(File mMusic) {
        Intent intent = new Intent(getApplicationContext(), MusicService.class);
        intent.putExtra("type", Config.CHANGE_MUSIC);
        intent.putExtra("musicName", mMusic.getAbsolutePath());
        startService(intent);
    }

    private void initMusicData(){
        //得到外部存储中音频文件存储的路径
        File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
        mMusics = musicDir.listFiles();
}
    //此广播***用于接收来自音乐服务的信息,并作出响应
    private class MusicReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            int type = intent.getIntExtra("type",0);
            switch (type){
                case 0:
                    duration = intent.getIntExtra("duration",0);
                    mMusicSeekBar.setMax(duration);
                    //将seekBar进度条的进度容量设定为音频的长度
                    break;
                case 1:
                    currentTime = intent.getIntExtra("time",0);
                    mMusicSeekBar.setProgress(currentTime);
                    mTimeText.setText(myTimeFormat(currentTime)+"/"+myTimeFormat(duration));//将seekbar的进度大小设定为当前音乐播放的进度
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(mReceiver);
    }
    //当要将得到的音乐进度和总长度转换为XX(分):XX(秒)形式时调用该函数
    public String myTimeFormat(long time){
        long miao = time/1000;
        long fen = miao/60;
        long yumiao = miao%60;
        String backTime = "";
        if(miao>0){
            backTime = fen+":"+yumiao;
        }else{
            backTime = ""+yumiao;
        }
        return backTime;
    }
    //点击后退键不停止活动
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_BACK){
            moveTaskToBack(false);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}


建立一个服务Service

public class MusicService extends Service {
    private MediaPlayer mPlayer;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
        int type = intent.getIntExtra("type", 1

        );
        //判断type以完成不同的操作
        switch (type) {
            case 0:
                startNewMusic(intent);
                break;
            case 1:
                if (mPlayer != null) {
                    int progress = intent.getIntExtra("progress", 0);
                    mPlayer.seekTo(progress);//设置曲目进度
                }
                break;
            default:
                break;
        }
        return super.onStartCommand(intent, flags, startId);
    }
    //此方法用于得到被点击的音频的绝对路径并播放
    private void startNewMusic(Intent intent) {
        String musicPath = intent.getStringExtra("musicName");
        if (mPlayer == null) {
            mPlayer = new MediaPlayer();
        }
        mPlayer.reset();
        try {
            mPlayer.setDataSource(musicPath);
            mPlayer.prepare();
            mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                    int duration = mPlayer.getDuration();//得到总的播放的时间
                    Intent intent = new Intent("com.music.play");
                    intent.putExtra("type", 0);
                    intent.putExtra("duration", duration);
                    sendBroadcast(intent);
                    MusicPlayThread musicPlayThread = new MusicPlayThread();
                    musicPlayThread.start();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //这个线程用于发送音乐播放的进度,理论上每1秒发送一次
    class MusicPlayThread extends Thread {
        @Override
        public void run() {
            while (mPlayer.isPlaying()) {
                int time = mPlayer.getCurrentPosition();//得到当前播放的时间
                Intent intent = new Intent("com.music.play");
                intent.putExtra("type", 1);
                intent.putExtra("time", time);
                sendBroadcast(intent);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}


MusicListView的adapter

public class MusicAdapter extends BaseAdapter {

    private File[] mMusics;
    private LayoutInflater mInflater;

    public MusicAdapter(File[] mMusics, LayoutInflater mInflater) {
        this.mMusics = mMusics;
        this.mInflater = mInflater;
    }

    @Override
    public int getCount() {
        return mMusics.length;
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder vh = null;
        if(convertView==null){
            convertView = mInflater.inflate(R.layout.music_item,null);
            vh = new ViewHolder();
            vh.musicName = (TextView) convertView.findViewById(R.id.text_music_name);
            vh.artistImage = (ImageView)convertView.findViewById(R.id.image_artist);
            vh.artistName = (TextView) convertView.findViewById(R.id.text_artist_name);
            convertView.setTag(vh);
        }else{
            vh = (ViewHolder) convertView.getTag();
        }
        String musicName = mMusics[position].getName();
        vh.musicName.setText(musicName);
        //MediaMetadataRetriever用于得到音乐文件的一些信息,如图片,艺术家等
        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        //MediaMetadataRetriever不能加载非音频文件,否则会出错
        mmr.setDataSource(mMusics[position].getAbsolutePath());
        //得到歌手名
        String author = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
        if(author!=null){
            vh.artistName.setText(author);
        }else{
            vh.artistName.setText("<未知>");
        }
        //得到音乐的图片,但很多音频文件不含图片
        byte[] image = mmr.getEmbeddedPicture();
        if(image!=null){
            Bitmap bitmap = BitmapFactory.decodeByteArray(image,0,image.length);
            vh.artistImage.setImageBitmap(bitmap);
        }else{
            vh.artistImage.setImageResource(R.mipmap.photo_nomal);
        }
        return convertView;
    }

    class ViewHolder{
        ImageView artistImage;
        TextView musicName;
        TextView artistName;
    }
}


布局

<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <ListView
        android:id="@+id/list_view_musics"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">

    </ListView>

    <Button
        android:id="@+id/button_start_music"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:text="开始音乐"/>

    <SeekBar
        style="?android:attr/seekBarStyle"
        android:id="@+id/music_seek_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/text_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingRight="15dp"
        android:gravity="right"/>

</LinearLayout>


music_item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center_vertical"
              android:padding="15dp">
    <ImageView
        android:id="@+id/image_artist"
        android:layout_width="30dp"
        android:layout_height="30dp"/>
    <TextView
        android:id="@+id/text_music_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:layout_marginLeft="20dp"/>

    <TextView
        android:id="@+id/text_artist_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"/>
</LinearLayout>


结果展示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: