今天我们来写一个超级超级简单的播放器,使用到的是android自带的音乐播放器类MediaPlayer,先上一张效果图:
里面只实现了播放器额基本功能,界面就不做了,因为不是重点哈。
代码:
1. layout/ activty_main.xml
<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" tools:context=".MainActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/btn_pre" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="pre" /> <Button android:id="@+id/btn_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="stop" /> <Button android:id="@+id/btn_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_play" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="play" /> <Button android:id="@+id/btn_next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="next" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/music_listview" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout></LinearLayout>
2. MainActivity.java :
package com.example.ch7_01_mediaplayer;import java.io.File;import java.io.FilenameFilter;import java.io.IOException;import java.util.ArrayList;import java.util.List;import android.media.MediaPlayer;import android.os.Bundle;import android.app.Activity;import android.content.Context;import android.view.Menu;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.ListView;public class MainActivity extends Activity { private Context mContext = this; private static final String MUSIC_PATH = new String("/sdcard/"); private List<String> mMusicList = new ArrayList<String>(); private ListView mMusicListView; private int mCurrentMusicItem = 0; private MediaPlayer mMediaPlayer = null; private Button mBtnStop = null; private Button mBtnPause = null; private Button mBtnPlay = null; private Button mBtnNext = null; private Button mBtnPre = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMediaPlayer = new MediaPlayer(); mBtnStop = (Button) findViewById(R.id.btn_stop); mBtnPause = (Button) findViewById(R.id.btn_pause); mBtnPlay = (Button) findViewById(R.id.btn_play); mBtnNext = (Button) findViewById(R.id.btn_next); mBtnPre = (Button) findViewById(R.id.btn_pre); mMusicListView = (ListView) findViewById(R.id.music_listview); getMusicList(); // 获取音乐播放列表 mBtnStop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mMediaPlayer.isPlaying()) { mMediaPlayer.reset(); } } }); mBtnPause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); mBtnPause.setText("continue"); } else { mMediaPlayer.start(); mBtnPause.setText("pause"); } } }); mBtnPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { playMusic(MUSIC_PATH + mMusicList.get(mCurrentMusicItem)); } }); mBtnNext.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { nextMusic(); } }); mBtnPre.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { preMusic(); } }); } private void playMusic(String path) { try { mMediaPlayer.reset(); mMediaPlayer.setDataSource(path); mMediaPlayer.prepare(); mMediaPlayer.start(); mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { nextMusic(); } }); } catch (Exception e) { e.printStackTrace(); } } private void getMusicList() { File home = new File(MUSIC_PATH); if (home.listFiles(new MusicFilter()).length > 0) { for (File file : home.listFiles(new MusicFilter())) { mMusicList.add(file.getName()); } ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, R.layout.music_item,R.id.music_item_tv, mMusicList); mMusicListView.setAdapter(adapter); mMusicListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> l, View view, int position, long id) { mCurrentMusicItem = position; playMusic(MUSIC_PATH + mMusicList.get(mCurrentMusicItem)); } }); } } private void nextMusic() { if (++mCurrentMusicItem >= mMusicList.size()) { mCurrentMusicItem = 0; } playMusic(MUSIC_PATH + mMusicList.get(mCurrentMusicItem)); } private void preMusic(){ if(--mCurrentMusicItem < 0){ mCurrentMusicItem = mMusicList.size()-1; } playMusic(MUSIC_PATH + mMusicList.get(mCurrentMusicItem)); } class MusicFilter implements FilenameFilter { @Override public boolean accept(File dir, String filename) { return filename.endsWith("mp3"); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override protected void onDestroy() { super.onDestroy(); mMediaPlayer.stop(); mMediaPlayer.reset(); mMediaPlayer.release(); } @Override protected void onResume() { super.onResume(); if(mMediaPlayer.isPlaying()){ mBtnPause.setText("pause"); } else{ mBtnPause.setText("continue"); } }}
3. 这里还用到了listview,所有还有一个资源文件: layout/ music_item.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="50dp" > <TextView android:id="@+id/music_item_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" /></RelativeLayout>
讲解篇:
代码有点多,我们就调重点讲。首先来介绍一下MediaPlayer这个类,是android中专门用来处理播放音乐请求的,在独立的线程当中,生命周期不随Anctivity一起消亡。
生命周期:
解释一下:要使用MediaPlayer需要先new一个对象出来,然后调用其 reset() 方法进入 idle 状态, 通过 setDataSource() 可以设置播放目录,进入 initalized状态, 然后调用 prepare()方法进入 prepare状态,这个时候就可以调用 start()方法开始播放音乐。暂停和停止分别调用 pause() 和 stop() 方法。 在退出的时候最好是先回到 idle 状态,就是调用 reset() ,然后再调用 release()就可以退出。
来看看代码是怎么写的:
播放音乐:
private void playMusic(String path) { try { mMediaPlayer.reset(); mMediaPlayer.setDataSource(path); mMediaPlayer.prepare(); mMediaPlayer.start(); mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { nextMusic(); } }); } catch (Exception e) { e.printStackTrace(); } }我们可以看到完全是按照生命周期来走的, reset() -> setDataSource() -> prepare() -> start() , 这里path是音乐文件的具体路径(作为入参), 这里设置了监听事件: OnCompletionListener,就是当一首音乐播放完时自动触发,这里我们直接播放下一首音乐。如果你想做一个功能单曲循环的话,那么直接再播当前的音乐就可以了,是不是很简单。
停止(stop):如果再播放,直接reset 到初始状态
if (mMediaPlayer.isPlaying()) { mMediaPlayer.reset();}
暂停(pause):判断是否在播放,如果在播放就暂停,并且设置暂停按钮为 继续, 如果是继续按钮,点击之后播放音乐,设置按钮为 暂停。我们这里用文字来代替。
if (mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); mBtnPause.setText("continue");} else { mMediaPlayer.start(); mBtnPause.setText("pause");}
下一首:这里我们需要一个类变量 mCurrentMusicItem 标志当前播放的是哪个位置上的歌曲,也就是第几首歌。如果到最后就循环到0,继续播放。
private void nextMusic() { if (++mCurrentMusicItem >= mMusicList.size()) { mCurrentMusicItem = 0; } playMusic(MUSIC_PATH + mMusicList.get(mCurrentMusicItem)); }
上一首:和下一首的思想一样,不做解释
private void preMusic(){ if(--mCurrentMusicItem < 0){ mCurrentMusicItem = mMusicList.size()-1; } playMusic(MUSIC_PATH + mMusicList.get(mCurrentMusicItem)); }
我们需要来看一看传入到 playMusic(String path)参数到底是什么?
这里将音乐播放路径设置为 " mnt/sdcard/ " :
private static final String MUSIC_PATH = new String("/sdcard/");
然后在目录下,将所有后缀为“MP3”的文件添加到 mMusicList<String> 当中,拼接就可以得到音乐的路径,例如: mnt/sdcard/Dreamer.mp3 , 注意 " /sdcard/ " 的第一个 "/" 表示根目录,其实就是 " mnt/“ , 这是从linux来的,大家不要误会。
private List<String> mMusicList = new ArrayList<String>();
private void getMusicList() { File home = new File(MUSIC_PATH); if (home.listFiles(new MusicFilter()).length > 0) { for (File file : home.listFiles(new MusicFilter())) { mMusicList.add(file.getName()); } ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, R.layout.music_item,R.id.music_item_tv, mMusicList); mMusicListView.setAdapter(adapter); mMusicListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> l, View view, int position, long id) { mCurrentMusicItem = position; playMusic(MUSIC_PATH + mMusicList.get(mCurrentMusicItem)); } }); } }
最后我们需要在Activity生命周期中调用 MediaPlayer的生命周期,否则当你Activity被销毁的时候,MediaPlayer还在那儿瞎放,岂不是很老火:
@Override protected void onDestroy() { super.onDestroy(); mMediaPlayer.stop(); mMediaPlayer.reset(); mMediaPlayer.release(); }
这里已经把音乐播放器最核心的代码谢了,如果要做扩展是很好扩展的,修改界面,修改音乐列表等,希望对大家有帮助。