安卓手机麦克风测试应用开发

来源:互联网 发布:苹果4s越狱软件 编辑:程序博客网 时间:2024/05/08 02:30

        之前接了一个开发测试手机麦克风寿命apk的任务,主要要求是:1、可以控制手机麦克风的开启与关闭;2、麦克风接收的声音从听筒发出;3、可设置测试时间。下面我对该应用的开发做一相关讲解并附上代码。

        开发难点:1、在话筒与听筒均开启的情况下,进入话筒的声音无法直接从听筒发出,需要做相关转换输出处理;

                            2、时间任务的启动与停止;

                            3、时间设置与数据类型的转换。

        解决方法:1、引入音频缓冲区作为音频接收与播放的中专(Buffer),以音频声音作为对象由缓冲区接收存储(音频录制),以缓冲区的对象作为播放对象由听筒播放出来;

                            2、将麦克风开启方法以线程体来定义和调用;

                            3、以EditText作为时间输入的控件来设置测试时长,并前值转换为长整型。

以下是代码:

主类:AndroidMikeTestActivity.java

package com.cfzz.amt;import com.android.methed.Run_Methed;import android.os.Bundle;import android.app.Activity;import android.view.KeyEvent;import android.view.View;import android.widget.Button;import android.view.View.OnClickListener;import android.widget.EditText;import android.widget.TextView;import android.view.WindowManager;import android.os.SystemClock;import android.widget.Chronometer;import java.util.Timer;import java.util.TimerTask;public class AndroidMikeTestActivity extends Activity implementsOnClickListener {Run_Methed run_Metned = new Run_Methed();Thread thread = null;private EditText timelength;Button playbutton, stopbutton;private Timer timer;private Chronometer time;private long recordingTime = 0;public void onRecordStart()// time start{time.setBase(SystemClock.elapsedRealtime() - recordingTime);// 跳过已经记录了的时间,起到继续计时的作用time.start();}public void onRecordPause()// time pause{time.stop();recordingTime = SystemClock.elapsedRealtime() - time.getBase();// 保存这次记录了的时间}public void onRecordStop()// time stop{recordingTime = 0;time.setBase(SystemClock.elapsedRealtime());}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);timelength = (EditText) this.findViewById(R.id.timelength);timelength.setText("0");time = (Chronometer) this.findViewById(R.id.chronometer);//引入计时器控件time.setBase(SystemClock.elapsedRealtime());//初始化时间// 按键监听playbutton = (Button) findViewById(R.id.playbutton);stopbutton = (Button) findViewById(R.id.stopbutton);playbutton.setOnClickListener(this);stopbutton.setOnClickListener(this);}public void onClick(View v) {switch (v.getId()) {case R.id.playbutton:// 按钮【开】long t = Long.parseLong("" + timelength.getText());//以小时为单位设置时间if (t != 0) {Thread thread = new Thread(run_Metned);//将麦克风开启方法加入线程体中thread.start();onRecordStart();long s = 1000 * 3600 * t ;//将小时数转化为毫秒数timer = new Timer(true);TimerTask task = new TimerTask()// 计时任务设置{public void run() {run_Metned.no();onRecordPause();timer.cancel();}};timer.schedule(task, s, 1);//s毫秒后停止} else if (t == 0) {run_Metned.no();} else if (timelength.getText() == null) {run_Metned.no();timelength.setText("0");}break;case R.id.stopbutton:// 按钮【关】run_Metned.no();timer.cancel();onRecordStop();onRecordPause();timelength.setText("0");break;}}int i = 0;public boolean onKeyDown(int keyCode, KeyEvent event) //双击返回键退出
        {if (keyCode == KeyEvent.KEYCODE_BACK&& event.getAction() == KeyEvent.ACTION_DOWN) {long t = Long.parseLong("" + timelength.getText());i++;if (i == 2 && t != 0) {run_Metned.no();timer.cancel();onRecordStop();onRecordPause();}if (i == 3) {finish();}}return true;}/* * @Override protected void onDestroy() { *  * thread.interrupt(); run_Metned.no(); timer.cancel(); onRecordStop(); * super.onDestroy(); } */}
方法类:

Run_Methed.java

