您的位置:首页 > 其它

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

2015-11-17 16:57 399 查看
之前接了一个开发测试手机麦克风寿命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 implements
OnClickListener {
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());
}

@Override
public 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,以便新的测试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: