1

Text-To-Speech を使用してアプリケーションを設計していますが、動作します。ここで、Bluetooth ヘッドセット (AD2P ではない) を使用して音声を受信したいと考えています。startBluetoothScoOn に関する Android ドキュメントを読むと、次のようになります。

電話アプリケーションは、電話で SCO 接続を使用する際に常に優先されることに注意してください。電話が通話中にこのメソッドが呼び出された場合、それは無視されます。同様に、アプリケーションが SCO 接続を使用しているときにコールが送受信された場合、アプリケーションの接続は失われ、コールが終了しても自動的に返されません。

今私の質問は次のとおりです。

  1. 通話が終了したときに startBluetoothScoOn を再呼び出しするには、電話の状態をリッスンする必要がありますか? はいの場合、どのように?例は見つかりませんでした。
  2. ヘッドセットの接続/切断をリッスンする必要がありますか? はいの場合、どのように?

通話が終了するか、ヘッドセットがオフになると、システムは 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);
    }
}
4

1 に答える 1