您的位置:首页 > 移动开发 > Android开发

解决 android audiorecord 蓝牙耳机 重启导致录音数据异常问题

2017-07-05 14:16 821 查看

解决 android audiorecord 蓝牙耳机 重启导致录音数据异常问题

蓝牙 两种同步链路(SCO)和异步链路(ACL)。A2DP(Advanced
Audio Distribution Profile 高级音频传输模型)是跑在ACL链路上去高品质音频协议。A2DP定义了ACL(Asynchronous
Connectionless 异步无连接)信道上传送单声道或立体声等高质量音A2DP 功能频信息的协议和过程。

蓝牙物理链路SCO(Synchronous Connection Oriented)主要用来传输对时间要求很高的数据通信,
另外的一种链路是ACL(Asynchronous Connectionless)。
SCO连接为对称连接,利用保留时隙传送数据包。连接建立后,主设备和从设备可以不被选中就发送SCO数据包。SCO数据包既可以传送话音,也可以传送数据,但在传送数据时,只用于重发被损坏的那部分的数据。

ACL链路就是定向发送数据包,它既支持对称连接,也支持不对称连接(既可以一对一,也可以一对多)。主设备负责控制链路带宽,并决定微微网中的每个从设备可以占用多少带宽和连接的对称性。从设备只有被选中时才能传送数据。ACL链路也支持接收主设备发给微微网中所有从设备的广播消息。

我们要选用的SCO模式,A2DP模式是默认链接的只进不出,蓝牙只能听到手机播放音乐不能录制声音

1.获取 AudioMannager

mAudioManager = ((AudioManager) getSystemService(Context.AUDIO_SERVICE));


2. 设置音频模式为交流模式

mAudioManager.setMode(mAudioManager.MODE_IN_COMMUNICATION);


3. 注册 蓝牙监控事件

mAudioManager.registerMediaButtonEventReceiver(new ComponentName(
this,
MusicIntentReceiver.class));


@SuppressLint("InlinedApi")
public class MusicIntentReceiver extends BroadcastReceiver {
private static final String LOG_TAG = "jni";
private Context mContext;
private KeyService mKeyService;

@Override
public void onReceive(Context context, Intent intent) {
mContext = context;
mKeyService = new KeyService(mContext);
if (intent.getAction().equals(
android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
Toast.makeText(context, "Headphones disconnected.",
Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Headphones disconnected.!");

// send an intent to our MusicService to telling it to pause the
// audio
// context.startService(new Intent(MusicService.ACTION_PAUSE));

} else if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {
Log.i(LOG_TAG, "ACTION_MEDIA_BUTTON!");
KeyEvent keyEvent = (KeyEvent) intent.getExtras().get(
Intent.EXTRA_KEY_EVENT);
if (keyEvent.getAction() != KeyEvent.ACTION_DOWN)
return;

switch (keyEvent.getKeyCode()) {
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
// context.startService(new
// Intent(MusicService.ACTION_TOGGLE_PLAYBACK));
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
// context.startService(new Intent(MusicService.ACTION_PLAY));
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
// context.startService(new Intent(MusicService.ACTION_PAUSE));
break;
case KeyEvent.KEYCODE_MEDIA_STOP:
// context.startService(new Intent(MusicService.ACTION_STOP));
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
// context.startService(new Intent(MusicService.ACTION_SKIP));
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
// TODO: ensure that doing this in rapid succession actually
// plays the
// previous song
// context.startService(new Intent(MusicService.ACTION_REWIND));
break;
}
} else if (intent.getAction().equals(
BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {

int state = intent.getIntExtra(
BluetoothAdapter.EXTRA_CONNECTION_STATE, 0);

if (state == BluetoothAdapter.STATE_CONNECTED
) {
Log.i(LOG_TAG, "BluetoothAdapter.ACTION_CONNECTION_STATE_CONNECT");
}
else if (state == BluetoothAdapter.STATE_DISCONNECTED){
Log.i(LOG_TAG, "BluetoothAdapter.ACTION_CONNECTION_STATE_DISCONNECTED");
}
} else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.i(LOG_TAG, "Intent.ACTION_BOOT_COMPLETED");
} else if (intent.getAction().equals("android.intent.action.UPDATE_SUSPEND_TIME_BY_HAND")) {
Log.i(LOG_TAG, "Intent.UPDATE_SUSPEND_TIME_BY_HAND");
} else {
//            Log.i(LOG_TAG, "other intent");
}
}


4. 开启线程监控 控制录音

if (mKeyService.isBtConect()) {
if (!is_record) {

try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mAudioManager.setMode(mAudioManager.MODE_IN_COMMUNICATION);
mAudioManager.startBluetoothSco();
mAudioManager.setSpeakerphoneOn(false);
mAudioManager.setBluetoothScoOn(true);
Log.i(LOG_TAG, "bluetooth is connect at start activity =  " + mAudioManager.isBluetoothScoOn() + mAudioManager.getMode());

record = new RecordPlayActivity();
record.playStart();
is_record = true;

}

} else {
if (is_record == true) {
//                            mAudioManager.stopBluetoothSco();
mAudioManager.setMode(mAudioManager.MODE_NORMAL);
//                            mAudioManager.setBluetoothScoOn(false);
//                            mAudioManager.stopBluetoothSco();
record.stopRecord();
record = null;
is_record = false;
}
}
注意红色字体,这个是解决蓝牙重新连接开始录音的关键,因为蓝牙重连接虽然广播收到了通知,但是蓝牙耳机自己还没准备好,所以当接收到蓝牙耳机连接好的通知,在延迟一定的时间,既可以完美解决了这个问题了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