音乐播放
MediaPlayer mediaPlayer = new MediaPlayer();
if (mediaPlayer.isPlaying()) {mediaPlayer.reset();//重置为初始状态
}
mediaPlayer.setDataSource("/mnt/sdcard/god.mp3");
mediaPlayer.prepare();
mediaPlayer.start();//开始或恢复播放
mediaPlayer.pause();//暂停播放
mediaPlayer.start();//恢复播放
mediaPlayer.stop();//停止播放
mediaPlayer.release();//释放资源
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {//播出完毕事件
@Override public void onCompletion(MediaPlayer arg0) {
mediaPlayer.release();
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {// 错误处理事件
@Override public boolean onError(MediaPlayer player, int arg1, int arg2) {
mediaPlayer.release();
return false;
}
});
示例
个人经验,实际上播放时间不用他写的那么复杂,直接
et_time.setBase(SystemClock.elapsedRealtime()-mediaPlayer.
getCurrentPosition()
);
et_time.start();
public
class
DemoActivity
extends
Activity
implements
OnClickListener,
OnChronometerTickListener, OnSeekBarChangeListener {
private
EditText et_path;
private
Chronometer et_time;
private
SeekBar sb;
private
Button bt_play, bt_pause, bt_replay, bt_stop;
private
MediaPlayer mediaPlayer;
private
TelephonyManager manager;
/**
* subtime:点击“续播”到暂停时的间隔的和 beginTime:重新回到播放时的bash值 falgTime:点击“播放”时的值
* pauseTime:“暂停”时的值
*/
private
long
subtime =
0
, beginTime =
0
, falgTime =
0
, pauseTime =
0
;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
manager = (TelephonyManager)
this
.getSystemService(TELEPHONY_SERVICE);
manager.listen(
new
MyListener(), PhoneStateListener.LISTEN_CALL_STATE);
sb = (SeekBar)
this
.findViewById(R.id.sb);
et_path = (EditText)
this
.findViewById(R.id.et_path);
et_time = (Chronometer)
this
.findViewById(R.id.et_time);
bt_play = (Button)
this
.findViewById(R.id.play);
bt_pause = (Button)
this
.findViewById(R.id.pause);
bt_replay = (Button)
this
.findViewById(R.id.replay);
bt_stop = (Button)
this
.findViewById(R.id.stop);
sb.setEnabled(
false
);
sb.setOnSeekBarChangeListener(
this
);
bt_play.setOnClickListener(
this
);
bt_pause.setOnClickListener(
this
);
bt_replay.setOnClickListener(
this
);
bt_stop.setOnClickListener(
this
);
et_time.setOnChronometerTickListener(
this
);
}
Handler handler =
new
Handler();
Runnable updateThread =
new
Runnable() {
public
void
run() {
// 获得歌曲现在播放位置并设置成播放进度条的值
if
(mediaPlayer !=
null
) {
sb.setProgress(mediaPlayer.getCurrentPosition());
// 每次延迟100毫秒再启动线程
handler.postDelayed(updateThread,
100
);
}
}
};
public
void
onClick(View v) {
String path;
try
{
switch
(v.getId()) {
case
R.id.play:
falgTime = SystemClock.elapsedRealtime();
path = et_path.getText().toString().trim();
play(path);
pauseTime =
0
;
et_time.setBase(falgTime);
et_time.start();
break
;
case
R.id.pause:
pause();
break
;
case
R.id.replay:
if
(mediaPlayer !=
null
&& mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(
0
);
et_time.setBase(SystemClock.elapsedRealtime());
et_time.start();
}
else
{
path = et_path.getText().toString().trim();
play(path);
et_time.setBase(SystemClock.elapsedRealtime());
et_time.start();
}
if
(
"续播"
.equals(bt_pause.getText().toString().trim())) {
bt_pause.setText(
"暂停"
);
}
falgTime = SystemClock.elapsedRealtime();
subtime =
0
;
break
;
case
R.id.stop:
if
(mediaPlayer !=
null
&& mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer =
null
;
et_time.setBase(SystemClock.elapsedRealtime());
et_time.start();
et_time.stop();
bt_play.setEnabled(
true
);
bt_play.setClickable(
true
);
}
falgTime =
0
;
subtime =
0
;
sb.setProgress(
0
);
sb.setEnabled(
false
);
break
;
}
}
catch
(Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"文件播放出现异常"
,
0
).show();
}
}
private
void
pause() {
// 判断音乐是否在播放
if
(mediaPlayer !=
null
&& mediaPlayer.isPlaying()) {
// 暂停音乐播放器
mediaPlayer.pause();
bt_pause.setText(
"续播"
);
sb.setEnabled(
false
);
et_time.stop();
pauseTime = SystemClock.elapsedRealtime();
// System.out.println("1 pauseTime" + pauseTime);
}
else
if
(mediaPlayer !=
null
&&
"续播"
.equals(bt_pause.getText().toString())) {
subtime += SystemClock.elapsedRealtime() - pauseTime;
// System.out.println("2 subtime:" + subtime);
mediaPlayer.start();
bt_pause.setText(
"暂停"
);
sb.setEnabled(
true
);
beginTime = falgTime + subtime;
// System.out.println("3 beginTime" + beginTime);
et_time.setBase(beginTime);
et_time.start();
}
}
/**
* 播放指定地址的音乐文件 .mp3 .wav .amr
*
* @param path
*/
private
void
play(String path)
throws
Exception {
if
(
""
.equals(path)) {
Toast.makeText(getApplicationContext(),
"路径不能为空"
,
0
).show();
return
;
}
File file =
new
File(path);
if
(file.exists()) {
mediaPlayer =
new
MediaPlayer();
mediaPlayer.setDataSource(path);
// mediaPlayer.prepare(); // c/c++ 播放器引擎的初始化
// 同步方法
// 采用异步的方式
mediaPlayer.prepareAsync();
// 为播放器注册
mediaPlayer.setOnPreparedListener(
new
OnPreparedListener() {
public
void
onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaPlayer.start();
bt_play.setEnabled(
false
);
bt_play.setClickable(
false
);
sb.setMax(mediaPlayer.getDuration());
handler.post(updateThread);
sb.setEnabled(
true
);
}
});
// 注册播放完毕后的监听事件
mediaPlayer.setOnCompletionListener(
new
OnCompletionListener() {
public
void
onCompletion(MediaPlayer mp) {
mediaPlayer.release();
mediaPlayer =
null
;
bt_play.setEnabled(
true
);
bt_play.setClickable(
true
);
et_time.setBase(SystemClock.elapsedRealtime());
et_time.start();
et_time.stop();
sb.setProgress(
0
);
}
});
}
else
{
Toast.makeText(getApplicationContext(),
"文件不存在"
,
0
).show();
return
;
}
}
private
class
MyListener
extends
PhoneStateListener {
@Override
public
void
onCallStateChanged(
int
state, String incomingNumber) {
super
.onCallStateChanged(state, incomingNumber);
switch
(state) {
case
TelephonyManager.CALL_STATE_RINGING:
// 音乐播放器暂停
pause();
break
;
case
TelephonyManager.CALL_STATE_IDLE:
// 重新播放音乐
pause();
break
;
}
}
}
public
void
onChronometerTick(Chronometer chronometer) {
}
public
void
onProgressChanged(SeekBar seekBar,
int
progress,
boolean
fromUser) {
// TODO 自动生成的方法存根
if
(fromUser ==
true
&& mediaPlayer !=
null
) {
mediaPlayer.seekTo(progress);
falgTime = SystemClock.elapsedRealtime();
beginTime = falgTime - sb.getProgress();
et_time.setBase(beginTime);
et_time.start();
}
}
public
void
onStartTrackingTouch(SeekBar seekBar) {
// TODO 自动生成的方法存根
}
public
void
onStopTrackingTouch(SeekBar seekBar) {
// TODO 自动生成的方法存根
}
}
使用SoundPool播放音效:
在 Android开发中我们经常使用MediaPlayer来播放音频文件,但是MediaPlayer存在一些不足,例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想,例如在对时间精准度要求相对较高的游戏开发中。在游戏开发中我们经常需要播放一些游戏音效(比如:子弹爆炸,物体撞击等),这些音效的共同特点是短促、密集、延迟程度小。在这样的场景下,我们可以使用SoundPool代替MediaPlayer来播放这些音效。
SoundPool(android.media.SoundPool),顾名思义是声音池的意思,主要用于播放一些较短的声音片段,支持从程序的资源或文件 系统加载。与MediaPlayer相比,SoundPool的优势在于CPU资源占用量低和反应延迟小。另外,SoundPool还支持自行设置声音的品质、音量、播放比率等参数,支持通过ID对多个音频流进行管理。
就现在已知的资料来说,SoundPool有一些设计上的BUG,从固件版本1.0开始有些还没有修复,我们在使用中应该小心再小心。相信将来Google会修复这些问题,但我们最好还是列出来:
1. SoundPool最大只能申请1M的内存空间,这就意味着我们只能用一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。
2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。建议使用这两个方法的时候尽可能多做测试工作,还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
3. SoundPool的效率问题。其实SoundPool的效率在这些播放类中算是很好的了,但是有的朋友在G1中测试它还是有100ms左右的延迟,这可能会影响用户体验。也许这不能管SoundPool本身,因为到了性能比较好的Droid中这个延迟就可以让人接受了。
在现阶段SoundPool有这些缺陷,但也有着它不可替代的优点,基于这些我们建议大在如下情况中多使用SoundPool: 1.应用程序中的声效(按键提示音,消息等)2.游戏中密集而短暂的声音(如多个飞船同时爆炸)
开发步骤:
1> 往项目的res/raw目录中放入音效文件。
2> 新建SoundPool对象,然后调用SoundPool.load()加载音效,调用SoundPool.play()方法播放指定音效文件。
public class AudioActivity extends Activity {
private SoundPool pool;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//指定声音池的最大音频流数目为10,声音品质为5
pool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
final int sourceid = pool.load(this, R.raw.pj, 0);//载入音频流,返回在池中的id
Button button = (Button)this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//播放音频,第二个参数为左声道音量;第三个参数为右声道音量;第四个参数为优先级;第五个参数为循环次数,0不循环,-1循环;第六个参数为速率,速率最低0.5最高为2,1代表正常速度
pool.play(sourceid, 1, 1, 0, -1, 1);
}
});
}
}
示例
public
class
DemoActivity
extends
Activity {
int
soundid;
SoundPool pool;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
pool =
new
SoundPool(
5
, AudioManager.STREAM_MUSIC,
0
);
// 这语句代码 是一个异步的操作
soundid = pool.load(
this
, R.raw.ring,
1
);
// 需要花费一定的时间
}
public
void
shoot(View view) {
// 不会播放 因为上面异步的加载声音的操作 还没完成
pool.play(soundid,
1
.0f,
1
.0f,
0
,
0
,
1
.0f);
// taking tom
}
}