/* * Copyright 2015 Jacek Marchwicki <jacek.marchwicki@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.appunite.rx.android; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.telephony.TelephonyManager; import com.appunite.rx.ObservableExtensions; import com.appunite.rx.observables.NetworkObservableProvider; import javax.annotation.Nonnull; import rx.Observable; import rx.Subscriber; import rx.functions.Action1; import rx.observers.Subscribers; import static com.appunite.rx.internal.Preconditions.checkNotNull; public class NetworkObservableProviderImpl implements NetworkObservableProvider { @Nonnull private final ConnectivityManager connectivityManager; private final Observable<NetworkStatus> networkStatusObservable; public NetworkObservableProviderImpl(@Nonnull final Context context) { checkNotNull(context); connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); final IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); networkStatusObservable = Observable .create(new Observable.OnSubscribe<NetworkStatus>() { @Override public void call(final Subscriber<? super NetworkStatus> subscriber) { subscriber.onNext(getActiveNetworkStatus()); final BroadcastReceiver receiver = new NetworkBroadcastReceiver(subscriber); context.registerReceiver(receiver, filter); subscriber.add(Subscribers.create(new Action1<Object>() { @Override public void call(final Object o) { context.unregisterReceiver(receiver); } })); } }) .distinctUntilChanged() .replay(1).refCount(); } private NetworkStatus getActiveNetworkStatus() { final NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); if (activeNetworkInfo == null) { return NetworkStatus.NO_NETWORK; } if (!activeNetworkInfo.isConnected()) { return NetworkStatus.NO_NETWORK; } final int type = activeNetworkInfo.getType(); final int subtype = activeNetworkInfo.getSubtype(); if (type == ConnectivityManager.TYPE_WIFI) { return NetworkStatus.BEST; } else if (type == ConnectivityManager.TYPE_MOBILE) { switch (subtype) { case TelephonyManager.NETWORK_TYPE_1xRTT: return NetworkStatus.WEAK; // ~ 50-100 kbps case TelephonyManager.NETWORK_TYPE_CDMA: return NetworkStatus.WEAK; // ~ 14-64 kbps case TelephonyManager.NETWORK_TYPE_EDGE: return NetworkStatus.WEAK; // ~ 50-100 kbps case TelephonyManager.NETWORK_TYPE_EVDO_0: return NetworkStatus.WEAK; // ~ 400-1000 kbps case TelephonyManager.NETWORK_TYPE_EVDO_A: return NetworkStatus.WEAK; // ~ 600-1400 kbps case TelephonyManager.NETWORK_TYPE_GPRS: return NetworkStatus.WEAK; // ~ 100 kbps case TelephonyManager.NETWORK_TYPE_HSDPA: return NetworkStatus.BEST; // ~ 2-14 Mbps case TelephonyManager.NETWORK_TYPE_HSPA: return NetworkStatus.GOOD; // ~ 700-1700 kbps case TelephonyManager.NETWORK_TYPE_HSUPA: return NetworkStatus.BEST; // ~ 1-23 Mbps case TelephonyManager.NETWORK_TYPE_UMTS: return NetworkStatus.GOOD; // ~ 400-7000 kbps /* * Above API level 7 */ case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11 return NetworkStatus.GOOD; // ~ 1-2 Mbps case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9 return NetworkStatus.BEST; // ~ 5 Mbps case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13 return NetworkStatus.BEST; // ~ 10-20 Mbps case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8 return NetworkStatus.BEST; // ~25 kbps case TelephonyManager.NETWORK_TYPE_LTE: // API level 11 return NetworkStatus.BEST; // ~ 10+ Mbps // Unknown case TelephonyManager.NETWORK_TYPE_UNKNOWN: default: return NetworkStatus.GOOD; } } else if (type == ConnectivityManager.TYPE_WIMAX) { return NetworkStatus.BEST; } else if (type == ConnectivityManager.TYPE_ETHERNET) { return NetworkStatus.BEST; } else { return NetworkStatus.GOOD; } } @Nonnull @Override public Observable<NetworkStatus> networkObservable() { return networkStatusObservable; } private class NetworkBroadcastReceiver extends BroadcastReceiver { private final Subscriber<? super NetworkStatus> subscriber; public NetworkBroadcastReceiver(final Subscriber<? super NetworkStatus> subscriber) { this.subscriber = subscriber; } @Override public void onReceive(final Context context, final Intent intent) { subscriber.onNext(getActiveNetworkStatus()); } } }