【发布时间】:2014-02-27 23:06:12
【问题描述】:
我正在尝试为我的一门课程构建蓝牙对讲机应用程序,但我似乎无法使其正常工作。我修改了 BluetoothChat 示例 (http://developer.android.com/guide/topics/connectivity/bluetooth.html) 以尝试满足我的需求,并且我可以成功地将录音从一部手机传输到另一部手机,但结果非常不稳定。我正在使用 AudioRecord 和 AudioTrack 进行录制和播放。
我有这些全局变量
private static final int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private AudioTrack audioTrack = null;
private int bufferSize = 0;
private Thread recordingThread = null;
private boolean isRecording = false;
在我的 onCreate 方法中,我设置了 bufferSize 并初始化了 AudioTrack。
bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
RECORDER_SAMPLERATE, AudioFormat.CHANNEL_OUT_STEREO,
RECORDER_AUDIO_ENCODING, bufferSize, AudioTrack.MODE_STREAM);
这是我按下记录/发送按钮时的代码(我目前只能记录 3 秒的数据。)
private void startRecording() {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING, bufferSize);
int i = recorder.getState();
if (i == 1)
recorder.startRecording();
isRecording = true;
new Timer().schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run()
{
enableButtons(false);
if(null != recorder){
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
}
});
}
}, 3000);
recordingThread = new Thread(new Runnable() {
@Override
public void run() {
writeOutAudioData();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
private void writeOutAudioData() {
byte data[] = new byte[bufferSize];
int read = 0;
while (isRecording)
{
read = recorder.read(data, 0, bufferSize);
if (AudioRecord.ERROR_INVALID_OPERATION != read)
{
mChatService.write(data);
//TODO
}
}
}
这是处理所有传入和传出传输的代码
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
// Start the service over to restart listening mode
BluetoothChatService.this.start();
break;
}
}
}
/**
* Write to the connected OutStream.
* @param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
这是从 BluetoothChatService 获取信息的处理程序的代码
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (D)
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to,
mConnectedDeviceName));
mConversationArrayAdapter.clear();
break;
case BluetoothChatService.STATE_CONNECTING:
setStatus(R.string.title_connecting);
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
setStatus(R.string.title_not_connected);
break;
}
break;
case MESSAGE_WRITE:
//byte[] writeBuf = (byte[]) msg.obj;
break;
case MESSAGE_READ:
final byte[] readBuf = (byte[]) msg.obj;
final byte bytes = (byte) msg.arg1;
Thread audioPlay = new Thread()
{
public void run(){
audioTrack.play();
audioTrack.write(readBuf, 0, readBuf.length);
audioTrack.stop();
}
};
audioPlay.start();
break;
}
}
};
我只是不明白 ConnectedThread 类中 byte[] 缓冲区的大小。我应该将其保留在 1024 还是将其更改为其他内容?而且我无法弄清楚读取这些传入字节并将它们写入 AudioTrack 进行播放(没有静态)的正确方法。 我在一部手机上使用 Android 4.3,在另一部手机上使用 4.2.2。 任何帮助将不胜感激!谢谢!
【问题讨论】:
-
确实找到了解决办法
标签: android bluetooth audio-streaming audiorecord audiotrack