package com.android.methed;import android.media.AudioFormat;import android.media.AudioManager;import android.media.AudioRecord;import android.media.AudioTrack;import android.media.MediaRecorder;public class Run_Methed implements Runnable {// 是否录放的标记boolean isRecording = false;static final int frequency = 44100;@SuppressWarnings("deprecation")static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;// 定义录放音缓冲区大小int recBufSize, playBufSize;// 实例化录音对象AudioRecord audioRecord;// 实例化播放对象AudioTrack audioTrack;public Run_Methed() {// 调用getMinBufferSize方法获得录音的最小缓冲空间recBufSize = AudioRecord.getMinBufferSize(frequency,channelConfiguration, audioEncoding);// 调用getMinBufferSize方法获得放音最小的缓冲区大小playBufSize = AudioTrack.getMinBufferSize(frequency,channelConfiguration, audioEncoding);// -----------------------------------------、// 调用构造函数实例化录音对象audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,channelConfiguration, audioEncoding, recBufSize);// 调用构造函数实例化放音对象,以听筒模式播放audioTrack = new AudioTrack(AudioManager.<span style="background-color: rgb(51, 204, 255);">STREAM_VOICE_CALL</span>, frequency,channelConfiguration, audioEncoding, playBufSize,AudioTrack.MODE_STREAM);}// 线程体public void run() {try {byte[] buffer = new byte[recBufSize];audioRecord.startRecording();// 开始录制audioTrack.play();// 开始播放this.isRecording = true;while (isRecording) {// 从MIC保存数据到缓冲区int bufferReadResult = audioRecord.read(buffer, 0, recBufSize);byte[] tmpBuf = new byte[bufferReadResult];System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);// 写入数据就播放audioTrack.write(tmpBuf, 0, tmpBuf.length);}audioTrack.stop();audioRecord.stop();} catch (Throwable t) {}}// 停止方法public void no() {isRecording = false;}}

Track_Methed,java

package com.android.methed;import android.media.AudioFormat;import android.media.AudioManager;import android.media.AudioTrack;public class Track_Methed implements Runnable {// 播放暂存int out_size;// 放音对象AudioTrack track = null;public void run() {}// 播送方法public void track() {out_size = android.media.AudioTrack.getMinBufferSize(8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT);track = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT, out_size,AudioTrack.MODE_STREAM);}}
布局文件:

main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_marginTop="24dp"        android:text="测试时间(小时/H)"        android:textAppearance="?android:attr/textAppearanceLarge"        android:textSize="12pt" />    <EditText        android:id="@+id/timelength"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_below="@+id/textView1"        android:layout_marginTop="20dp"
        <!-- 未输入值时会显示的内容,作为输入提示-->        android:hint="请输入测试小时数!"        android:layout_gravity="center_horizontal"        android:textSize="12pt"
        <!-- 限定输入值为整数 -->        android:inputType="number"        android:singleLine="true" />    <Button        android:id="@+id/playbutton"        android:layout_width="100dip"        android:layout_height="60dip"        android:layout_below="@+id/timelength"        android:layout_marginTop="120dp"        android:onClick="onClick"        android:text="@string/playbutton"        android:textSize="12pt" />    <Button        android:id="@+id/stopbutton"        android:layout_width="100dip"        android:layout_height="60dip"        android:layout_alignBaseline="@+id/playbutton"        android:layout_alignBottom="@+id/playbutton"        android:layout_alignParentRight="true"        android:onClick="onClick"        android:text="@string/stopbutton"        android:textSize="12pt" />    <Chronometer        android:id="@+id/chronometer"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_above="@+id/stopbutton"        android:layout_centerHorizontal="true"        android:layout_marginBottom="28dp"        android:format="%s"        android:textColor="#00FF00"        android:textSize="80px" /></RelativeLayout>
AndroidManifest.xml

注意添加相关权限

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.cfzz.amt"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk android:minSdkVersion="15" />    <span style="background-color: rgb(102, 255, 255);"><uses-permission android:name="android.permission.RECORD_AUDIO" /></span>    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity android:name="org.achartengine.GraphicalActivity" />        <activity            android:name="com.cfzz.amt.AndroidMikeTestActivity"            android:screenOrientation="portrait"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
运行效果图:



        到此,麦克风测试程序就可以运行了,在编辑框内输入小时数,再点击开始即可运行麦克风,这时可以从听筒中听到麦克风里的声音,当时间到达设定时间时会自动停止,同时计时器也会暂停。当按停止按钮时,时间设置和计时器会同时置为00:00,以便新的测试。



0 0