1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.common; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.net.ConnectivityManager; 24 import android.net.NetworkInfo; 25 import android.os.Handler; 26 import android.os.Message; 27 import android.util.Log; 28 29 import java.util.HashMap; 30 import java.util.Iterator; 31 32 /** 33 * A wrapper for a broadcast receiver that provides network connectivity 34 * state information, independent of network type (mobile, Wi-Fi, etc.). 35 * @deprecated Code tempted to use this class should simply listen for connectivity intents 36 * (or poll ConnectivityManager) directly. 37 * {@hide} 38 */ 39 public class NetworkConnectivityListener { 40 private static final String TAG = "NetworkConnectivityListener"; 41 private static final boolean DBG = false; 42 43 private Context mContext; 44 private HashMap<Handler, Integer> mHandlers = new HashMap<Handler, Integer>(); 45 private State mState; 46 private boolean mListening; 47 private String mReason; 48 private boolean mIsFailover; 49 50 /** Network connectivity information */ 51 private NetworkInfo mNetworkInfo; 52 53 /** 54 * In case of a Disconnect, the connectivity manager may have 55 * already established, or may be attempting to establish, connectivity 56 * with another network. If so, {@code mOtherNetworkInfo} will be non-null. 57 */ 58 private NetworkInfo mOtherNetworkInfo; 59 60 private ConnectivityBroadcastReceiver mReceiver; 61 62 private class ConnectivityBroadcastReceiver extends BroadcastReceiver { 63 @Override 64 public void onReceive(Context context, Intent intent) { 65 String action = intent.getAction(); 66 67 if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || 68 mListening == false) { 69 Log.w(TAG, "onReceived() called with " + mState.toString() + " and " + intent); 70 return; 71 } 72 73 boolean noConnectivity = 74 intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 75 76 if (noConnectivity) { 77 mState = State.NOT_CONNECTED; 78 } else { 79 mState = State.CONNECTED; 80 } 81 82 mNetworkInfo = (NetworkInfo) 83 intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 84 mOtherNetworkInfo = (NetworkInfo) 85 intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO); 86 87 mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON); 88 mIsFailover = 89 intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false); 90 91 if (DBG) { 92 Log.d(TAG, "onReceive(): mNetworkInfo=" + mNetworkInfo + " mOtherNetworkInfo = " 93 + (mOtherNetworkInfo == null ? "[none]" : mOtherNetworkInfo + 94 " noConn=" + noConnectivity) + " mState=" + mState.toString()); 95 } 96 97 // Notifiy any handlers. 98 Iterator<Handler> it = mHandlers.keySet().iterator(); 99 while (it.hasNext()) { 100 Handler target = it.next(); 101 Message message = Message.obtain(target, mHandlers.get(target)); 102 target.sendMessage(message); 103 } 104 } 105 }; 106 107 public enum State { 108 UNKNOWN, 109 110 /** This state is returned if there is connectivity to any network **/ 111 CONNECTED, 112 /** 113 * This state is returned if there is no connectivity to any network. This is set 114 * to true under two circumstances: 115 * <ul> 116 * <li>When connectivity is lost to one network, and there is no other available 117 * network to attempt to switch to.</li> 118 * <li>When connectivity is lost to one network, and the attempt to switch to 119 * another network fails.</li> 120 */ 121 NOT_CONNECTED 122 } 123 124 /** 125 * Create a new NetworkConnectivityListener. 126 */ 127 public NetworkConnectivityListener() { 128 mState = State.UNKNOWN; 129 mReceiver = new ConnectivityBroadcastReceiver(); 130 } 131 132 /** 133 * This method starts listening for network connectivity state changes. 134 * @param context 135 */ 136 public synchronized void startListening(Context context) { 137 if (!mListening) { 138 mContext = context; 139 140 IntentFilter filter = new IntentFilter(); 141 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 142 context.registerReceiver(mReceiver, filter); 143 mListening = true; 144 } 145 } 146 147 /** 148 * This method stops this class from listening for network changes. 149 */ 150 public synchronized void stopListening() { 151 if (mListening) { 152 mContext.unregisterReceiver(mReceiver); 153 mContext = null; 154 mNetworkInfo = null; 155 mOtherNetworkInfo = null; 156 mIsFailover = false; 157 mReason = null; 158 mListening = false; 159 } 160 } 161 162 /** 163 * This methods registers a Handler to be called back onto with the specified what code when 164 * the network connectivity state changes. 165 * 166 * @param target The target handler. 167 * @param what The what code to be used when posting a message to the handler. 168 */ 169 public void registerHandler(Handler target, int what) { 170 mHandlers.put(target, what); 171 } 172 173 /** 174 * This methods unregisters the specified Handler. 175 * @param target 176 */ 177 public void unregisterHandler(Handler target) { 178 mHandlers.remove(target); 179 } 180 181 public State getState() { 182 return mState; 183 } 184 185 /** 186 * Return the NetworkInfo associated with the most recent connectivity event. 187 * @return {@code NetworkInfo} for the network that had the most recent connectivity event. 188 */ 189 public NetworkInfo getNetworkInfo() { 190 return mNetworkInfo; 191 } 192 193 /** 194 * If the most recent connectivity event was a DISCONNECT, return 195 * any information supplied in the broadcast about an alternate 196 * network that might be available. If this returns a non-null 197 * value, then another broadcast should follow shortly indicating 198 * whether connection to the other network succeeded. 199 * 200 * @return NetworkInfo 201 */ 202 public NetworkInfo getOtherNetworkInfo() { 203 return mOtherNetworkInfo; 204 } 205 206 /** 207 * Returns true if the most recent event was for an attempt to switch over to 208 * a new network following loss of connectivity on another network. 209 * @return {@code true} if this was a failover attempt, {@code false} otherwise. 210 */ 211 public boolean isFailover() { 212 return mIsFailover; 213 } 214 215 /** 216 * An optional reason for the connectivity state change may have been supplied. 217 * This returns it. 218 * @return the reason for the state change, if available, or {@code null} 219 * otherwise. 220 */ 221 public String getReason() { 222 return mReason; 223 } 224 } 225