Last active
January 18, 2021 10:35
-
-
Save yangweigbh/e89bb4336f6ccb6e59ef05f28f03405f to your computer and use it in GitHub Desktop.
Class to listen to network change
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface NetworkEventProvider { | |
void setListener(Listener listener); | |
interface Listener { | |
/** | |
* @param networkStatus {@link com.birbit.android.jobqueue.network.NetworkUtil.NetworkStatus} | |
*/ | |
void onNetworkChange(@NetworkUtil.NetworkStatus int networkStatus); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface NetworkUtil { | |
/** | |
* Order of these constant values matter as they are relied upon to be incrementing in terms | |
* of availability. | |
*/ | |
@Retention(RetentionPolicy.SOURCE) | |
@IntDef({DISCONNECTED, METERED, UNMETERED}) | |
@interface NetworkStatus {} | |
int DISCONNECTED = 0; | |
int METERED = 1; | |
int UNMETERED = 2; | |
/** | |
* Returns the current connection status. If you cannot detect granular network type, return | |
* {@link #UNMETERED} if there is an internet connection or {@link #DISCONNECTED} if there is no | |
* connection. | |
* | |
* @param context The application context | |
* | |
* @return The current connection status. It should be one of {@link #DISCONNECTED}, | |
* {@link #METERED} or {@link #UNMETERED}. | |
*/ | |
@NetworkStatus | |
int getNetworkStatus(Context context); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class NetworkUtilImpl implements NetworkUtil, NetworkEventProvider { | |
private Listener listener; | |
public NetworkUtilImpl(Context context) { | |
context = context.getApplicationContext(); | |
if (VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
if (VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
listenForIdle(context); | |
} | |
listenNetworkViaConnectivityManager(context); | |
} else { | |
context.registerReceiver(new BroadcastReceiver() { | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
dispatchNetworkChange(context); | |
} | |
}, getNetworkIntentFilter()); | |
} | |
} | |
@TargetApi(23) | |
private void listenNetworkViaConnectivityManager(final Context context) { | |
ConnectivityManager cm = (ConnectivityManager) context | |
.getSystemService(Context.CONNECTIVITY_SERVICE); | |
NetworkRequest request = new NetworkRequest.Builder() | |
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) | |
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) | |
.build(); | |
cm.registerNetworkCallback(request, new ConnectivityManager.NetworkCallback() { | |
@Override | |
public void onAvailable(Network network) { | |
dispatchNetworkChange(context); | |
} | |
}); | |
} | |
@TargetApi(23) | |
private void listenForIdle(Context context) { | |
context.registerReceiver(new BroadcastReceiver() { | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
dispatchNetworkChange(context); | |
} | |
}, new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)); | |
} | |
void dispatchNetworkChange(Context context) { | |
if(listener == null) {//shall not be but just be safe | |
return; | |
} | |
//http://developer.android.com/reference/android/net/ConnectivityManager.html#EXTRA_NETWORK_INFO | |
//Since NetworkInfo can vary based on UID, applications should always obtain network information | |
// through getActiveNetworkInfo() or getAllNetworkInfo(). | |
listener.onNetworkChange(getNetworkStatus(context)); | |
} | |
@Override | |
public int getNetworkStatus(Context context) { | |
if (isDozing(context)) { | |
return NetworkUtil.DISCONNECTED; | |
} | |
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); | |
NetworkInfo netInfo = cm.getActiveNetworkInfo(); | |
if (netInfo == null) { | |
return NetworkUtil.DISCONNECTED; | |
} | |
if (netInfo.getType() == ConnectivityManager.TYPE_WIFI || | |
netInfo.getType() == ConnectivityManager.TYPE_ETHERNET) { | |
return NetworkUtil.UNMETERED; | |
} | |
return NetworkUtil.METERED; | |
} | |
@TargetApi(23) | |
private static IntentFilter getNetworkIntentFilter() { | |
IntentFilter networkIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); | |
if (VERSION.SDK_INT >= 23) { | |
networkIntentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); | |
} | |
return networkIntentFilter; | |
} | |
/** | |
* Returns true if the device is in Doze/Idle mode. Should be called before checking the network connection because | |
* the ConnectionManager may report the device is connected when it isn't during Idle mode. | |
*/ | |
@TargetApi(23) | |
private static boolean isDozing(Context context) { | |
if (VERSION.SDK_INT >= 23) { | |
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); | |
return powerManager.isDeviceIdleMode() && | |
!powerManager.isIgnoringBatteryOptimizations(context.getPackageName()); | |
} else { | |
return false; | |
} | |
} | |
@Override | |
public void setListener(Listener listener) { | |
this.listener = listener; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment