andorid 怎么提高怎么把音频音量量

作者:高天辰
& & & &在Android中,音频、视频等多媒体元素的加入,使得应用程序的用户体验更好。可以说,现在的手机,已经远远不只作为通信工具,更成为娱乐、办公的必备产品。
Android提供了简单的音频API。一般大家使用的是MediaPlayer播放音频,这也是最常见的一种播放声音的工具。这种工具在互联网上有大量的实例,因此在此只做简单的介绍。
对播放行为的控制是三个大家非常熟悉的方法:start()、stop()和pause()。
通过static MediaPlayer create(Context, Uri)这个方法,可以获得一个新创建的MediaPlayer对象。
在播放过程中,有几个可以监听播放过程的监听器,如:
n setOnCompletionListener(MediaPlayer.OnCompletionListener listener),监听音频播放结束;
n setOnErrorListener(MediaPlayer.OnErrorListener listener),监听播放过程中的错误事件;
n setOnPreparedListener(MediaPlayer.OnPreparedListener listener),当prepare()被调用时触发。
然而,使用MediaPlayer播放时,也有一些问题。我们知道MediaPlayer在创建和销毁时都会耗费大量的系统资源,且创建和销毁的时间相对较长。此外,如果我们需要在同一时刻播放很多声音,MediaPlayer是不支持的。
因此,我们需要一个更加轻量级的声音播放工具。
Android提供了另外一种,叫做SoundPool,它适合播放那些需要反复播放,但时间较短的音效。它支持同时播放多种声音,这些声音在系统开始时会加载到列表中,按照这些声音的id,我们可以调用这些音效。
下面我们进入一个实例看看SoundPool到底是怎么工作的。
例如,现在在一个五子棋游戏中,我们需要在棋子落盘的时候播放一段声音。我们可以利用SoundPool,因为它时间很短,而且需要反复播放,并且我们不希望声音占用太大资源。
先看看代码:
private SoundPool
soundPool;
soundPool=
newSoundPool(10,AudioManager.STREAM_SYSTEM,5);
soundPool.load(this,R.raw.collide,1);
soundPool.play(1,1, 1, 0, 0, 1);
代码非常简单,第一行是声明了一个SoundPool对象,这个一般是作为类的成员属性出现的。第二行将soundPool实例化,第一个参数为soundPool可以支持的声音数量,这决定了Android为其开设多大的缓冲区,第二个参数为声音类型,在这里标识为系统声音,除此之外还有AudioManager.STREAM_RING以及AudioManager.STREAM_MUSIC等,系统会根据不同的声音为其标志不同的优先级和缓冲区,最后参数为声音品质,品质越高,声音效果越好,但耗费更多的系统资源。
第三行,系统为soundPool加载声音,第一个参数为上下文参数,第二个参数为声音的id,一般我们将声音信息保存在res的raw文件夹下,如下图所示。
第三个参数为声音的优先级,当多个声音冲突而无法同时播放时,系统会优先播放优先级高的。
第四行就是播放了,第一个参数为id,id即为放入到soundPool中的顺序,比如现在collide.wav是第一个,因此它的id就是1。第二个和第三个参数为左右声道的音量控制。第四个参数为优先级,由于只有这一个声音,因此优先级在这里并不重要。第五个参数为是否循环播放,0为不循环,-1为循环。最后一个参数为播放比率,从0.5到2,一般为1,表示正常播放。
本文已收录于以下专栏:
相关文章推荐
【1】使用MediaPlayer实现一般的音频播放
MediaPlayer播放通常的音频文件
view plaincopyprint?
前言这段时间在看一些IPC相关的东西,这里面就不可避免的要涉及到service,进程线程这些知识点,而且在研究的过程中我惊觉自己对这些东西的记忆已经开始有些模糊了——这可要不得。于是我就干脆花了点心思...
为了调用方便,自己写了一个简单的Android播放声音的工具类,供大家参考。
前言前面一篇博文介绍了关于Service的一些基本知识,包括service是什么,怎么创建一个service,创建了一个service之后如何启动它等等。在这一篇博文里有一些需要前一篇铺垫的东西,建议...
SoundPool可以用来播放一些较短的音效,如一些信息提醒之类的
先来说下会用到的参数
SoundPool(int maxStreams, int streamType, int srcQualit...
From: http://blog.csdn.net/pku_android/article/details/7625868
From: http://blog.csdn.net/liu_zhen_...
原文地址:
/guide/topics/media/mediaplayer.html#viacontentresolver语音播放因为实习工...
Android中实现录音功能其实很简单,直接调用的系统的就ok了,这里就不写实现的原理了,直接部署代码:所谓的实现就是用的MediaRecorder。
录音功能代码:
 //开始录制
    p...
网上搜了些关于MediaPlayer的资料
1)如何获得MediaPlayer实例:
可以使用直接new的方式:
MediaPlayer mp = new MediaPlayer();
如果你的APP播放音频,你必须能够控制音频的播放。为了保证用户体验,你的APP必须要能够获取音频焦点,这样就能保证多个APP不会在同一时刻播放音频。
1、确认使用的音频流
Android为play...
他的最新文章
讲师:王哲涵
讲师:韦玮
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Andorid6.0音量调整(设置)流程
Andorid6.0音量调整(设置)流程
编辑:www.fx114.net
本篇文章主要介绍了"Andorid6.0音量调整(设置)流程",主要涉及到Andorid6.0音量调整(设置)流程方面的内容,对于Andorid6.0音量调整(设置)流程感兴趣的同学可以参考一下。
按文件分步骤,代码版本Android6.0.1
1.上层调用AudioManager的接口,要么是setStreamVolume(),要么是按了音量键adjustStreamVolume().
2.AudioService.java:
1.1分两种情况
情况一:如果setStreamVolume()--------------------------应用层调用
(1)setStreamVolume()
onSetStreamVolume(streamType, index, flags, device, caller);
(2) onSetStreamVolume()
setStreamVolumeInt(stream, index, device, false, caller);
(3)setStreamVolumeInt()
sendMsg(mAudioHandler,
MSG_SET_DEVICE_VOLUME,
SENDMSG_QUEUE,
streamState,
mAudioHandler定义:AudioHandler mAudioH
-&case MSG_SET_DEVICE_VOLUME:
setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
情况二:如果adjustStreamVolume()-----------------------------音量键
sendMsg(mAudioHandler,
MSG_SET_DEVICE_VOLUME,
SENDMSG_QUEUE,
streamState,
1.2setDeviceVolume():
mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
1.3applyDeviceVolume_syncVSS():
AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
这一步中的index值并不是通过msg传递过来的,那么是怎么来的呢?
public void applyDeviceVolume_syncVSS(int device) {
if (mIsMuted) {//静音了
index = 0;
} else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
mAvrcpAbsVolSupported)//某类蓝牙设备保持在一个固定的音量上(雷柏a3060)
|| ((device & mFullVolumeDevices) != 0)) {//某类可调,比如Leme(乐视蓝牙耳机)
index = (mIndexMax + 5)/10;
index = (getIndex(device) + 5)/10;
AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
探讨一下Leme和雷柏a3060的表现不一样的问题
用adb shell dump研究audio_flinger得知,此时,系统输出的音量db值都是0(即最大音量)。
调音量是在哪调的呢?
if (mA2dp != null && mAvrcpAbsVolSupported) {
mA2dp.setAvrcpAbsoluteVolume(index / 10);
结果发现两个设备都会执行到这来,但是再往下jni层,雷柏的返回音量一直是0,其他蓝牙耳机,蓝牙音箱都正常音量值。。。估计雷柏本身支持的不够好了,毕竟设备比较久远,
我们就不深究了。
至少在这可以得出一个结论:
手机针对蓝牙音频输出设备的策略是:给你最大音量的输出,要调你自己调,比如这个地方用Avrcp协议去和蓝牙设备进行通讯来调整音量。
言归正传。很明显。index来自getIndex方法,一路找下去,发现index来自 mIndexMap
调用顺序:
情况一:adjustStreamVolume():
streamState.adjustIndex(direction * step, device, caller)
setIndex(getIndex(device) + deltaIndex, device, caller);
mIndexMap.put(device, index);
情况二:setStreamVolume():
在前面说到的1.1情况一的 setStreamVolumeInt()函数里index一路通过参数传过来,然后通过
streamState.setIndex(index, device, caller) 也进行了赋值
mIndexMap.put(device, index);
put之后,那边就可以get出来了,不过要注意
(1)set的地方和get的地方(收到msg之后)是异步的,两个线程.
(2)setIndex有个参数device。不同device,index是不一样的。
(3)setIndex里头:
boolean currentDevice = (device == getDeviceForStream(mStreamType));
int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType &= 0; streamType--) {
if (streamType != mStreamType &&
mStreamVolumeAlias[streamType] == mStreamType) {
int scaledIndex = rescaleIndex(index, mStreamType, streamType);
mStreamStates[streamType].setIndex(scaledIndex, device, caller);
//根据上面的赋值可知,这个变量的意思是,本次调用想设置音量的device对应
//mStreamType
if (currentDevice) {
mStreamStates[streamType].setIndex(scaledIndex,
getDeviceForStream(streamType), caller);
注意这段代码,打日志的话,setIndex会被调用多次。别名一样的也会被同时设置。我自己都没懂这块是什么意思?????????????????懂的人说下
2.AudioSystem.java
public static native int setStreamVolumeIndex()
这下到ndk层了
3.android_media_AudioSystem.cpp
android_media_AudioSystem_setStreamVolumeIndex():
AudioSystem::setStreamVolumeIndex()
4.AudioSystem.cpp
status_t AudioSystem::setStreamVolumeIndex
到这层开始返回值变成了status_t这个结构体,虽然我不知道这个结构体在哪定义的,但是这个结构体很常见。
return aps-&setStreamVolumeIndex(stream, index, device);
aps定义:const sp&IAudioPolicyService&& aps = AudioSystem::get_audio_policy_service();
IaudioPolicyService是一个IInterface,我们找到
再往下,实在懒得分析了,等以后的吧!
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:【转】Android&AudioRecord语音采集&噪音解决方案?
http://www.shouyanwang.org/thread-.html.html
最近在做手机客户端用G726编码库向机台发送语音消息的DEMO,弄了一周左右才解决.
中间碰到的问题贼多,主要是用AudioRecord采集声音的时候,然后用AudioTrack播放经常会出现噪音,这样的情况让人实在是无法接受。
后来查谷歌实在是没折了,于是再次翻查了下sipdroid的代码,发现sipdroid在采集声音后,每次都会调用一个函数,于是我猜测,这个函数应该跟去除噪音有关,于是写了个DEMO,测试了一下,发现噪音还真消除了.
噪音消除算法:
void calc1(short[] lin,int off,int len) {
for (i = 0; i & i++) {
j = lin[i+off];
lin[i+off] = (short)(j&&2);
自己录制PCM,播放PCM的DEMO。
不用带耳机也不会产生回音.
Runnable test = new Runnable(){
public void run() {
int samp_rate = 8000 ;
int min = AudioRecord.getMinBufferSize(samp_rate,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
Log.e(TAG, "min buffer size:"+min);
//用于采集音频源
AudioRecord record =
record = new AudioRecord(
MediaRecorder.AudioSource.MIC,//the recording source
samp_rate, //采样频率,一般为8000hz/s
AudioFormat.CHANNEL_OUT_DEFAULT,
AudioFormat.ENCODING_PCM_16BIT,
record.startRecording();
//用于播放音频源
int maxjitter = AudioTrack.getMinBufferSize(samp_rate,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack track = new
AudioTrack(AudioManager.STREAM_MUSIC,samp_rate,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
maxjitter*10, AudioTrack.MODE_STREAM);
track.play();
int frame_size = 320;//g726_32 : 4:1的压缩比
byte [] audioData = new byte [frame_size/4];
short [] encodeData = new short[frame_size/2];
int num = 0;
g726Codec codec = new g726Codec ();
short[] putIn = new short [160];
// int result= 0;
while(running)
num = record.read(encodeData, 0, 160);
Log.e(TAG, "num:"+num);
calc1(encodeData,0,160);
int wirteNum = track.write(encodeData, 0, num);
// if(wirteNum==160)
// track.play();
// System.arraycopy(encodeData, 0, putIn, 0, 80);
// num = record.read(encodeData, 0, 160);
// System.arraycopy(encodeData, 0, putIn, 80, 80);
// num = record.read(putIn, 0, 160);
// Log.e(TAG, "num:"+num);
// if(num == AudioRecord.ERROR_INVALID_OPERATION || num ==
AudioRecord.ERROR_BAD_VALUE) {
// Log.e(TAG, "Bad ");
// int iRet = codec.encode(encodeData,
audioData);//先用G726进行编码
// Log.e(TAG, "encode iRet:"+iRet);
// iRet = codec.decode(audioData,
encodeData);//然后用g726进行解码
// Log.e(TAG, "decode iRet:"+iRet);
// track.write(encodeData, 0, 160);
// Thread.sleep(200);
// } catch (InterruptedException e) {
// e.printStackTrace();
record.stop();
record.release();
track.stop();
track.release();
void calc1(short[] lin,int off,int len) {
for (i = 0; i & i++) {
j = lin[i+off];
lin[i+off] = (short)(j&&2);
protected void onDestroy() {
super.onDestroy();
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Android实现音频录制的两种方式
在移动APP开发中,每逢APP应用设计到多媒体开发的时候,都会让很多的程序员头疼不已,而且项目的开发进度会放慢、项目
的难度也会加大蛮多,同时APP的测试也会增加。中的多媒体开发,有音频的播放、音频的录制、视频的播放、视频的录制
等,虽然Android的SDK中提供了一些基础的开发API类,如音频的录制就提供了两种方式:AudioRecord录制音频和MediaRecorder录
制音频。AudioRecord类相对于MediaRecorder来说,更加接近底层,为我们封装的方法也更少。然而实现一个AudioRecord的音频录
制程序也很简单。
一、AudioRecord实现录制音频:
package com.hb56.MyAndroidU
import java.io.BufferedInputS
import java.io.BufferedOutputS
import java.io.DataInputS
import java.io.DataOutputS
import java.io.F
import java.io.FileInputS
import java.io.FileOutputS
import java.io.IOE
import android.app.A
import android.content.ContentV
import android.content.I
import android.hardware.Camera.AutoFocusC
import android.media.AudioF
import android.media.AudioM
import android.media.AudioR
import android.media.AudioT
import android.media.MediaP
import android.media.MediaR
import android.net.U
import android.os.AsyncT
import android.os.B
import android.os.E
import android.provider.MediaS
import android.util.L
import android.view.V
import android.widget.B
import android.widget.TextV
* 该实例中,我们使用AudioRecord类来完成我们的音频录制程序
* AudioRecord类,我们可以使用三种不同的read方法来完成录制工作,
* 每种方法都有其实用的场合
* 一、实例化一个AudioRecord类我们需要传入几种参数
* 1、AudioSource:这里可以是MediaRecorder.AudioSource.MIC
* 2、SampleRateInHz:录制频率,可以为8000hz或者11025hz等,不同的硬件设备这个值不同
* 3、ChannelConfig:录制通道,可以为AudioFormat.CHANNEL_CONFIGURATION_MONO和AudioFormat.CHANNEL_CONFIGURATION_STEREO
* 4、AudioFormat:录制编码格式,可以为AudioFormat.ENCODING_16BIT和8BIT,其中16BIT的仿真性比8BIT好,但是需要消耗更多的电量和存储空间
* 5、BufferSize:录制缓冲大小:可以通过getMinBufferSize来获取
* 这样我们就可以实例化一个AudioRecord对象了
* 二、创建一个文件,用于保存录制的内容
* 三、打开一个输出流,指向创建的文件
* DataOutputStream
= new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)))
* 四、现在就可以开始录制了,我们需要创建一个字节数组来存储从AudioRecorder中返回的音频数据,但是
* 注意,我们定义的数组要小于定义AudioRecord时指定的那个BufferSize
* short[]buffer = new short[BufferSize/4];
* startRecording();
* 然后一个循环,调用AudioRecord的read方法实现读取
* 另外使用MediaPlayer是无法播放使用AudioRecord录制的音频的,为了实现播放,我们需要
* 使用AudioTrack类来实现
* AudioTrack类允许我们播放原始的音频数据
* 一、实例化一个AudioTrack同样要传入几个参数
* 1、StreamType:在AudioManager中有几个常量,其中一个是STREAM_MUSIC;
* 2、SampleRateInHz:最好和AudioRecord使用的是同一个值
* 3、ChannelConfig:同上
* 4、AudioFormat:同上
* 5、BufferSize:通过AudioTrack的静态方法getMinBufferSize来获取
* 6、Mode:可以是AudioTrack.MODE_STREAM和MODE_STATIC,关于这两种不同之处,可以查阅文档
* 二、打开一个输入流,指向刚刚录制内容保存的文件,然后开始播放,边读取边播放
* 实现时,音频的录制和播放分别使用两个AsyncTask来完成
* 利用AudioRecord类实现自己的音频录制程序
* com.hb56.MyAndroidUtil.AudioRecord
* @author Admin-zhangyx
* create at
下午2:03:13
public class AudioRecordActivity extends Activity{
private TextView stateV
private Button btnStart, btnStop, btnPlay, btnF
private RecordT
private PlayT
private File audioF
private boolean isRecording = true, isPlaying = // 标记
private int frequence = 8000; // 录制频率,单位hz.这里的值注意了,写的不好,可能实例化AudioRecord对象的时候,会出错。我开始写成11025就不行。这取决于硬件设备
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_audio_record);
stateView = (TextView) this.findViewById(R.id.view_state);
stateView.setText(&准备开始&);
btnStart = (Button) this.findViewById(R.id.btn_start);
btnStop = (Button) this.findViewById(R.id.btn_stop);
btnPlay = (Button) this.findViewById(R.id.btn_play);
btnFinish = (Button) this.findViewById(R.id.btn_finish);
btnFinish.setText(&停止播放&);
btnStop.setEnabled(false);
btnPlay.setEnabled(false);
btnFinish.setEnabled(false);
// 在这里我们创建一个文件,用于保存录制内容
File fpath = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + &/data/files/&);
fpath.mkdirs();// 创建文件夹
// 创建临时文件,注意这里的格式为.pcm
audioFile = File.createTempFile(&recording&, &.pcm&, fpath);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.btn_start:
// 开始录制
// 这里启动录制任务
recorder = new RecordTask();
recorder.execute();
case R.id.btn_stop:
// 停止录制
this.isRecording =
// 更新状态
// 在录制完成时设置,在RecordTask的onPostExecute中完成
case R.id.btn_play:
player = new PlayTask();
player.execute();
case R.id.btn_finish:
// 完成播放
this.isPlaying =
class RecordTask extends AsyncTask {
protected Void doInBackground(Void... arg0) {
isRecording =
// 开通输出流到指定的文件
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(audioFile)));
// 根据定义好的几个配置,来获取合适的缓冲大小
int bufferSize = AudioRecord.getMinBufferSize(frequence,
channelConfig, audioEncoding);
// 实例化AudioRecord
AudioRecord record = new AudioRecord(
MediaRecorder.AudioSource.MIC, frequence,
channelConfig, audioEncoding, bufferSize);
// 定义缓冲
short[] buffer = new short[bufferSize];
// 开始录制
record.startRecording();
int r = 0; // 存储录制进度
// 定义循环,根据isRecording的值来判断是否继续录制
while (isRecording) {
// 从bufferSize中读取字节,返回读取的short个数
// 这里老是出现buffer overflow,不知道是什么原因,试了好几个值,都没用,TODO:待解决
int bufferReadResult = record
.read(buffer, 0, buffer.length);
// 循环将buffer中的音频数据写入到OutputStream中
for (int i = 0; i & bufferReadR i++) {
dos.writeShort(buffer[i]);
publishProgress(new Integer(r)); // 向UI线程报告当前进度
r++; // 自增进度值
// 录制结束
record.stop();
Log.v(&The DOS available:&, &::& + audioFile.length());
dos.close();
} catch (Exception e) {
// TODO: handle exception
// 当在上面方法中调用publishProgress时,该方法触发,该方法在UI线程中被执行
protected void onProgressUpdate(Integer... progress) {
stateView.setText(progress[0].toString());
protected void onPostExecute(Void result) {
btnStop.setEnabled(false);
btnStart.setEnabled(true);
btnPlay.setEnabled(true);
btnFinish.setEnabled(false);
protected void onPreExecute() {
// stateView.setText(&正在录制&);
btnStart.setEnabled(false);
btnPlay.setEnabled(false);
btnFinish.setEnabled(false);
btnStop.setEnabled(true);
class PlayTask extends AsyncTask {
protected Void doInBackground(Void... arg0) {
isPlaying =
int bufferSize = AudioTrack.getMinBufferSize(frequence,
channelConfig, audioEncoding);
short[] buffer = new short[bufferSize / 4];
// 定义输入流,将音频写入到AudioTrack类中,实现播放
DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream(audioFile)));
// 实例AudioTrack
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,
frequence, channelConfig, audioEncoding, bufferSize,
AudioTrack.MODE_STREAM);
// 开始播放
track.play();
// 由于AudioTrack播放的是流,所以,我们需要一边播放一边读取
while (isPlaying && dis.available() & 0) {
int i = 0;
while (dis.available() & 0 && i & buffer.length) {
buffer[i] = dis.readShort();
// 然后将数据写入到AudioTrack中
track.write(buffer, 0, buffer.length);
// 播放结束
track.stop();
dis.close();
} catch (Exception e) {
// TODO: handle exception
protected void onPostExecute(Void result) {
btnPlay.setEnabled(true);
btnFinish.setEnabled(false);
btnStart.setEnabled(true);
btnStop.setEnabled(false);
protected void onPreExecute() {
// stateView.setText(&正在播放&);
btnStart.setEnabled(false);
btnStop.setEnabled(false);
btnPlay.setEnabled(false);
btnFinish.setEnabled(true);
二、MediaRecorder 实现录制音频:
package com.hb56.MyAndroidU
import java.io.F
import java.io.IOE
import android.app.A
import android.content.ContentV
import android.content.I
import android.media.MediaP
import android.media.MediaR
import android.net.U
import android.os.B
import android.os.E
import android.provider.MediaS
import android.view.V
import android.widget.B
import android.widget.TextV
* 这个是利用MediaRecorder类来实现自己的音频录制程序
* 为了可以录制音频我们需要RECORD_AUDIO权限
* 为了可以写入SDCard,我们需要WRITE_EXTERNAL_STORAGE权限
* 利用MediaRecorder类实现自己的音频录制程序
*com.hb56.MyAndroidUtil.MediaRecorderActivity
* @author Admin-zhangyx
* create at
下午2:13:38
public class MediaRecorderActivity {
private TextView stateV
private Button btnStart,btnStop,btnPlay,btnF
private MediaR
private MediaP
private File audioF
private Uri fileU
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.my_audio_record);
stateView = (TextView)this.findViewById(R.id.view_state);
stateView.setText(&准备开始&);
btnStart = (Button)this.findViewById(R.id.btn_start);
btnStop = (Button)this.findViewById(R.id.btn_stop);
btnPlay = (Button)this.findViewById(R.id.btn_play);
btnFinish = (Button)this.findViewById(R.id.btn_finish);
btnStop.setEnabled(false);
btnPlay.setEnabled(false);
public void onClick(View v){
int id = v.getId();
switch(id){
case R.id.btn_start:
//开始录制
//我们需要实例化一个MediaRecorder对象,然后进行相应的设置
recorder = new MediaRecorder();
//指定AudioSource 为MIC(Microphone audio source ),这是最长用的
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//指定OutputFormat,我们选择3gp格式
//其他格式,MPEG-4:这将指定录制的文件为mpeg-4格式,可以保护Audio和Video
//RAW_AMR:录制原始文件,这只支持音频录制,同时要求音频编码为AMR_NB
//THREE_GPP:录制后文件是一个3gp文件,支持音频和视频录制
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//指定Audio编码方式,目前只有AMR_NB格式
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//接下来我们需要指定录制后文件的存储路径
File fpath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+&/data/files/&);
fpath.mkdirs();//创建文件夹
//创建临时文件
audioFile = File.createTempFile(&recording&, &.3gp&, fpath);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
recorder.setOutputFile(audioFile.getAbsolutePath());
//下面就开始录制了
recorder.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
recorder.start();
stateView.setText(&正在录制&);
btnStart.setEnabled(false);
btnPlay.setEnabled(false);
btnStop.setEnabled(true);
case R.id.btn_stop:
recorder.stop();
recorder.release();
//然后我们可以将我们的录制文件存储到MediaStore中
ContentValues values = new ContentValues();
values.put(MediaStore.Audio.Media.TITLE, &this is my first record-audio&);
values.put(MediaStore.Audio.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Audio.Media.DATA, audioFile.getAbsolutePath());
fileUri = this.getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
//录制结束后,我们实例化一个MediaPlayer对象,然后准备播放
player = new MediaPlayer();
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
//更新状态
stateView.setText(&准备录制&);
btnPlay.setEnabled(true);
btnStart.setEnabled(true);
btnStop.setEnabled(false);
//准备播放
player.setDataSource(audioFile.getAbsolutePath());
player.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//更新状态
stateView.setText(&准备播放&);
btnPlay.setEnabled(true);
btnStart.setEnabled(true);
btnStop.setEnabled(false);
case R.id.btn_play:
//播放录音
//注意,我们在录音结束的时候,已经实例化了MediaPlayer,做好了播放的准备
player.start();
//更新状态
stateView.setText(&正在播放&);
btnStart.setEnabled(false);
btnStop.setEnabled(false);
btnPlay.setEnabled(false);
//在播放结束的时候也要更新状态
case R.id.btn_finish:
//完成录制,返回录制的音频的Uri
Intent intent = new Intent();
intent.setData(fileUri);
this.setResult(RESULT_OK, intent);
this.finish();

我要回帖

更多关于 提高音频音量 的文章

 

随机推荐