Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 蓝牙SCO在来电后失败_Android_Bluetooth_Bluetooth Sco - Fatal编程技术网

Android 蓝牙SCO在来电后失败

Android 蓝牙SCO在来电后失败,android,bluetooth,bluetooth-sco,Android,Bluetooth,Bluetooth Sco,我正在尝试通过SCO发送应用程序的所有音频 我能够成功地发送音频 但当来电时,我需要断开与SCO的连接,以便应用程序音频不会干扰呼叫 问题是,当我尝试在通话后将音频重新路由到SCO时,它不起作用 以下是我用来向SCO发送音频的代码: public class BluetoothManager { // For Bluetooth connectvity private static String TAG = "BluetoothManager"; private static Bluetooth

我正在尝试通过SCO发送应用程序的所有音频

我能够成功地发送音频

但当来电时,我需要断开与SCO的连接,以便应用程序音频不会干扰呼叫

问题是,当我尝试在通话后将音频重新路由到SCO时,它不起作用

以下是我用来向SCO发送音频的代码:

public class BluetoothManager {
// For Bluetooth connectvity
private static String TAG = "BluetoothManager";
private static BluetoothAdapter mBluetoothAdapter =    BluetoothAdapter.getDefaultAdapter();
private static AudioManager aM;

/**
 * Set the audio manager of the device.
 * @param c: The context this method is called from
 */
public static void setAudioManager(Context c) {
    aM = (android.media.AudioManager)c.getSystemService(Context.AUDIO_SERVICE);
}

/**
 * Check if a Bluetooth headset is connected. If so, route audio to Bluetooth SCO.
 */
private static void initializeAudioMode(Context context) {
    BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (profile == BluetoothProfile.HEADSET) {
                BluetoothHeadset bh = (BluetoothHeadset) proxy;
                List<BluetoothDevice> devices = bh.getConnectedDevices();
                if (devices.size() > 0) {
                    enableBluetoothSCO();
                }
            }
            mBluetoothAdapter.closeProfileProxy(profile, proxy);
        }
        public void onServiceDisconnected(int profile) {}
    };
    mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
}

/**
 * Bluetooth Connectvity
 *   The following methods are associated with enabling/disabling Bluetooth.
 *   In the future we may want to disable other sources of audio.
 */
private static void enableBluetoothSCO() {
    aM.setMode(AudioManager.MODE_IN_CALL);
    aM.startBluetoothSco();
    aM.setBluetoothScoOn(true);
}

/** Right now, this simply enables Bluetooth */
@SuppressLint("NewApi")
public static boolean enableBluetooth(Context c) {
    // If there is an adapter, enable it if not already enabled
    if (mBluetoothAdapter != null) {

        if (!mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.enable(); 
        }

        setAudioManager(c);
        initializeAudioMode(c);
        Log.e(TAG, "SCO: " + aM.isBluetoothScoOn());
        Log.e(TAG, "A2DP: " + aM.isSpeakerphoneOn());
        return true;
    } else {
        Log.v(TAG, "There is no bluetooth adapter");
        return false;
    }
}

/** Right now, this simply disables Bluetooth */
public static void disableBluetooth() {
    // If there is an adapter, disabled it if not already disabled
    if (mBluetoothAdapter != null) {
        if (mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.disable(); 
        }
    } else {
        Log.v(TAG, "There is no bluetooth adapter");
    }
}

