Android学习笔记_24_多媒体MediaPlayer对象之音乐播放器与SoundPool声音池
一、MediaPlayer对象常用方法介绍:
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;
}
});
二、音乐播放器实现:
1、加入权限:
<!-- 多媒体播放音乐 -->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<!-- 监听电话状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
2、界面布局:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <Button
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/editPlayFile"
android:layout_marginTop="22dp"
android:text="@string/play"
android:onClick="mediaPlayer"/> <Button
android:id="@+id/btnPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btnReplay"
android:layout_alignBottom="@+id/btnReplay"
android:layout_toRightOf="@+id/btnReplay"
android:text="@string/pause"
android:onClick="mediaPlayer"/> <Button
android:id="@+id/btnReplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btnStop"
android:layout_alignBottom="@+id/btnStop"
android:layout_toRightOf="@+id/btnStop"
android:text="@string/replay"
android:onClick="mediaPlayer"/> <Button
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btnPlay"
android:layout_alignBottom="@+id/btnPlay"
android:layout_toRightOf="@+id/btnPlay"
android:text="@string/stop"
android:onClick="mediaPlayer"/> <EditText
android:id="@+id/editPlayFile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/btnPlay"
android:layout_alignParentTop="true"
android:layout_alignRight="@+id/btnPause"
android:layout_marginTop="44dp"
android:text="11.mp3"
android:ems="10" > <requestFocus />
</EditText> </RelativeLayout>
3、代码实现:
package com.example.musicplayer; import java.io.File;
import java.io.FileInputStream; import android.app.Activity;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; public class MainActivity extends Activity { private EditText musicFile;
private String path;
private FileInputStream fileInputStream;
private MediaPlayer mediaPlayer;
private boolean pause=false;
private int position;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); musicFile=(EditText)this.findViewById(R.id.editPlayFile);
mediaPlayer = new MediaPlayer();
//监听电话
TelephonyManager manager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
manager.listen(new MyPhoneListener(), PhoneStateListener.LISTEN_CALL_STATE); }
private final class MyPhoneListener extends PhoneStateListener{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING://来电
if(mediaPlayer.isPlaying()){
position=mediaPlayer.getCurrentPosition();
mediaPlayer.stop();
}
break;
case TelephonyManager.CALL_STATE_IDLE://挂断电话
if(position>0 && fileInputStream!=null){
play(position);
}
break;
}
} }
public void mediaPlayer(View view){
switch (view.getId()) {
case R.id.btnPlay:
try {
String filename=musicFile.getText().toString();
// File file=new File(Environment.getExternalStorageDirectory(),filename);
File file=new File("/storage/sdcard0/Music/王菲 - 传奇.mp3");
if(file.exists()){
// AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
// audioManager.setMode(AudioManager.MODE_IN_CALL);// 把模式调成听筒放音模式
path=file.getAbsolutePath();
Log.i("MainActivity", path);
fileInputStream = new FileInputStream(file);
play(position);
// 设置音频循环播放
mediaPlayer.setLooping(true); }else {
path=null;
Toast.makeText(getApplicationContext(), "文件不存在", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
} break;
case R.id.btnPause:
if(mediaPlayer.isPlaying()){//如果正在播放
pause=true;
mediaPlayer.pause();//暂停
((Button)view).setText(R.string.continues);
}else {
if(pause){
mediaPlayer.start();
pause=false;
((Button)view).setText(R.string.pause);
}
}
break;
case R.id.btnReplay://重新播放
if(mediaPlayer.isPlaying()){
mediaPlayer.seekTo(0);//从开始位置播放
}else {
if(path!=null)
play(position);//播放
}
break;
case R.id.btnStop:
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
break;
}
} private void play(int position) {
try {
mediaPlayer.reset();//把各项参数恢复到初始状态
mediaPlayer.setDataSource(fileInputStream.getFD());
mediaPlayer.prepare();//进行缓冲
mediaPlayer.setOnPreparedListener(new PrepareListener(position));
} catch (Exception e) {
e.printStackTrace();
} } private final class PrepareListener implements OnPreparedListener{
private int position;
public PrepareListener(int position) {
super();
this.position = position;
}
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();//缓冲完毕开始播放
if(position>0){
mediaPlayer.seekTo(position);
}
position=0;
}
} //释放资源
@Override
protected void onDestroy() {
mediaPlayer.release();
mediaPlayer=null;
super.onDestroy();
}
/*
//暂停
@Override
protected void onPause() {
if(mediaPlayer.isPlaying()){
//停止播放时获取当前播放位置
position=mediaPlayer.getCurrentPosition();
mediaPlayer.stop();
}
super.onPause();
}
//从暂停状态重新运行状态
@Override
protected void onResume() {
if(position>0 && fileInputStream!=null){
play(position);
}
super.onResume();
}
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
三、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);
}
});
}
}
Android学习笔记_24_多媒体MediaPlayer对象之音乐播放器与SoundPool声音池的更多相关文章
- Android开发学习之路--MediaPlayer之简单音乐播放器初体验
很多时候我们都会用手机来播放音乐,播放视频,那么具体地要怎么实现呢,其实主要是MediaPlayer类来完成的.下面通过简单的例子来实现一首歌曲的播放吧.新建工程MediaPlayerStudy,这里 ...
- 小菜学习Winform(二)WMPLib实现音乐播放器
前言 现在网上有很多的音乐播放器,但好像都不是.net平台做的,在.net中实现音乐文件的播放功能很简单,下面就简单实现下. SoundPlayer类 在.net提供了音乐文件的类:SoundPlay ...
- Android 音视频深入 十三 OpenSL ES 制作音乐播放器,能暂停和调整音量(附源码下载)
项目地址https://github.com/979451341/OpenSLAudio OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能,低 ...
- Android学习笔记(二十)——自定义内容提供器
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 如果我们想要实现跨程序共享数据的功能,官方推荐的方式就是使用内容提供器,可以通过新建一个类去继承 Conten ...
- Android——用Activity和Service实现简单的音乐播放器
一.只用Activity 容易出现问题 xml <?xml version="1.0" encoding="utf-8"?> <LinearL ...
- Android学习笔记_25_多媒体之在线播放器
一.布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...
- Android学习笔记_27_多媒体之视频刻录
一.配置文件: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android= ...
- Android学习笔记_26_多媒体之拍照
一.配置文件: 需要引入摄像头权限,sdcard读写权限. <?xml version="1.0" encoding="utf-8"?> <m ...
- Android学习笔记(十八)——使用意图筛选器和实现浏览网页(附源代码)
使用意图筛选器 点击下载源代码 1.创建一个Intents项目,给该项目加入一个新类,命名为MyBrowserActivity.在res/layout目录下新增一个browser.xml: 2.在An ...
随机推荐
- 安卓获取输入法高度与ViewTreeObserver讲解
目录 安卓获取输入法高度 前言 清单 开始 ViewTreeObserver讲解 获取输入法高度原理 思路 实现 关于ViewTreeObserver 定义 继承 摘要 获取View高度的三种方法 源 ...
- 获取top10
ips = ['', '123.125.71.49', '164.132.161.48', '217.182.132.55', '217.182.132.55', '217.182.132.94', ...
- bzoj 5340: [Ctsc2018]假面
Description 题面 Solution 生命值范围比较小,首先维护每一个人在每个血量的概率,从而算出生存的概率,设为 \(a[i]\) 询问时,只需要考虑生存的人数,可以 \(DP\) 设 \ ...
- JS常用的设计模式(2)——简单工厂模式
简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...
- bootstrap --datetimepicker之时间段选择
文件引入 <script type="text/javascript" src="css/jquery-3.2.1.js"></script& ...
- 【Linux】查看磁盘空间大小
Ubuntu 查看磁盘空间大小命令 df -h Df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息, 命令格式: df -hl 显示格式为: 文件系统 容量 已 ...
- Spring @Resource, @Autowired and @Inject 注入
Overview I’ve been asked several times to explain the difference between injecting Spring beans with ...
- Csharp: Send Email
/// <summary> /// 發送郵件 /// 塗聚文 /// 20130816 /// </summary> /// <param name="to&q ...
- TiDB, Distributed Database
https://www.zhihu.com/topic/20062171/top-answers
- 05_Jedis操作Redis
[工程截图] [String类型操作] package com.higgin.string; import java.util.List; import redis.clients.jedis.Jed ...