麦克风打开时不断更改TextView

时间:2014-04-15 00:12:46

标签: android textview mediarecorder android-mediarecorder

我正在尝试让我的应用程序在按下按钮时开始录制麦克风的声音。我想让它打印出麦克风打开时记录的声音幅度到我的TextView对象。

以下是RecordSound类的代码:

import android.media.MediaRecorder;

public class RecordSound {
private MediaRecorder mRecorder = null;

public void start() {
    if (mRecorder == null) {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setOutputFile("/dev/null");

        try {
            mRecorder.prepare();
        } catch (Exception e) {
            e.printStackTrace();
        }

        mRecorder.start();
    }
}

public void stop() {
    if (mRecorder != null) {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
    }
}

public double getAmplitude() {
    if (mRecorder != null) {
        return mRecorder.getMaxAmplitude();
    }
    else {
        return 0;
    }
}

public boolean isOn() {
    if (mRecorder == null) {
        return false;
    }
    else {
        return true;
    }
}
}

以下是MainActivity类的代码:

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
private RecordSound mRecorder = null;
private TextView tv = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button recordButton = (Button) findViewById(R.id.bRecord);
    tv = (TextView)findViewById(R.id.data);
    mRecorder = new RecordSound();

    recordButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mRecorder.isOn()) {
                mRecorder.stop();
            }
            else {
                mRecorder.start();
            }

            if (mRecorder.isOn()) {
//                  long t= System.currentTimeMillis();
//                  long end = t+15000;
//                  while(System.currentTimeMillis() < end) {
//                      tv.setText(String.valueOf(mRecorder.getAmplitude()));
//                  }
//                  
                tv.setText(String.valueOf(mRecorder.getAmplitude()));
            }
        }
    });

    while (mRecorder != null && mRecorder.isOn()) {
        tv.setText(String.valueOf(mRecorder.getAmplitude()));
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

注释掉的代码是我尝试制作麦克风记录并在麦克风开启的前十五秒内打印振幅。

目前我可以按按钮开始录制。然后它会将幅度值打印到TextView,但始终为0.0。我已在while方法内外的几个不同位置尝试了onClick()语句。当麦克风正在录制声音时,我似乎无法动态更新TextView

1 个答案:

答案 0 :(得分:0)

我并没有真正尝试运行您的代码,我对Android中的MediaRecoder了解不多。但我想你的代码问题是你的while循环在onCreate()方法内,所以循环只在调用onCreate()时运行(如果你还没有理解的话)当Android系统调用您应用的onCreate()方法时,我建议您阅读Activity Lifecycle文档。很明显,当while循环运行时,您的介质记录器尚未启动,因此该声明:

tv.setText(String.valueOf(mRecorder.getAmplitude()));

根本没有运行。

然后当你第一次按下按钮时,媒体编码器就会启动,然后就会得到振幅,同时设置TextView值为第一次,也只有一次。 MediaRecorder.getMaxAmplitude()的文档说它返回

  

自上次呼叫以来测量的最大绝对振幅,或0时   第一次呼吁

这就是为什么你总是在TextView上显示0.0

为了在麦克风打开时动态更新TextView,您应该维护一个后台线程来检查媒体重新编码器并定期获取振幅。为此,您可以考虑使用TimerTimerTask。但由于Android系统不允许您从主线程以外的任何线程更新UI,因此您可能必须使用Handler。我发现this answer对您有用。