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 ...
随机推荐
- 2018最新mfc作为上位机接收硬件端USB或串口数据显示成图片 解决串口接收数据丢字节丢包问题
原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9490616.html 本文用的是VS2013MFC写串口数据接收: 第一步:首先建立一个MFC ...
- 很有用的PHP笔试题系列二
1.如何用php的环境变量得到一个网页地址的内容?ip地址又要怎样得到? Gethostbyname() echo $_SERVER ["PHP_SELF"];echo $_SER ...
- 02.List泛型集合
List泛型可以转换成数组 List泛型和数组的相同点: List泛型的数据类型必须是指定的,数组的数据类型也必须是指定的. List泛型和数组的不同点: List泛型的长度是随意的,而数组的长度必须 ...
- Java ConcurrentHashMap的小测试
今天正式开始自己的分布式学习,在第一章介绍多线程工作模式时,作者抛出了一段关于ConcurrentHashMap代码让我很是疑惑,代码如下: public class TestClass { priv ...
- JavaScript写的随机选人真实案例
JavaScript写的随机选人真实案例 因工作需要,写了一个随机选人的小网页,先看效果图. 背景也是动态的,只不过在写的时候碰到个问题,就是如果把生成动态流星雨的画布放到上生成随机数的操作界面之上的 ...
- POJO对象
POJO(Plain Old Java Objects)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称. 使用POJO名称是为了避免和 EJB混淆起来, 而且简 ...
- JSTL标签概述
什么是JSTL JSP 标准标记库(JSP Standard Tag Library,JSTL)是一个实现 Web 应用程序中常见的通用功能的定制标记库集,这些功能包括迭代和条件判断.数据管理格式化. ...
- Java—集合框架Set
Set接口及其实现类——HashSet Set是元素无序并且不可以重复的集合,被称作集. HashSet—哈希集,是Set的一个重要实现类. Set的使用 HashSet没有像List一样的set ...
- 【邀请函】小投入 大产出—微软智能云(Azure)之CDN 专题
会议时间 2016 年 11 月 24 日 14:00-16:00 会议介绍 尊敬的客户: 您是否还在为如何提高网站的响应速度以及用户增长造成的源站压力烦恼?是否还在担心源站 IP 暴露存在安全隐患? ...
- jmeter中CSV Data Set Config各项说明
Config the CSV Data Source: 1)Filename:csv文件的名称(包括绝对路径,当csv文件在bin目录下时,只需给出文件名即可) 2)File encoding:csv ...