Android多媒体五:MediaRecorder录制音频
Android手机一般都提供麦克风的硬件,而Android系统可以利用该硬件来录制音频。
为了在Android应用中录制音频,Android提供了MediaRecorder类,使用MediaRecorder录制音频的过程很简单,步骤如下:
1:创建MediaRecorder对象;
2:调用MediaRecorder对象的setAudioSource()方法设置声音来源,一般传入MediaRecorder.AudioSource.MIC参数指定录制来自麦克风的声音;
3:调用MediaRecorder对象的setOutputFormat()方法设置所录制的音频文件格式;
4:调用MediaRecorder对象的setAudioEncoder()、setAudioEncodingBitRate(int bitRate)、setAudioSamplingRate(int samplingRate)方法设置所录制的声音编码格式、编码位率、采样率等,这些参数将可以控制所录制的声音品质、文件大小。一般来说,声音品质越好,声音文件越大;
5:调用MediaRecorder的setOutputFile(String path)方法设置所录制的音频文件的保存位置;
6:调用MediaRecorder的prepare()方法准备录制;
7:调用MediaRecorder对象的start()方法开始录制。
实例:录制音频
app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
res/anim/rote.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="1000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:toDegrees="-360" />
</set>
com/example/administrator/MainActivity.java
package com.example.administrator;
import android.Manifest;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.administrator.Permission.PermissionManager;
import java.io.File;
import java.io.IOException;
import java.security.Permission;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, PermissionManager.PermissionsResultListener {
// 定义界面的两个按钮
Button record, stop;
// 系统的音频文件
File soundFile;
MediaRecorder mRecorder;
private Button play;
private ImageView iv;
private Animation animation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//权限申请
PermissionManager.requestPermission(this, "读写SD卡", 0, this, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.RECORD_AUDIO);
// 获取程序界面中的两个按钮
record = findViewById(R.id.record);
stop = findViewById(R.id.stop);
play = findViewById(R.id.play);
iv = findViewById(R.id.iv);
// 为两个按钮的单击事件绑定监听器
record.setOnClickListener(this);
stop.setOnClickListener(this);
play.setOnClickListener(this);
//初始化动画
animation = AnimationUtils.loadAnimation(this, R.anim.rote);
}
@Override
public void onClick(View v) {
// 单击录音按钮
if (v.getId() == R.id.record) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(this, "SD卡不存在,请插入SD卡!", Toast.LENGTH_SHORT).show();
return;
}
try {
// 创建保存录音的音频文件
soundFile = new File(Environment.getExternalStorageDirectory().getCanonicalFile() + "/sound.mp3");
mRecorder = new MediaRecorder();
// 设置录音的声音来源
mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
// 设置录制的声音的输出格式(必须在设置声音编码格式之前设置)
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 设置声音编码格式
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(soundFile.getAbsolutePath());
mRecorder.prepare();
// 开始录音
mRecorder.start();
iv.startAnimation(animation);
} catch (Exception e) {
e.printStackTrace();
}
} else if (v.getId() == R.id.stop) {
// 单击停止按钮
if (soundFile != null && soundFile.exists()) {
// 停止录音
mRecorder.stop();
// 释放资源
mRecorder.release();
mRecorder = null;
iv.clearAnimation();
}
} else if (v.getId() == R.id.play) {
try {
MediaPlayer mMediaPlayer = new MediaPlayer();
String path = Environment.getExternalStorageDirectory().getCanonicalFile() + "/sound.mp3";
mMediaPlayer.setDataSource(path);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
protected void onDestroy() {
if (soundFile != null && soundFile.exists()) {
// 停止录音
mRecorder.stop();
// 释放资源
mRecorder.release();
mRecorder = null;
}
if (animation != null) {
iv.clearAnimation();
}
super.onDestroy();
}
@Override
public void onPermissionGranted(int requestCode) {
}
@Override
public void onPermissionDenied(int requestCode) {
}
}
com/example/administrator/Permission/PermissionManager.java
package com.example.administrator.Permission;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import java.util.concurrent.ConcurrentHashMap;
/**
* @time 2017/2/20
* @fuction 动态权限管理封装类
* @use 1. 在BaseActivity和BaseFragment重写onRequestPermissionsResult ,并实现如下代码PermissionManager.onRequestResult(requestCode, permissions, grantResults);
* 2. 然后需要请求权限的时候调用requestPermission方法 即可
*/
public class PermissionManager {
//维护的每个Activity的申请权限的监听
//便于清除释放
private static ConcurrentHashMap<Integer, PermissionsResultListener> mListenerMap = new ConcurrentHashMap<>();
/**
* 权限申请
*
* @param context Activity
* @param desc 再次申请权限的提示语
* @param requestCode
* @param permissionsListener
* @param permissions
*/
public static void requestPermission(Activity context,
String desc,
int requestCode,
PermissionsResultListener permissionsListener,
String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mListenerMap.put(requestCode, permissionsListener);
if (checkEachSelfPermission(context, permissions)) {
requestEachPermission(context, desc, permissions, requestCode);
} else {
mListenerMap.get(requestCode).onPermissionGranted(requestCode);
}
}
}
/**
* 权限申请
*
* @param context Fragment
* @param desc 再次申请权限的提示语
* @param requestCode
* @param permissionsListener
* @param permissions
*/
public static void requestPermission(Fragment context,
String desc,
int requestCode,
PermissionsResultListener permissionsListener,
String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mListenerMap.put(requestCode, permissionsListener);
if (checkEachSelfPermission(context.getActivity(), permissions)) {
requestEachPermission(context, desc, permissions, requestCode);
} else {
mListenerMap.get(requestCode).onPermissionGranted(requestCode);
}
}
}
/**
* 权限请求
*
* @param context Activity
* @param desc 再次申请权限的提示语
* @param permissions
* @param requestCode
*/
private static void requestEachPermission(final Activity context, String desc, final String[] permissions, final int requestCode) {
if (shouldShowRequestPermissionRationale(context, permissions)) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("权限申请")
.setMessage(desc)
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(context, permissions, requestCode);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
})
.setCancelable(false)
.show();
} else {
ActivityCompat.requestPermissions(context, permissions, requestCode);
}
}
/**
* 权限请求
*
* @param context Fragment
* @param desc 再次申请权限的提示语
* @param permissions
* @param requestCode
*/
private static void requestEachPermission(final Fragment context, String desc, final String[] permissions, final int requestCode) {
if (shouldShowRequestPermissionRationale(context, permissions)) {
AlertDialog.Builder builder = new AlertDialog.Builder(context.getActivity());
builder.setTitle("权限申请")
.setMessage(desc)
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
context.requestPermissions(permissions, requestCode);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
})
.setCancelable(false)
.show();
} else {
context.requestPermissions(permissions, requestCode);
}
}
/**
* 再次申请权限时,是否需要声明
*
* @param context Activity
* @param permissions
* @return
*/
private static boolean shouldShowRequestPermissionRationale(Activity context, String[] permissions) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(context, permission)) {
return true;
}
}
return false;
}
/**
* 再次申请权限时,是否需要声明
*
* @param context Fragment
* @param permissions
* @return
*/
private static boolean shouldShowRequestPermissionRationale(Fragment context, String[] permissions) {
for (String permission : permissions) {
if (context.shouldShowRequestPermissionRationale(permission)) {
return true;
}
}
return false;
}
/**
* 检察每个权限是否申请
*
* @param permissions
* @return true 需要申请权限,false 已申请权限
*/
private static boolean checkEachSelfPermission(Context context, String[] permissions) {
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
/**
* 权限申请处理回调
* 写在Activity或者Fragment的onRequestPermissionsResult 方法内
*
* @param requestCode
* @param permissions
* @param grantResults
*/
public static void onRequestResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
PermissionsResultListener permissionsResultListener = mListenerMap.get(requestCode);
if (permissionsResultListener == null) {
return;
}
if (grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
permissionsResultListener.onPermissionGranted(requestCode);
} else {
permissionsResultListener.onPermissionDenied(requestCode);
}
}
/**
* 清除掉已用完的Listner
*/
public static void clearListner(int requestCode) {
if (mListenerMap.get(requestCode) != null) {
mListenerMap.remove(requestCode);
}
}
public interface PermissionsResultListener {
/**
* 权限申请成功回调
*/
void onPermissionGranted(int requestCode);
/**
* 权限申请失败回调
*/
void onPermissionDenied(int requestCode);
}
/**
* 危险权限 授权一个就等于同组都授权了
* Manifest.permission.XXX
*
* group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
*/
}