此demo涉及到麦克风 动画 以及线程的使用:
开启麦克风录制声音:
为实现分贝测试, 需要对周围声音进行录制, 新建MicActivity 类, 使用MediaRecorder(视频/ 音频 录制类)来气麦克风录制音频, 并使用File 创建文件将音频保存到手机, 使用AnimationDrawable 用于显示录音的动画效果:
public class MicActivity extends AppCompatActivity {private MediaRecorder mediaRecorder; //麦克风private File mAudiofile, mSampleDir; //录音文件保存private ImageView iv_wave_left,iv_wave_right; //声音动画图片private AnimationDrawable ad_left, ad_right; //左右动画属性@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_mic);getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //保持屏幕不暗initView();}private void initView() {iv_wave_left = (ImageView) findViewById(R.id.iv_record_wave_left);iv_wave_right = (ImageView) findViewById(R.id.iv_record_wave_right);ad_left = (AnimationDrawable) iv_wave_left.getBackground(); //动画效果ad_right = (AnimationDrawable) iv_wave_right.getBackground();ad_left.start();ad_right.start(); //开启动画}@Overrideprotected void onStart() {super.onStart();mediaRecorder = new MediaRecorder();mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //姻缘为麦克风mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR); //音频文件的编码mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //设置audio的格式try {mSampleDir = Environment.getExternalStorageDirectory(); //获取手机内存路径//用IM+ 系统当前时间为文件名建立 .amr的文件, 文件路径为mSampleDirmAudiofile = File.createTempFile("IM" + System.currentTimeMillis(), ".arm", mSampleDir);}catch (IOException e){e.printStackTrace();}mediaRecorder.setOutputFile(mAudiofile.getAbsolutePath()); //设置声音输出文件的路径try {mediaRecorder.prepare(); //准备录制}catch (Exception e){e.printStackTrace();}mediaRecorder.start(); //开始录制}//返回功能public void onBack(){MicActivity.this.finish(); //关闭当前页面}
}
将声音转换为分贝值:
前面已经实现了声音的录制, 现在实现分贝的显示, 首先需要自定义Thread 使用该线程将麦克风录制的声音转换为分贝并显示出来。
class MicrophoneThread extends Thread{ //测量当前分贝值通知UI修改final float minAngle = (float) Math.PI * 4 / 11;float angle; //分贝值@Overridepublic void run() {while (true){angle = 100 * minAngle * mediaRecorder.getMaxAmplitude() / 32768;if (angle > 1000){angle = 100;}//构造方法的字符格式在这里如果不足两位,会补0DecimalFormat decimalFormat = new DecimalFormat("0.00");String p = decimalFormat.format(angle); //format返回的是字符串, 分贝值try {Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}}}
设置全局对象:
private MicrophoneThread microphoneThread = new MicrophoneThread(); //线程用于实时录制环境声音
在onStart() 方法中加入
microphoneThread.start(); //开启线程声音转换为分贝值
通过发送消息 实现更新页面:
使用Handler 接收消息更新UI, 从而更新当前页面的分贝值。 需要对控件进行声明:
private TextView textView1; //用于显示分贝值private MHandler mHandler = new MHandler(); //接收消息修改分贝值class MHandler extends Handler{@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case 1: //返回消息1textView1.setText(msg.obj.toString()); //修改分贝值break;}}}
初始化TextView, 用于显示当前分贝值, 在init() 中实例化:
textView1 = (TextView) findViewById(R.id.textView1);
接着发送当前分贝值给Handler, 更新当前页面分贝值:
在麦克风线程中添加代码:
String p = decimalFormat.format(angle); //format返回的是字符串, 分贝值Message message = new Message();message.what = 1;message.obj = p;mHandler.sendMessage(message); //发送当前分贝值
实现主界面向分贝测试仪界面跳转:
textView = (TextView) findViewById(R.id.text);textView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, MicActivity.class);startActivity(intent);}});}