我正在嘗試爲我的一個課程建立一個藍牙對講機應用程序,但我似乎無法使其正常工作。我修改了BluetoothChat示例(http://developer.android.com/guide/topics/connectivity/bluetooth.html)以適應我的需求,並且我可以成功地將語音錄製從一部手機傳輸到另一部手機,但它顯得非常笨拙。我正在使用AudioRecord和AudioTrack進行錄製和播放。如何使用藍牙將音頻從Android手機流式傳輸到其他Android手機?
我有這些全局變量
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方法我設置了緩衝區大小和初始化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
獲取信息回我的處理程序代碼10private 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。 任何幫助將不勝感激!謝謝!
的確找到了解決辦法 – kId