1823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang/* 2823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * Copyright (C) 2006 The Android Open Source Project 3823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * 4823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * you may not use this file except in compliance with the License. 6823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * You may obtain a copy of the License at 7823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * 8823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * http://www.apache.org/licenses/LICENSE-2.0 9823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * 10823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * Unless required by applicable law or agreed to in writing, software 11823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * distributed under the License is distributed on an "AS IS" BASIS, 12823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * See the License for the specific language governing permissions and 14823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * limitations under the License. 15823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 16823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 17823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangpackage com.android.common; 18823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 19823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.content.BroadcastReceiver; 20823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.content.Context; 21823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.content.Intent; 22823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.content.IntentFilter; 23823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.net.ConnectivityManager; 24823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.net.NetworkInfo; 25823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.os.Handler; 26823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.os.Message; 27823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport android.util.Log; 28823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 29823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport java.util.HashMap; 30823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangimport java.util.Iterator; 31823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 32823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang/** 33823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * A wrapper for a broadcast receiver that provides network connectivity 34823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * state information, independent of network type (mobile, Wi-Fi, etc.). 35823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @deprecated Code tempted to use this class should simply listen for connectivity intents 36823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * (or poll ConnectivityManager) directly. 37823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * {@hide} 38823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 39194dda102240aeeaa30c28f4eda3e1d3ccdb6b03Scott Kennedy@Deprecated 40823b6f3516076b92f78c3fc27037d24bb514e653Ying Wangpublic class NetworkConnectivityListener { 41823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private static final String TAG = "NetworkConnectivityListener"; 42823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private static final boolean DBG = false; 43823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 44823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private Context mContext; 45823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private HashMap<Handler, Integer> mHandlers = new HashMap<Handler, Integer>(); 46823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private State mState; 47823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private boolean mListening; 48823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private String mReason; 49823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private boolean mIsFailover; 50823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 51823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** Network connectivity information */ 52823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private NetworkInfo mNetworkInfo; 53823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 54823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 55823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * In case of a Disconnect, the connectivity manager may have 56823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * already established, or may be attempting to establish, connectivity 57823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * with another network. If so, {@code mOtherNetworkInfo} will be non-null. 58823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 59823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private NetworkInfo mOtherNetworkInfo; 60823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 61823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private ConnectivityBroadcastReceiver mReceiver; 62823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 63823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang private class ConnectivityBroadcastReceiver extends BroadcastReceiver { 64823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang @Override 65823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public void onReceive(Context context, Intent intent) { 66823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang String action = intent.getAction(); 67823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 68823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || 69823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mListening == false) { 70823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang Log.w(TAG, "onReceived() called with " + mState.toString() + " and " + intent); 71823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang return; 72823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 73823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 74823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang boolean noConnectivity = 75823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 76823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 77823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang if (noConnectivity) { 78823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mState = State.NOT_CONNECTED; 79823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } else { 80823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mState = State.CONNECTED; 81823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 82823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 83823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mNetworkInfo = (NetworkInfo) 84823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 85823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mOtherNetworkInfo = (NetworkInfo) 86823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO); 87823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 88823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON); 89823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mIsFailover = 90823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false); 91823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 92823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang if (DBG) { 93823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang Log.d(TAG, "onReceive(): mNetworkInfo=" + mNetworkInfo + " mOtherNetworkInfo = " 94823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang + (mOtherNetworkInfo == null ? "[none]" : mOtherNetworkInfo + 95823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang " noConn=" + noConnectivity) + " mState=" + mState.toString()); 96823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 97823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 98823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang // Notifiy any handlers. 99823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang Iterator<Handler> it = mHandlers.keySet().iterator(); 100823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang while (it.hasNext()) { 101823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang Handler target = it.next(); 102823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang Message message = Message.obtain(target, mHandlers.get(target)); 103823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang target.sendMessage(message); 104823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 105823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 106194dda102240aeeaa30c28f4eda3e1d3ccdb6b03Scott Kennedy } 107823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 108823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public enum State { 109823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang UNKNOWN, 110823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 111823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** This state is returned if there is connectivity to any network **/ 112823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang CONNECTED, 113823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 114823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * This state is returned if there is no connectivity to any network. This is set 115823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * to true under two circumstances: 116823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * <ul> 117823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * <li>When connectivity is lost to one network, and there is no other available 118823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * network to attempt to switch to.</li> 119823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * <li>When connectivity is lost to one network, and the attempt to switch to 120823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * another network fails.</li> 121823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 122823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang NOT_CONNECTED 123823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 124823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 125823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 126823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * Create a new NetworkConnectivityListener. 127823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 128823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public NetworkConnectivityListener() { 129823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mState = State.UNKNOWN; 130823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mReceiver = new ConnectivityBroadcastReceiver(); 131823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 132823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 133823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 134823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * This method starts listening for network connectivity state changes. 135823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @param context 136823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 137823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public synchronized void startListening(Context context) { 138823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang if (!mListening) { 139823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mContext = context; 140823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 141823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang IntentFilter filter = new IntentFilter(); 142823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 143823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang context.registerReceiver(mReceiver, filter); 144823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mListening = true; 145823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 146823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 147823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 148823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 149823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * This method stops this class from listening for network changes. 150823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 151823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public synchronized void stopListening() { 152823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang if (mListening) { 153823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mContext.unregisterReceiver(mReceiver); 154823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mContext = null; 155823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mNetworkInfo = null; 156823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mOtherNetworkInfo = null; 157823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mIsFailover = false; 158823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mReason = null; 159823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mListening = false; 160823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 161823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 162823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 163823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 164823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * This methods registers a Handler to be called back onto with the specified what code when 165823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * the network connectivity state changes. 166823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * 167823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @param target The target handler. 168823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @param what The what code to be used when posting a message to the handler. 169823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 170823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public void registerHandler(Handler target, int what) { 171823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mHandlers.put(target, what); 172823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 173823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 174823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 175823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * This methods unregisters the specified Handler. 176823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @param target 177823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 178823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public void unregisterHandler(Handler target) { 179823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang mHandlers.remove(target); 180823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 181823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 182823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public State getState() { 183823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang return mState; 184823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 185823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 186823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 187823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * Return the NetworkInfo associated with the most recent connectivity event. 188823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @return {@code NetworkInfo} for the network that had the most recent connectivity event. 189823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 190823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public NetworkInfo getNetworkInfo() { 191823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang return mNetworkInfo; 192823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 193823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 194823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 195823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * If the most recent connectivity event was a DISCONNECT, return 196823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * any information supplied in the broadcast about an alternate 197823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * network that might be available. If this returns a non-null 198823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * value, then another broadcast should follow shortly indicating 199823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * whether connection to the other network succeeded. 200823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * 201823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @return NetworkInfo 202823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 203823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public NetworkInfo getOtherNetworkInfo() { 204823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang return mOtherNetworkInfo; 205823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 206823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 207823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 208823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * Returns true if the most recent event was for an attempt to switch over to 209823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * a new network following loss of connectivity on another network. 210823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @return {@code true} if this was a failover attempt, {@code false} otherwise. 211823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 212823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public boolean isFailover() { 213823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang return mIsFailover; 214823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 215823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang 216823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang /** 217823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * An optional reason for the connectivity state change may have been supplied. 218823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * This returns it. 219823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * @return the reason for the state change, if available, or {@code null} 220823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang * otherwise. 221823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang */ 222823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang public String getReason() { 223823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang return mReason; 224823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang } 225823b6f3516076b92f78c3fc27037d24bb514e653Ying Wang} 226