Merge pull request #43 from TouchInstinct/bluetooth_headset
observe bluetooth headset state
This commit is contained in:
commit
90fa6dca63
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package ru.touchin.roboswag.components.utils.audio;
|
||||
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
|
@ -27,67 +28,93 @@ import android.media.AudioManager;
|
|||
import android.support.annotation.NonNull;
|
||||
|
||||
import rx.Observable;
|
||||
import rx.subjects.PublishSubject;
|
||||
import rx.subjects.BehaviorSubject;
|
||||
|
||||
/**
|
||||
* Created by Gavriil Sitnikov on 02/11/2015.
|
||||
* Simple observer of wired headset state (plugged in or not).
|
||||
* Simple observer of wired or wireless (bluetooth A2DP) headsets state (connected or not).
|
||||
* <br><font color="yellow"> You require android.permission.BLUETOOTH and API level >= 11 if want to observe wireless headset state </font>
|
||||
*/
|
||||
public final class HeadsetStateObserver {
|
||||
|
||||
@NonNull
|
||||
private final AudioManager audioManager;
|
||||
@NonNull
|
||||
private final Observable<Boolean> isPluggedInObservable;
|
||||
private final Observable<Boolean> isConnectedObservable;
|
||||
|
||||
public HeadsetStateObserver(@NonNull final Context context) {
|
||||
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
isPluggedInObservable = Observable
|
||||
.<IsPluggedInReceiver>create(subscriber -> {
|
||||
subscriber.onNext(new IsPluggedInReceiver());
|
||||
isConnectedObservable = Observable
|
||||
.<IsConnectedReceiver>create(subscriber -> {
|
||||
subscriber.onNext(new IsConnectedReceiver(audioManager));
|
||||
subscriber.onCompleted();
|
||||
})
|
||||
.switchMap(isPluggedInReceiver -> Observable
|
||||
.just(isPluggedIn())
|
||||
.concatWith(isPluggedInReceiver.isPluggedInChangedEvent
|
||||
.doOnSubscribe(() -> context.registerReceiver(isPluggedInReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)))
|
||||
.doOnUnsubscribe(() -> context.unregisterReceiver(isPluggedInReceiver))))
|
||||
.switchMap(isConnectedReceiver -> Observable.combineLatest(isConnectedReceiver.isWiredConnectedChangedEvent,
|
||||
isConnectedReceiver.isWirelessConnectedChangedEvent,
|
||||
(isWiredConnected, isWirelessConnected) -> isWiredConnected || isWirelessConnected)
|
||||
.distinctUntilChanged()
|
||||
.doOnSubscribe(() -> {
|
||||
final IntentFilter headsetStateIntentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
|
||||
headsetStateIntentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
|
||||
}
|
||||
context.registerReceiver(isConnectedReceiver, headsetStateIntentFilter);
|
||||
})
|
||||
.doOnUnsubscribe(() -> context.unregisterReceiver(isConnectedReceiver)))
|
||||
.replay(1)
|
||||
.refCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if wired headset plugged in.
|
||||
* Returns if wired or wireless headset is connected.
|
||||
*
|
||||
* @return True if headset is plugged in.
|
||||
* @return True if headset is connected.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean isPluggedIn() {
|
||||
return audioManager.isWiredHeadsetOn();
|
||||
public boolean isConnected() {
|
||||
return audioManager.isWiredHeadsetOn() || audioManager.isBluetoothA2dpOn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Observes plugged in state of wired headset.
|
||||
* Observes connection state of headset.
|
||||
*
|
||||
* @return Returns observable which will provide current plugged in state and any of it's udpdate.
|
||||
* @return Returns observable which will provide current connection state and any of it's udpdate.
|
||||
*/
|
||||
@NonNull
|
||||
public Observable<Boolean> observeIsPluggedIn() {
|
||||
return isPluggedInObservable;
|
||||
public Observable<Boolean> observeIsConnected() {
|
||||
return isConnectedObservable;
|
||||
}
|
||||
|
||||
private static class IsPluggedInReceiver extends BroadcastReceiver {
|
||||
private static class IsConnectedReceiver extends BroadcastReceiver {
|
||||
|
||||
@NonNull
|
||||
private final PublishSubject<Boolean> isPluggedInChangedEvent = PublishSubject.create();
|
||||
private final BehaviorSubject<Boolean> isWiredConnectedChangedEvent;
|
||||
@NonNull
|
||||
private final BehaviorSubject<Boolean> isWirelessConnectedChangedEvent;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public IsConnectedReceiver(@NonNull final AudioManager audioManager) {
|
||||
isWiredConnectedChangedEvent = BehaviorSubject.create(audioManager.isWiredHeadsetOn());
|
||||
isWirelessConnectedChangedEvent = BehaviorSubject.create(audioManager.isBluetoothA2dpOn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())) {
|
||||
if (intent.getExtras() == null) {
|
||||
isPluggedInChangedEvent.onNext(false);
|
||||
} else {
|
||||
isPluggedInChangedEvent.onNext(intent.getExtras().getInt("state") != 0);
|
||||
if (Intent.ACTION_HEADSET_PLUG.equals(intent.getAction()) && !isInitialStickyBroadcast()) {
|
||||
isWiredConnectedChangedEvent.onNext(intent.getIntExtra("state", 0) != 0);
|
||||
}
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB &&
|
||||
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
|
||||
final int bluetoothState = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_DISCONNECTED);
|
||||
switch (bluetoothState) {
|
||||
case BluetoothA2dp.STATE_DISCONNECTED:
|
||||
isWirelessConnectedChangedEvent.onNext(false);
|
||||
break;
|
||||
case BluetoothA2dp.STATE_CONNECTED:
|
||||
isWirelessConnectedChangedEvent.onNext(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue