AudioManager : 안드로이드 여전히 오디오 스피커를 재생하는 헤드폰에 연결하는 데 사용됩니다

모바일 오디오 출력 (스피커), 휴대폰 (전화 수신기)가 태우고, 유선 헤드셋 (WiredHeadset), 블루투스 스피커 (블루투스 A2DP) 및 기타 출력 장치. 평상시에, 핸즈프리 전화, 헤드셋 플러그, 운영 시스템과 같은 블루투스 장치를 분리 자동으로 해당 오디오 오디오 출력 장치로 전환됩니다. 핸즈프리 전화기 헤드셋이 헤드셋으로 시끄러운 스피커에서 전환 삽입, 시끄러운 스피커 휴대폰에서 전환하는 것 등.

장면 수요

이러한 전략 안드로이드 시스템이 자동으로 전환하고 당황에 우위를 점할에 갑자기 스위치를 방지하기 위해 음악 작업 중지 (일시 중지 재생)을들을 때 헤드폰을 분리하는 음악 앱의 필요성 우리의 제품에 대한 모든 수요를 충족시킬 수 없다.

최근 프로젝트는 희망이 필요합니다 即使在连接蓝牙音箱的情况下,仍旧使用手机外放播放音频. 이것은 원래의 전략 시스템을 침입, 오디오 출력 채널을 전환하도록 강요 필요합니다.

정보에 대한 액세스, 안드로이드에서 볼 수 AudioManager, 쿼리 현재 채널 오디오 출력을 전환 할 때, 그리고 오디오 출력은 변경 캐치하고이 변경 사항을 처리한다.

먼저 다음과 같은 방법을 사용하는 경우, 당신이 권한을 추가 할 필요가 있음을 알려 :

< 사용-권한 안드로이드 : 이름 = "android.permission.MODIFY_AUDIO_SETTINGS을"  />

오디오 출력 상태 쿼리

AudioManager 다음 방법은 현재 상태 질의 오디오 출력을 제공 할 수있다 :

  • isBluetoothA2dpOn(): 체크 블루투스 헤드셋을 통해 A2DPAudio 오디오 출력 여부;

  • isSpeakerphoneOn(): 스피커가 켜져 있는지 확인하십시오;

  • isWiredHeadsetOn(): 헤드폰 와이어 결합 여부를 확인,이 방법에만 이어폰 상태가 삽입되어 있는지 여부를 결정하는 데 사용하는 것으로, 또한 다른 조건들에 의존하는 이어폰을 통해 현재 음성 출력을 결정하는 결과를 사용하지 않는다.

  • setSpeakerphoneOn(boolean on): 직접 선택 시끄러운 스피커 소리;

  • setBluetoothScoOn(boolean on): SCO는 통신 할 수있는 블루투스 헤드셋의 사용을 필요로;

다음은 문서에 따르면 간단하게 링크 두 종류의 블루투스 헤드셋, A2DP와 SCO를 소개합니다. 안드로이드 API 쇼 :

  • A2DP : 고품질 오디오 링크의 단방향 데이터 전송, 일반적으로 스테레오 음악 재생을위한;
  • SCO는 : 그것은 양방향 오디오 데이터 전송 링크입니다 링크는 8K를 지원하고 16K는 단지 음악을 재생하는 데 사용할 수있는 경우 오디오 데이터는 오, 일반 음성의 전송을 위해 사용할 수있는 모노 .

, A2DP는 재생 기본적으로, 그리고 SCO는 모두 녹음을 재생할 수 있습니다, 기본적으로 꺼져 : 둘 사이의 가장 큰 차이점이다. 당신은 문제가 확실히 열린 SCO 될 것입니다 녹음하려면, 그래서 위의 전화  setBluetoothScoOn (에 부울)  , 블루투스 헤드셋 녹음, 오디오 재생, 완성 된 녹음을 통해 완성 된 연주를 해제하는 것을 잊지 수 있습니다.

또한, 안드로이드 시스템에 의해 AudioManager.setMode()재생 모드 방법을 관리. 에서 setMode()다양한 재생 모드는 다음과 같은 방법에 해당합니다 :

  • MODE_NORMAL : 일반 모드, 어느 벨소리 나 통화 모드
  • MODE_RINGTONE : 링 패턴
  • MODE_IN_CALL : 토크 모드
  • MODE_IN_COMMUNICATION : 모드 오디오 / 비디오, VoIP 통화 (3.0 추가 된 통화 모드와 같은)를 포함한 통신,의.

