我设计使用文本到语音应用程序和它的作品。 现在我想使用蓝牙耳机(未AD2P)接收音频。 阅读Android文档约startBluetoothScoOn我看到:
需要注意的是手机应用程序总是对电话的SCO连接的使用优先级。 如果这种方法被调用,而手机处于通话将被忽略。 类似地,如果接收或发送呼叫时的应用程序正在使用SCO连接,该连接将丢失的应用程序和当呼叫结束时不会自动返回。
现在,我的问题是:
- 我需要听手机状态重新调用startBluetoothScoOn当通话结束? 如果是的话,怎么样? 我没有找到任何例子;
- 我需要听耳机连接/断开? 如果是的话,怎么样?
我想,当通话结束或我的耳机已关闭,该系统提供了一个SCO_AUDIO_STATE_DISCONNECTED,对不对?
编辑:我张贴我使用的代码:
public class BluetoothHeadSetManager implements
BluetoothProfile.ServiceListener {
BluetoothManager manager;
BluetoothHeadset bluetoothHeadset;
Context context;
HeadSetBroadcastReceiver recv;
public BluetoothHeadSetManager(Context cont, BluetoothManager manager) {
this.manager = manager;
this.context = cont;
recv = null;
}
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
// mBluetoothHeadset is just a headset profile,
// it does not represent a headset device.
bluetoothHeadset = (BluetoothHeadset) proxy;
List<BluetoothDevice> devices = bluetoothHeadset.getConnectedDevices();
if (devices.size() > 0)
manager.onHeadSetConnected();
// During the active life time of the app, a user may turn on and off
// the headset.
// So register for broadcast of connection states.
if (recv == null) {
recv = new HeadSetBroadcastReceiver();
context.registerReceiver(recv, new IntentFilter(
BluetoothDevice.ACTION_ACL_CONNECTED));
context.registerReceiver(recv, new IntentFilter(
BluetoothDevice.ACTION_ACL_DISCONNECTED));
}
}
public void close() {
if (recv != null)
context.unregisterReceiver(recv);
if (bluetoothHeadset != null)
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(
BluetoothProfile.HEADSET, bluetoothHeadset);
}
@Override
public void onServiceDisconnected(int arg0) {
Logger.getInstance().writeLog("onServiceDisconnected called");
if (recv != null)
context.unregisterReceiver(recv);
manager.onHeadSetDisconnected();
}
private class HeadSetBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice mConnectedHeadset;
if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
mConnectedHeadset = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
BluetoothClass bluetoothClass = mConnectedHeadset
.getBluetoothClass();
if (bluetoothClass != null) {
// Check if device is a headset. Besides the 2 below, are
// there other
// device classes also qualified as headset?
int deviceClass = bluetoothClass.getDeviceClass();
if (deviceClass == BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE
|| deviceClass == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET) {
// override this if you want to do other thing when the
// device is connected.
manager.onHeadSetConnected();
}
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
manager.onHeadSetDisconnected();
}
}
}
上海合作组织接收器:
public class BluetoothScoReceiver extends BroadcastReceiver {
BluetoothManager manager;
public BluetoothScoReceiver(BluetoothManager manager) {
this.manager = manager;
}
@Override
public void onReceive(Context arg0, Intent intent) {
Bundle extras = intent.getExtras();
if (extras == null)
return;
int state = extras.getInt(AudioManager.EXTRA_SCO_AUDIO_STATE);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED)
manager.onScoConnected();
else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED)
manager.onScoDisconnected();
}
主要:
@Override
public void onScoConnected() {
this.headsetReady = true;
requestState = CONNECTED;
}
@Override
public void onScoDisconnected() {
this.headsetReady = false;
if (requestState == TRY_CONNECTION && headsetConnected)
this.onHeadSetConnected(); //try again
}
@Override
public void onHeadSetConnected() {
headsetConnected = true;
if (requestState == TRY_CONNECTION) {
requestState = TRY_CONNECTION;
audioMng.setMode(AudioManager.MODE_NORMAL);
audioMng.stopBluetoothSco();
audioMng.setMode(AudioManager.MODE_IN_CALL);
audioMng.startBluetoothSco();
} else {
requestState = TRY_CONNECTION;
audioMng.setMode(AudioManager.MODE_IN_CALL);
audioMng.startBluetoothSco();
}
}
@Override
public void onHeadSetDisconnected() {
audioMng.setMode(AudioManager.MODE_NORMAL);
if (requestState != NOT_CONNECTED_IDLE) {
audioMng.stopBluetoothSco();
audioMng.setBluetoothScoOn(false);
requestState = NOT_CONNECTED_IDLE;
}
headsetConnected = false;
}
@SuppressLint("InlinedApi")
@SuppressWarnings("deprecation")
@Override
public void startBluetooth() {
Intent currentScoState;
if (audioMng.isBluetoothScoAvailableOffCall()) {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null)
return;
blueInit = adapter.getProfileProxy(this, headsetMng,
BluetoothProfile.HEADSET);
if (blueInit) {
scoListner = new BluetoothScoReceiver(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
currentScoState = this
.registerReceiver(
scoListner,
new IntentFilter(
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED));
else
currentScoState = this
.registerReceiver(
scoListner,
new IntentFilter(
AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED));
Bundle extras = currentScoState.getExtras();
if (extras == null)
return;
if (extras
.getInt(AudioManager.EXTRA_SCO_AUDIO_STATE) == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
this.headsetReady = true;
requestState = CONNECTED;
} else {
this.headsetReady = false;
requestState = NOT_CONNECTED_IDLE;
}
}
}
}
@Override
public void stopBluetooth() {
this.onHeadSetDisconnected();
if (blueInit) {
headsetMng.close();
this.unregisterReceiver(scoListner);
}
}