<span style="font-size:18px;"><span style="font-size:18px;">项目中,新需求要求可以录音,同时转换成mp3格式传到服务器。这其中遇到了不少坑,接下来慢慢详谈。首先录音可以使用MediaPlayer这个类,直接展示代码 具体demo,下载地址最后会给出。然后android默认录音时.raw格式的,此时我们应该将raw格式的文件转化成mp3格式的。这里我们用到FLameUtils,值得一提的就是flame.jar,和libmp3lame.so文件。
1.最好是放在main文件夹下的jniLibs下
2.要在gradle.properties下加入如下代码:android.useDeprecatedNdk
允许ndk开发
3.当然不要忘记加入如下权限:
<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" />
public class MainActivity extends Activity implements View.OnClickListener {
private Button start,stop;
//语音备注
private Button record;
private Dialog dialog;
private MediaPlayer mediaPlayer;
private Boolean isZhuanhuan = true;
private Boolean isPermit=false;
private Thread recordThread;
private static int MAX_TIME = 90; // 最长录制时间,单位秒,0为无时间限制
private static int MIX_TIME = 1; // 最短录制时间,单位秒,0为无时间限制,建议设为1
private static int RECORD_NO = 0; // 不在录音
private static int RECORD_ING = 1; // 正在录音
private static int RECODE_ED = 2; // 完成录音
private String file;
private static int RECODE_STATE = 0; // 录音的状态
private static float recodeTime = 0.0f; // 录音的时间
private static double voiceValue = 0.0; // 麦克风获取的音量值
private ImageView dialog_img;
private boolean canClean = false;
AudioRecorder2Mp3Util util = null;
private static boolean playState = false; // 播放状态
private TextView tvchonglu;
private TextView player;//显示录制时间
private String sec=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = ((Button) findViewById(R.id.start));
player = ((TextView) findViewById(R.id.player));
stop = ((Button) findViewById(R.id.stop));
initvoice();
start.setOnClickListener(this);
stop.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.start:
break;
case R.id.stop:
break;
}
}
//****************语音部分******************
private void initvoice() {
// 播放
player.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!playState) {
mediaPlayer = new MediaPlayer();
String url = Environment.getExternalStorageDirectory()
+ "/radio.mp3";
try {
if (!isZhuanhuan) {
// 模拟器里播放传url,真机播放传getAmrPath()
// mediaPlayer.setDataSource(url);
mediaPlayer.setDataSource(getAmrPath());
mediaPlayer.prepare();
mediaPlayer.start();
// player.setText("正在播放中");
playState = true;
// 设置播放结束时监听
mediaPlayer
.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (playState) {
// player.setText("播放声音");
playState = false;
}
}
});
}
} 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();
}
} else {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
playState = false;
} else {
playState = false;
}
// player.setText("播放录音");
}
}
});
record = (Button) this.findViewById(R.id.start);
// tvchonglu= (TextView) findViewById(R.id.act_ffzb_tvchonglu);
// 录音
record.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (RECODE_STATE != RECORD_ING) {
scanOldFile();
// mr = new AudioRecorder("voice");
RECODE_STATE = RECORD_ING;
// showVoiceDialog();
if (util == null) {
util = new AudioRecorder2Mp3Util(null, Environment
.getExternalStorageDirectory()
+ "/radio.raw", Environment
.getExternalStorageDirectory()
+ "/radio.mp3");
}
if (canClean) {
util.cleanFile(AudioRecorder2Mp3Util.MP3
| AudioRecorder2Mp3Util.RAW);
}
util.startRecording(MainActivity.this);
canClean = true;
mythread();
}
break;
case MotionEvent.ACTION_UP:
if (RECODE_STATE == RECORD_ING) {
RECODE_STATE = RECODE_ED;
if (dialog!=null&&dialog.isShowing()) {
dialog.dismiss();
}
isZhuanhuan = true;
Toast.makeText(MainActivity.this, "正在保存录音", Toast.LENGTH_LONG).show();
util.stopRecordingAndConvertFile();
isZhuanhuan = false;
Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_LONG).show();
util.cleanFile(AudioRecorder2Mp3Util.RAW);
// 如果要关闭可以
util.close();
util = null;
voiceValue = 0.0;
if (recodeTime < MIX_TIME) {
showWarnToast();
// record.setText("按住开始录音");
RECODE_STATE = RECORD_NO;
} else {
player.setText(((int) recodeTime) + "″");
sec=recodeTime+"";
player.setVisibility(View.VISIBLE);
// tvchonglu.setVisibility(View.VISIBLE);
file = getAmrPath();
// record.setText("录音完成!按住重新录音");
// luyin_txt.setText("录音时间:"+((int)recodeTime));
// luyin_path.setText("文件路径:"+getAmrPath());
}
}
break;
case MotionEvent.ACTION_CANCEL:
// Toast.makeText(FeiFangZhiBaoActivity.this,"cancel",Toast.LENGTH_LONG).show();
if (RECODE_STATE == RECORD_ING) {
RECODE_STATE = RECODE_ED;
if (dialog.isShowing()) {
dialog.dismiss();
}
// dialog.dismiss();
isZhuanhuan = true;
Toast.makeText(MainActivity.this, "正在保存录音", Toast.LENGTH_LONG).show();
util.stopRecordingAndConvertFile();
isZhuanhuan = false;
Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_LONG).show();
util.cleanFile(AudioRecorder2Mp3Util.RAW);
// 如果要关闭可以
util.close();
util = null;
// try {
// recorder.stop();
voiceValue = 0.0;
// } catch (IOException e) {
// e.printStackTrace();
// }
if (recodeTime < MIX_TIME) {
showWarnToast();
// record.setText("按住开始录音");
RECODE_STATE = RECORD_NO;
} else {
player.setText(((int) recodeTime) + "″");
sec=recodeTime+"";
player.setVisibility(View.VISIBLE);
// tvchonglu.setVisibility(View.VISIBLE);
file = getAmrPath();
// record.setText("录音完成!按住重新录音");
// luyin_txt.setText("录音时间:"+((int)recodeTime));
// luyin_path.setText("文件路径:"+getAmrPath());
}
}
break;
}
return false;
}
});
}
// 删除老文件
void scanOldFile() {
File file = new File(Environment.getExternalStorageDirectory(),
"radio.mp3");
if (file.exists()) {
file.delete();
}
}
// 录音时显示Dialog
// void showVoiceDialog() {
// dialog = new Dialog(MainActivity.this, R.style.DialogStyle);
// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);
// dialog.setContentView(R.layout.my_dialog);
// dialog_img = (ImageView) dialog.findViewById(R.id.dialog_img);
// dialog.show();
// }
// 录音时间太短时Toast显示
void showWarnToast() {
Toast.makeText(MainActivity.this,"录音时间太短",Toast.LENGTH_SHORT).show();
}
// Toast toast = new Toast(FeiFangZhiBaoActivity.this);
// LinearLayout linearLayout = new LinearLayout(FeiFangZhiBaoActivity.this);
// linearLayout.setOrientation(LinearLayout.VERTICAL);
// linearLayout.setPadding(20, 20, 20, 20);
//
// // 定义一个ImageView
// ImageView imageView = new ImageView(FeiFangZhiBaoActivity.this);
// imageView.setImageResource(R.drawable.voice_to_short); // 图标
//
// TextView mTv = new TextView(FeiFangZhiBaoActivity.this);
// mTv.setText("时间太短 录音失败");
// mTv.setTextSize(14);
// mTv.setTextColor(Color.WHITE);// 字体颜色
// // mTv.setPadding(0, 10, 0, 0);
//
// // 将ImageView和ToastView合并到Layout中
// linearLayout.addView(imageView);
// linearLayout.addView(mTv);
// linearLayout.setGravity(Gravity.CENTER);// 内容居中
// linearLayout.setBackgroundResource(R.drawable.record_bg);// 设置自定义toast的背景
//
// toast.setView(linearLayout);
// toast.setGravity(Gravity.CENTER, 0, 0);// 起点位置为中间 100为向下移100dp
// toast.show();
// }
// 获取文件手机路径
private String getAmrPath() {
File file = new File(Environment.getExternalStorageDirectory(),
"/radio.mp3");
return file.getAbsolutePath();
}
// 录音计时线程
void mythread() {
recordThread = new Thread(ImgThread);
recordThread.start();
}
// 录音Dialog图片随声音大小切换
// void setDialogImage() {
// if (voiceValue < 200.0) {
// dialog_img.setImageResource(R.drawable.record_animate_01);
// } else if (voiceValue > 200.0 && voiceValue < 400) {
// dialog_img.setImageResource(R.drawable.record_animate_02);
// } else if (voiceValue > 400.0 && voiceValue < 800) {
// dialog_img.setImageResource(R.drawable.record_animate_03);
// } else if (voiceValue > 800.0 && voiceValue < 1600) {
// dialog_img.setImageResource(R.drawable.record_animate_04);
// } else if (voiceValue > 1600.0 && voiceValue < 3200) {
// dialog_img.setImageResource(R.drawable.record_animate_05);
// } else if (voiceValue > 3200.0 && voiceValue < 5000) {
// dialog_img.setImageResource(R.drawable.record_animate_06);
// } else if (voiceValue > 5000.0 && voiceValue < 7000) {
// dialog_img.setImageResource(R.drawable.record_animate_07);
// } else if (voiceValue > 7000.0 && voiceValue < 10000.0) {
// dialog_img.setImageResource(R.drawable.record_animate_08);
// } else if (voiceValue > 10000.0 && voiceValue < 14000.0) {
// dialog_img.setImageResource(R.drawable.record_animate_09);
// } else if (voiceValue > 14000.0 && voiceValue < 17000.0) {
// dialog_img.setImageResource(R.drawable.record_animate_10);
// } else if (voiceValue > 17000.0 && voiceValue < 20000.0) {
// dialog_img.setImageResource(R.drawable.record_animate_11);
// } else if (voiceValue > 20000.0 && voiceValue < 24000.0) {
// dialog_img.setImageResource(R.drawable.record_animate_12);
// } else if (voiceValue > 24000.0 && voiceValue < 28000.0) {
// dialog_img.setImageResource(R.drawable.record_animate_13);
// } else if (voiceValue > 28000.0) {
// dialog_img.setImageResource(R.drawable.record_animate_14);
// }
// }
// 录音线程
private Runnable ImgThread = new Runnable() {
@Override
public void run() {
recodeTime = 0.0f;
while (RECODE_STATE == RECORD_ING) {
if (recodeTime >= MAX_TIME && MAX_TIME != 0) {
imgHandle.sendEmptyMessage(0);
} else {
try {
Thread.sleep(200);
recodeTime += 0.2;
if (RECODE_STATE == RECORD_ING) {
voiceValue = util.getAmplitude();
imgHandle.sendEmptyMessage(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Handler imgHandle = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
// 录音超过15秒自动停止
if (RECODE_STATE == RECORD_ING) {
RECODE_STATE = RECODE_ED;
if (dialog.isShowing()) {
dialog.dismiss();
}
// mr.stop();
util.stopRecordingAndConvertFile();
Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_LONG).show();
util.cleanFile(AudioRecorder2Mp3Util.RAW);
// 如果要关闭可以
util.close();
util = null;
voiceValue = 0.0;
if (recodeTime < 1.0) {
showWarnToast();
// record.setText("按住开始录音");
RECODE_STATE = RECORD_NO;
} else {
// record.setText("录音完成!点击重新录音");
player.setText(((int) recodeTime) + "″");
player.setVisibility(View.VISIBLE);
// luyin_txt.setText("录音时间:"+((int)recodeTime));
// luyin_path.setText("文件路径:"+getAmrPath());
file = getAmrPath();
}
}
break;
case 1:
// setDialogImage();
break;
default:
break;
}
}
};
};
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
//****************语音部分end******************
}
然后,实际测试中,发现有的部分手机cpu是64位的,然而上面的so文件是没有64位的,推荐一个第三方,简单易用https://github.com/GavinCT/AndroidMP3Recorder
</span></span>
android原生录音
最新推荐文章于 2025-05-06 00:15:00 发布