|
5 | 5 | import android.net.Network;
|
6 | 6 | import android.net.NetworkCapabilities;
|
7 | 7 | import android.net.NetworkInfo;
|
| 8 | +import android.net.NetworkRequest; |
8 | 9 | import android.os.Build;
|
9 | 10 | import android.util.Log;
|
10 | 11 |
|
11 |
| -import androidx.annotation.RequiresApi; |
| 12 | +import java.util.ArrayList; |
| 13 | +import java.util.List; |
| 14 | + |
| 15 | +import androidx.annotation.NonNull; |
| 16 | + |
12 | 17 |
|
13 | 18 | /**
|
14 | 19 | * NetworkManager manages all network related information, including but not limited to
|
15 | 20 | * connectivity states, active network information(wifi, cellular) and
|
16 | 21 | * listen to changes in network states.
|
| 22 | + * |
| 23 | + * @see <a href="https://developer.android.com/training/basics/network-ops/reading-network-state#java">reading network state</a> |
17 | 24 | */
|
18 | 25 | public class NetworkManager {
|
19 | 26 |
|
20 | 27 | // LOG TAG constant
|
21 |
| - private static final String LOG_TAG = "NETWORK_MANAGER_TAG"; |
| 28 | + private static final String TAG = "NETWORK_MANAGER_TAG"; |
| 29 | + |
| 30 | + public interface NetworkChangeListener { |
| 31 | + void onAvailable(); |
| 32 | + void onUnavailable(); |
| 33 | + void onLost(); |
| 34 | + void onCellularNetworkChanged(boolean isConnected); |
| 35 | + } |
| 36 | + |
| 37 | + // A List of registered ColorChangeListeners |
| 38 | + private List<NetworkChangeListener> mNetworkChangeListeners; |
| 39 | + |
| 40 | + // A Network Callback object |
| 41 | + private ConnectivityManager.NetworkCallback networkCallback; |
22 | 42 |
|
23 | 43 | // the connectivity manager object that keeps track of all information
|
24 | 44 | // related to phone's connectivyt states.
|
25 | 45 | private ConnectivityManager connectivityManager;
|
26 | 46 |
|
| 47 | + // the network object that encapsulates all info regarding Network |
| 48 | + private Network network; |
| 49 | + |
27 | 50 | // the network capabilities object that stores everything that the
|
28 | 51 | // current device supports with regards to networking.
|
29 | 52 | private NetworkCapabilities capabilities;
|
30 | 53 |
|
31 |
| - // boolean value that keeps track of the cellular connectivity state. |
32 |
| - private boolean isCellularConnected; |
33 |
| - |
34 | 54 | /**
|
35 | 55 | * Initialize a Network Manager object following the context of current device.
|
36 | 56 | * @param context the Context object of the current device
|
37 | 57 | */
|
38 |
| - public NetworkManager(Context context) { |
| 58 | + public NetworkManager(@NonNull Context context) { |
39 | 59 | this.connectivityManager =
|
40 | 60 | (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
41 | 61 |
|
42 |
| - Network network = this.connectivityManager.getActiveNetwork(); |
| 62 | + this.network = this.connectivityManager.getActiveNetwork(); |
43 | 63 | this.capabilities = this.connectivityManager.getNetworkCapabilities(network);
|
44 |
| - this.isCellularConnected = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); |
| 64 | + this.mNetworkChangeListeners = new ArrayList<>(); |
| 65 | + } |
| 66 | + |
| 67 | + /** |
| 68 | + * Registers a new listener |
| 69 | + * |
| 70 | + * @param networkChangeListener a new listener (should not be null). |
| 71 | + */ |
| 72 | + public void addNetworkChangeListener(@NonNull NetworkChangeListener networkChangeListener) { |
| 73 | + mNetworkChangeListeners.add(networkChangeListener); |
| 74 | + |
| 75 | + NetworkRequest request = new NetworkRequest |
| 76 | + .Builder() |
| 77 | + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) |
| 78 | + .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) |
| 79 | + .build(); |
| 80 | + |
| 81 | + this.networkCallback = new ConnectivityManager.NetworkCallback() { |
| 82 | + @Override |
| 83 | + public void onAvailable(@NonNull Network network) { |
| 84 | + super.onAvailable(network); |
| 85 | + Log.i(TAG, "current network is " + network); |
| 86 | + mNetworkChangeListeners.forEach(NetworkChangeListener::onAvailable); |
| 87 | + } |
| 88 | + |
| 89 | + @Override |
| 90 | + public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) { |
| 91 | + super.onCapabilitiesChanged(network, networkCapabilities); |
| 92 | + Log.e(TAG, "The default network changed capabilities: " + networkCapabilities); |
| 93 | + mNetworkChangeListeners.forEach(l -> l.onCellularNetworkChanged( |
| 94 | + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) |
| 95 | + )); |
| 96 | + } |
| 97 | + |
| 98 | + @Override |
| 99 | + public void onLost(@NonNull Network network) { |
| 100 | + super.onLost(network); |
| 101 | + Log.e(TAG, "The default network lost. Previous one is " + network); |
| 102 | + mNetworkChangeListeners.forEach(NetworkChangeListener::onLost); |
| 103 | + } |
| 104 | + |
| 105 | + @Override |
| 106 | + public void onUnavailable() { |
| 107 | + super.onUnavailable(); |
| 108 | + Log.e(TAG, "The default network is unavailable"); |
| 109 | + mNetworkChangeListeners.forEach(NetworkChangeListener::onUnavailable); |
| 110 | + } |
| 111 | + }; |
| 112 | + |
| 113 | + this.connectivityManager.registerNetworkCallback(request, networkCallback); |
| 114 | + } |
| 115 | + |
| 116 | + /** |
| 117 | + * Remove a specified listener |
| 118 | + * |
| 119 | + * @param networkChangeListener the listener to be removed (should not be null) |
| 120 | + */ |
| 121 | + public void removeNetworokChangeListener(@NonNull NetworkChangeListener networkChangeListener) { |
| 122 | + mNetworkChangeListeners.remove(networkChangeListener); |
45 | 123 | }
|
46 | 124 |
|
47 | 125 | /**
|
48 |
| - * Returns the cellular connectivity state of the current device. |
| 126 | + * Remove all registered listeners |
| 127 | + */ |
| 128 | + public void removeAllNetworkChangeListeners() { |
| 129 | + mNetworkChangeListeners.clear(); |
| 130 | + this.connectivityManager.unregisterNetworkCallback(this.networkCallback); |
| 131 | + } |
| 132 | + |
| 133 | + /** |
| 134 | + * Returns the current cellular connectivity state of the current device when this method gets called. |
49 | 135 | * @return true if the current device is connected to the internet via cellular; false otherwise.
|
50 | 136 | */
|
51 | 137 | public boolean isCellularConnected() {
|
52 |
| - return isCellularConnected; |
| 138 | + return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); |
| 139 | + } |
| 140 | + |
| 141 | + public int getLinkDownstreamBandwidthKbps() { |
| 142 | + return this.capabilities.getLinkDownstreamBandwidthKbps(); |
| 143 | + } |
| 144 | + |
| 145 | + public int getLinkUpstreamBandwidthKbps() { |
| 146 | + return this.capabilities.getLinkUpstreamBandwidthKbps(); |
53 | 147 | }
|
54 | 148 | }
|
0 commit comments