1

我正在尝试制作一个音频应用程序,它允许通过麦克风通过扬声器投射声音。我为这个应用程序做了一个切换按钮,但点击它后,它保持突出显示,我无法调整系统音量。那么我该如何打破这个循环呢?

私人无效setUpButton(){

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);
             }

}

    }});


}
4

1 回答 1

0

切换按钮保持突出显示,因为您while(is){...}在主 UI 线程中运行无限循环(根据 323go 的评论)。主 UI 线程忙于不断地运行无限循环,因此没有机会处理更多的 UI 操作,例如进一步的按钮状态更新等。

使用消息处理程序将无限循环移动到它自己的线程中,以处理来自主 UI 线程的消息,告诉它何时启动或停止等。这将释放主 UI 线程来做它应该做的事情......处理用户界面。
例如:

主要活动

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;
    }
}

根据您的描述,您想要实时录制、操作(调整音量等)和输出音频。对于该级别的音频处理,您将需要了解和使用线程。如果您还没有很好地掌握线程,这里有很多很好的示例和教程。

于 2013-11-05T08:08:16.433 回答