public static void restartBluetooth(){
    aM.setMode(AudioManager.MODE_IN_CALL);

}
public static void stopBluetooth(){
    aM.setMode(AudioManager.MODE_NORMAL);

}

}
公共类BluetoothManager{
//蓝牙连接
私有静态字符串TAG=“BluetoothManager”;
私有静态BluetoothAdapter mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
专用静态音频管理器aM;
/**
*设置设备的音频管理器。
*@param c:调用此方法的上下文
*/
公共静态void setAudioManager(上下文c){
aM=(android.media.AudioManager)c.getSystemService(Context.AUDIO\u服务);
}
/**
*检查蓝牙耳机是否已连接。如果已连接,请将音频路由到蓝牙SCO。
*/
私有静态void initializeAudioMode(上下文){
BluetoothProfile.ServiceListener mProfileListener=新的BluetoothProfile.ServiceListener(){
服务连接上的公共void(int配置文件、Bluetooth配置文件代理){
if(情景模式==蓝牙情景模式.耳机){
蓝牙耳机bh=(蓝牙耳机)代理;
List devices=bh.getConnectedDevices();
如果(devices.size()>0){
enableBluetoothSCO();
}
}
mBluetoothAdapter.closeProfileProxy(profile,proxy);
}
服务断开连接(int配置文件){}
};
getProfileProxy(上下文、mProfileListener、蓝牙模式、耳机);
}
/**
*蓝牙连接
*以下方法与启用/禁用蓝牙相关。
*将来,我们可能希望禁用其他音频源。
*/
私有静态void启用bluetoothsco(){
aM.setMode(AudioManager.MODE在通话中);
aM.startBluetoothSco();
aM.setBluetoothScoOn(真);
}
/**现在,这只是启用蓝牙*/
@SuppressLint(“新API”)
公共静态布尔启用蓝牙(上下文c){
//如果有适配器,请启用它(如果尚未启用)
if(mBluetoothAdapter!=null){
如果(!mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.enable();
}
音乐经理(c);
初始化模式(c);
Log.e(标记“SCO:+aM.isBluetoothScoOn());
Log.e(标记为“A2DP:+aM.isSpeakerphoneOn());
返回true;
}否则{
Log.v(标记“没有蓝牙适配器”);
返回false;
}
}
/**现在,这只是禁用蓝牙*/
公共静态无效禁用蓝牙(){
//如果有适配器,则禁用它(如果尚未禁用)
if(mBluetoothAdapter!=null){
if(mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.disable();
}
}否则{
Log.v(标记“没有蓝牙适配器”);
}
}
公共静态void restartbooth(){
aM.setMode(AudioManager.MODE在通话中);
}
公共静态void stopBluetooth(){
aM.setMode(AudioManager.MODE_正常);
}
}
当我正确调用
stopBluetooth()
时,应用程序的音频不再发送到耳机


但是,当我呼叫
restartbooth()
时,音频不是从耳机播放的,而是从手机扬声器播放的。

通话结束后,SCO链路是否可能中断?如果是这种情况,则SCO链路也必须与音频路由一起启动


您是否尝试在restartBluetooth()中调用enableBluetoothSCO()

您可能需要调用:

aM.startBluetoothSco();
aM.setBluetoothScoOn(真)


设置模式后。

在重新启动功能中,再次初始化所有内容,并查看其是否工作。像这样:

public static void restartBluetooth(){
    enableBluetooth(getApplicationContext());
}
如果这样做有效,则意味着当通话结束时,由于某种原因,最后一次初始化将丢失。

“电话应用程序始终优先使用SCO连接进行电话。如果在通话中调用此方法,则会忽略此方法。类似地,如果在应用程序使用SCO连接时接收或发送呼叫,则应用程序的连接将丢失,并且在呼叫结束时不会自动返回。”


因此,当通话中断时,您必须通过呼叫startBluetoothSco()

重新建立连接。对于仍有此问题的任何人,需要做一些事情。您需要做的第一件事是跟踪电话状态。您可以在此处看到如何做到这一点:

当状态为空闲时,表示传入呼叫已结束。现在,如果此时尝试重新连接蓝牙,您会发现它仍然无法工作,因为呼叫需要一段时间(大约2秒)才能“释放”蓝牙设备。 因此,您有两个选择,请稍等,然后尝试重新连接,或者您可以向BluetoothHeadset添加另一个侦听器。操作\音频\状态\已更改

然后,您可以添加一个全局布尔值isIdle,当TelephonyManager.CALL\u STATE\u空闲时为true,当TelephonyManager.CALL\u STATE\u挂起时为false(否则,您将在传入呼叫期间重新连接蓝牙)。此时,当BluetoothHeadset.STATE_断开连接且isIdle为真时,请重新连接蓝牙

@Override public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals((BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED))){
        int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
        switch(state) {
            case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
                if (isIdle){
                    //reconnect bluetooth 
                }
                break;
        }
    }
    if(("OFFHOOK").equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
        isIdle = false;
        // turn bluetooth off
    }
    if(("IDLE").equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
        isIdle = true;
    }
}

我还试图通过蓝牙将音频发送到spcific应用程序,但无法到达该应用程序。这是我的查询