Android 困惑的如何停止声音循环?
我正在尝试制作一个音频应用程序,允许声音通过麦克风通过扬声器投射。我为这个应用程序做了一个切换按钮,但在点击它之后,它会一直高亮显示,我无法调整系统音量。 那么我如何打破这个循环呢 专用无效设置按钮{Android 困惑的如何停止声音循环?,android,audio,Android,Audio,我正在尝试制作一个音频应用程序,允许声音通过麦克风通过扬声器投射。我为这个应用程序做了一个切换按钮,但在点击它之后,它会一直高亮显示,我无法调整系统音量。 那么我如何打破这个循环呢 专用无效设置按钮{ final ToggleButton tb = (ToggleButton) findViewById(R.id.tb); tb.setOnClickListener(new View.OnClickListener (){ public void onClick(View view)
final ToggleButton tb = (ToggleButton) findViewById(R.id.tb);
tb.setOnClickListener(new View.OnClickListener (){
public void onClick(View view) {
// TODO Auto-generated method stub
boolean on = ((ToggleButton) view).isChecked();
if (on){
boolean is = true;
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
int buffersize = AudioRecord.getMinBufferSize(20000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC, 20000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize);
AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC, 20000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize, AudioTrack.MODE_STREAM);
atrack.setPlaybackRate(20000);
byte[] buffer = new byte[buffersize];
arec.startRecording();
atrack.play();
while(is) {
arec.read(buffer, 0, buffersize);
atrack.write(buffer, 0, buffer.length);
}
}
}});
}
切换按钮保持高亮显示,因为根据323go的评论,您的无限whileis{…}循环在主UI线程中运行。主UI线程会一直忙于运行无限循环,因此没有机会处理任何其他UI操作,例如进一步的按钮状态更新等 使用消息处理程序将无限循环移动到它自己的线程中,以处理来自主UI线程的消息,告诉它何时启动或停止等。这将释放主UI线程来执行它应该执行的操作…处理用户界面。 例如: 主要活动 音频线程
根据您的描述,您希望录制、操作、调整音量等,并实时输出音频。对于这一级别的音频处理,您需要了解和使用线程。如果您还没有很好地掌握线程,那么有很多很好的示例和教程。这不应该在ui上运行。Cre吃掉一个威胁并在那里运行它。你只是在一个永远不会结束的循环中。你应该使用其他条件来读取缓冲区,而不是使用始终为真的布尔值。我可以有其他条件的示例来读取它吗?很抱歉这么麻烦。非常感谢!如果这没有帮助,我将阅读更多内容!不客气。顺便说一句,我找到了这个我自己真的很有帮助。PS:如果你的问题有帮助,记得接受他们的答案。嗨,我用了你给出的例子,效果很好。但是,我似乎根本不能停止录制和播放。是因为我包括了一个while循环,因为它需要不断阅读和播放。whilemRunning{…}我的示例代码中的循环充当无限循环,您应该在其中执行arec.read和atrack.write。如果您已经这样做了,请不要将它们嵌套在另一个无限循环中。您好,感谢您的回复。我假设我将录制和播放所需的代码放入if mPlayAudio{…}是吗?如果是这样的话,我只收到一小会儿的声音。如果我做错了什么,请纠正我。
public class MainActivity {
private AudioScheduler mAudioThread;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAudioThread = new AudioThread();
mAudioThread.start();
final ToggleButton tb = (ToggleButton) findViewById(R.id.tb);
tb.setOnClickListener(new View.OnClickListener (){
public void onClick(View view) {
Message messageToAudioThread = Message.obtain();
boolean on = ((ToggleButton) view).isChecked();
if (on){
messageToAudioThread.what = AudioThread.PLAY;
} else {
messageToAudioThread.what = AudioThread.STOP;
}
mAudioThread.getHandler().sendMessage(messageToAudioThread);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mAudioThread.close();
}
}
public class AudioThread extends Thread {
// Handler message constants
public static final int PLAY = 0;
public static final int STOP = 1;
// Class variables
private boolean mRunning = false;
private boolean mPlayAudio = false;
private static class AudioThreadHandler extends Handler {
private final WeakReference<AudioThread> mThread;
public AudioThreadHandler(AudioThread thread) {
mThread = new WeakReference<AudioThread>(thread);
}
@Override
public void handleMessage(Message msg) {
AudioThread thread = mThread.get();
if (thread != null) {
switch(msg.what) {
case PLAY:
thread.mPlayAudio = true;
break;
case STOP:
thread.mPlayAudio = false;
break;
}
}
}
};
private final AudioThreadHandler mAudioThreadHandler = new AudioThreadHandler(this);
@Override
public void run() {
try {
mRunning = true;
while(mRunning) {
if (mPlayAudio) {
// Your code for handling audio recording/playback
// or whatever goes here
} else {
// If you have code you want to keep executing while
// audio is not active, stick it here
}
}
} catch (Exception e) {
Log.e("AudioThread", "Thread Loop Exception: " + e);
}
}
public void close() {
mRunning = false;
}
public Handler getHandler() {
return mAudioThreadHandler;
}
}