재생 모드를 설정할 때, 당신은 내가 사용하고 여기에 입력 흐름, 흐름의 유형을 고려할 필요  STREAM_MUSIC 는 재생 장치로 설정되어 전환해야 그렇게 할 때, MODE_IN_COMMUNICATION 모드 대신  MODE_NORMAL 모드. 당신은 참조 할 수 있습니다 이 문제 .

문제 해결

참조하여, 오디오 오디오 출력을 전환하는 방법에 따라 안드로이드 오디오 그리고 모순 BETWEEN 블루투스 전화 스피커 스위칭 IS :

= AudioManager AudioManager (AudioManager) context.getSystemService (Context.AUDIO_SERVICE);
 / ** 
* 큰 소리로 전환 
* / 
공공  무효 changeToSpeaker () {
  // 참고 여기에, 대신 MODE_IN_COMMUNICATION MODE_NORMAL 블루투스를 사용하여 연결이 해제되지 않습니다 
  mAudioManager.setMode (bluetoothIsConnected? ; AudioManager.MODE_IN_COMMUNICATION AudioManager.MODE_NORMAL) 
  mAudioManager.stopBluetoothSco (); 
  mAudioManager.setBluetoothScoOn ( 거짓 ) 
  mAudioManager.setSpeakerphoneOn ( true로 ); 
} 
/ ** 
블루투스 스피커 * 스위치 
* / 
공공  무효 changeToHeadset () {
  mAudioManager.setMode (AudioManager.MODE_IN_COMMUNICATION) 
  mAudioManager.startBluetoothSco (); 
  mAudioManager.setBluetoothScoOn ( true로 ) 
  mAudioManager.setSpeakerphoneOn ( false로 ); 
} 
/ ** ******************************************************** **************************************** * / 
// 참고 : 다음과 같은 두 가지 방법 아직 검증 
/ ** **************************** ************* * / 
/ ** 
* 헤드셋 모드로 전환 
* / 
공용  공극 changeToHeadset () { 
  mAudioManager.setMode (AudioManager.MODE_IN_COMMUNICATION) 
  mAudioManager.stopBluetoothSco (); 
  mAudioManager.setBluetoothScoOn ( 그릇된 ) 
  mAudioManager.setSpeakerphoneOn ( 거짓 ); 
} 
/ ** 
*切换到听筒
* / 
공용  공극 changeToReceiver () { 
  audioManager.setSpeakerphoneOn ( 거짓 );
  경우 (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) { 
    audioManager.setMode (AudioManager.MODE_IN_COMMUNICATION); 
  } 다른 { 
    audioManager.setMode (AudioManager.MODE_IN_CALL); 
  } 
}

직접 방법은 우리가 이미 알고있는 출력 채널을 전환합니다. 해결해야 할 나머지 문제는 블루투스 기기가 연결되었을 때, 연결, 우리는 그 블루투스가 연결되어 있지 않을 때와 같이, 사용자에게 원래 세트의 출력 채널을 전환 자동 수 희망이며이되어야하므로, 사용자에 의해 설정은, 블루투스를 통해 방송이고 블루투스 연결이 일단 후, 음성 절환은 블루투스 장치에 넣어.

여기에서 우리는 블루투스 장치의 연결 상태를 모니터링하는 방법에 봐.

첫째, 이전의 사용은 다음과 같은 권한이 필요합니다주의 :

< 사용-권한 : 안드로이드 이름 = "android.permission.BLUETOOTH_ADMIN은"  /> 
< 사용-권한 : 이름 안드로이드 = "android.permission.BLUETOOTH을"  />

에 따르면 기사 , 우리는 당신이 사용할 수 있다는 것을 발견  AudioManager.ACTION_AUDIO_BECOMING_NOISY , 의도 액션 블루투스를 듣고 헤드셋 무선 연결이,하지만 테스트가되지 않도록 그것은 단지, 블루투스 연결로 방송을 수신 할 수 Bluetooth 무선을받을 수 있다는 것을 발견 우리는 할 수 있습니다.

또한이 문서를 발견 : 블루투스 개발에 대해서는, 방송에주의를 지불해야합니다 다음은 블루투스 라디오를 요약 한 것입니다.

