package com.cantrowitz.rxbroadcast; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.support.v4.content.LocalBroadcastManager; import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import io.reactivex.ObservableOnSubscribe; import io.reactivex.functions.Cancellable; /** * Created by adamcantrowitz on 9/1/15. */ public class RxBroadcast { private static final OrderedBroadcastAbortStrategy NO_OP_ORDERED_BROADCAST_STRATEGY = new OrderedBroadcastAbortStrategy() { @Override public void handleOrderedBroadcast(Context context, Intent intent, BroadcastReceiverAbortProxy abortProxy) { //no-op } }; private RxBroadcast() { throw new AssertionError("No instances"); } /** * Create {@link Observable} that wraps {@link BroadcastReceiver} and emits received intents. * * @param context the context the {@link BroadcastReceiver} will be created from * @param intentFilter the filter for the particular intent * @return {@link Observable} of {@link Intent} that matches the filter */ public static Observable<Intent> fromBroadcast(Context context, IntentFilter intentFilter) { return fromBroadcast(context, intentFilter, NO_OP_ORDERED_BROADCAST_STRATEGY); } /** * Create {@link Observable} that wraps {@link BroadcastReceiver} and emits received intents. * <p> * <em>This is only useful in conjunction with Ordered Broadcasts, e.g., * {@link Context#sendOrderedBroadcast(Intent, String)}</em> * * @param context the context the {@link BroadcastReceiver} will be * created from * @param intentFilter the filter for the particular intent * @param orderedBroadcastAbortStrategy the strategy to use for Ordered Broadcasts * @return {@link Observable} of {@link Intent} that matches the filter */ public static Observable<Intent> fromBroadcast( Context context, IntentFilter intentFilter, OrderedBroadcastAbortStrategy orderedBroadcastAbortStrategy) { BroadcastRegistrar broadcastRegistrar = new BroadcastRegistrar(context, intentFilter); return createBroadcastObservable(broadcastRegistrar, orderedBroadcastAbortStrategy); } /** * Create {@link Observable} that wraps {@link BroadcastReceiver} and emits received intents. * * @param context the context the {@link BroadcastReceiver} will be created from * @param intentFilter the filter for the particular intent * @param broadcastPermission String naming a permissions that a broadcaster must hold in * order to send an Intent to you. If null, no permission is * required. * @param handler Handler identifying the thread that will receive the Intent. If * null, the main thread of the process will be used. * @return {@link Observable} of {@link Intent} that matches the filter */ public static Observable<Intent> fromBroadcast( Context context, IntentFilter intentFilter, String broadcastPermission, Handler handler) { return fromBroadcast( context, intentFilter, broadcastPermission, handler, NO_OP_ORDERED_BROADCAST_STRATEGY ); } /** * Create {@link Observable} that wraps {@link BroadcastReceiver} and emits received intents. * <p> * <em>This is only useful in conjunction with Ordered Broadcasts, e.g., * {@link Context#sendOrderedBroadcast(Intent, String)}</em> * * @param context the context the {@link BroadcastReceiver} will be created * from * @param intentFilter the filter for the particular intent * @param broadcastPermission String naming a permissions that a broadcaster must hold * in order to send an Intent to you. If null, no permission * is required. * @param handler Handler identifying the thread that will receive the * Intent. If null, the main thread of the process will be used. * @param orderedBroadcastAbortStrategy the strategy to use for Ordered Broadcasts * @return {@link Observable} of {@link Intent} that matches the filter */ public static Observable<Intent> fromBroadcast( Context context, IntentFilter intentFilter, String broadcastPermission, Handler handler, OrderedBroadcastAbortStrategy orderedBroadcastAbortStrategy) { BroadcastWithPermissionsRegistrar broadcastWithPermissionsRegistrar = new BroadcastWithPermissionsRegistrar( context, intentFilter, broadcastPermission, handler); return createBroadcastObservable( broadcastWithPermissionsRegistrar, orderedBroadcastAbortStrategy); } /** * Create {@link Observable} that wraps {@link BroadcastReceiver} and emits received intents. * <p> * This uses a {@link LocalBroadcastManager} * * @param context the context the {@link BroadcastReceiver} will be created from * @param intentFilter the filter for the particular intent * @return {@link Observable} of {@link Intent} that matches the filter */ public static Observable<Intent> fromLocalBroadcast( Context context, IntentFilter intentFilter) { LocalBroadcastRegistrar localBroadcastRegistrar = new LocalBroadcastRegistrar( intentFilter, LocalBroadcastManager.getInstance(context)); return createBroadcastObservable(localBroadcastRegistrar, NO_OP_ORDERED_BROADCAST_STRATEGY); } private static Observable<Intent> createBroadcastObservable( final BroadcastRegistrarStrategy broadcastRegistrarStrategy, final OrderedBroadcastAbortStrategy orderedBroadcastAbortStrategy) { return Observable.create(new ObservableOnSubscribe<Intent>() { @Override public void subscribe(final ObservableEmitter<Intent> intentEmitter) throws Exception { final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { intentEmitter.onNext(intent); if (isOrderedBroadcast()) { orderedBroadcastAbortStrategy.handleOrderedBroadcast( context, intent, BroadcastReceiverAbortProxy.create(this)); } } }; intentEmitter.setCancellable(new Cancellable() { @Override public void cancel() throws Exception { broadcastRegistrarStrategy.unregisterBroadcastReceiver(broadcastReceiver); } }); broadcastRegistrarStrategy.registerBroadcastReceiver(broadcastReceiver); } }); } }