/ ** 
* 주석 무선 블루투스 연결을 사용한다 
* / 
intentFilter.addAction (BluetoothDevice.ACTION_FOUND) // 블루 전압 장치를 검색하는 검색 장치는 각 방송 송신 
intentFilter.addAction (BluetoothDevice.ACTION_BOND_STATE_CHANGED)를; // 페어링이 성공적으로 시작, 페어링 할 때 
intentFilter.addAction (BluetoothDevice.ACTION_ACL_CONNECTED이); // 페어링을 연결 시작 
, intentFilter.addAction (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) 
intentFilter.addAction (BluetoothDevice.ACTION_ACL_DISCONNECTED를); // 페어 것은 오프 종료 오픈 연결 
intentFilter.addAction (PAIRING_REQUEST) // 페어링 요구 (Android.bluetooth.device.action.PAIRING_REQUEST) 
intentFilter.addAction (BluetoothAdapter.ACTION_DISCOVERY_STARTED) //검색 시작 
intentFilter.addAction (BluetoothAdapter.ACTION_DISCOVERY_FINISHED); // 검색 종료됩니다. 재 검색하면 검색하기 전에 종료한다 
; intentFilter.addAction (BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE) 
intentFilter.addAction (BluetoothAdapter.ACTION_STATE_CHANGED) // 기기가 블루투스 오프 스위치를 온 
intentFilter.addAction (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED) // 블루투스 장치 또는 분리 
intentFilter.addAction (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED); // 당신은 블루투스 이름을 변경하려면 블루투스를 열 호출 할 수 있습니다 여러 번 
intentFilter.addAction (BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE) 
intentFilter.addAction (BluetoothAdapter.ACTION_REQUEST_ENABLE) 
intentFilter.addAction (BluetoothAdapter. ACTION_SCAN_MODE_CHANGED); //검색 모드 변경

우리는 발견 BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED 하고  BluetoothAdapter.ACTION_STATE_CHANGED 이 개 의도 방송.

그래서이 두 방송 의도가있다 차이점은 무엇입니까? 하나만 할 수 있습니까? 보기 Google 문서 발견

  • BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED : 로컬 블루투스 어댑터의 접속 상태의 변화를 의미 (예컨대 기계없이 블루투스 오프 스위치로, 다른 한 쌍의 디바이스는 자신이 해제)

  • BluetoothAdapter.ACTION_STATE_CHANGED : 로컬 블루투스 어댑터의 상태로 참조가 변경되었습니다. 예를 들어, 또는 해제 블루투스 스위치.

즉, 변화가 접속 상태, 다른 블루투스 어댑터 자체의 상태 변화에 대한 것이다. 테스트가 발견 한 경우에만, BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED 보다 적은 방송을 듣고 "기기의 전원을 켭니다 활성 블루투스 스위치,"이벤트는 방송 수신 될 것입니다. 그러나 단지와 BluetoothAdapter.ACTION_STATE_CHANGED 단어, 정말 블루투스 장치를 연결되어 있지 그 시간이 분명하다.

동적 등록 블루투스 연결, 분리 방송은 다음과 같다 :

  • 동적 등록 방송
공용  클래스 BluetoothConnectionReceiver (가) 확장 브로드 캐스트 리시버를 { 
  @Override 
  공개  공극 onReceive (컨텍스트 컨텍스트 텐트 텐트) {
    IF (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals (intent.getAction ())) { // 블루투스 접속 상태 
      INT 상태 = intent.getIntExtra (BluetoothAdapter.EXTRA_CONNECTION_STATE , -1 );
      IF (주 주 == == BluetoothAdapter.STATE_CONNECTED || BluetoothAdapter.STATE_DISCONNECTED) {
        // 연결 또는 손실 접촉, 시끄러운 스피커를 강제로 여전히 오디오 출력 (블루투스, 또는 스위치) 
      } 
    } 다른  IF(BluetoothAdapter.ACTION_STATE_CHANGED.equals은 (는 intent.getAction ())) { // 로컬 블루투스 개방 또는 폐쇄 
      INT 상태 = intent.getIntExtra (BluetoothAdapter.EXTRA_STATE, -1 ),
      IF (주 스테이트 == == BluetoothAdapter.STATE_OFF || BluetoothAdapter.STATE_TURNING_OFF) {
      // OFF가 음성 출력을 전환 
      } 
    } 
  } 
}
BluetoothConnectionReceiver audioNoisyReceiver는 = 새로운 BluetoothConnectionReceiver을 ();
// 蓝牙状态广播监听 
로 IntentFilter audioFilter = 신규 로 IntentFilter (); 
audioFilter.addAction (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); 
audioFilter.addAction (BluetoothAdapter.ACTION_STATE_CHANGED); 
mContext.registerReceiver (audioNoisyReceiver, audioFilter);

그 후, 우리는 블루투스 장치를 달성하기 위해 상기 코드에 따라서 상기 음성 출력 채널을 전환 할 수 연결된 후에 자체 찾는의 전환 기능을 달성하기 위해 원래 운영체제 출력 채널 스위칭 전략을 끊는 것을 강요.

이것은 전환 : 오디오 출력 오디오 채널 스위칭 - 블루투스, 퍼팅

 

추천

출처www.cnblogs.com/yongdaimi/p/11898816.html