Задача: программно понять внутри приложения подключен ли смартфон к интернету. Узнать текущий источник — WiFi или сотовые данные.
Постоянна проверка текущего подключения
Реализация для Android до 9 (api 28)
Чтобы постоянно следить за связью, начиная с api level 28 у ConnectivityManager появились методы (un)registerDefaultNetworkCallback
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
cm.registerDefaultNetworkCallback(networkCallback);
...
cm.unregisterNetworkCallback(networkCallback);
Реализация для Android 9+ (api 28)
Постоянная проверка наличия сети на Android до версии 9 выполняется с помощью BroadcastReceiver.
Важно: регистрация данного ресивера должна происходить динамически из кода. Иначе, при объявлении в AndroidManifest он может не сработать
IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(networkChangeReceiver, intentFilter);
Получение текущего подключения
Необходимо не только постоянно следить за наличием и отсутствием соединения, но и за тем, какое именно доступно на текущий момент.
Получение имени подключения для Android M+ (api 23)
Имя подключения для Android младше чем api level 23 осуществляется с помощью ConnectivityManager
private String getConnectionTypeName() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork.getTypeName();
}
Получение имени подключения для Android M+ (api 23)
Начиная с Android M появилось больше простора для изучения текущего подключения.
@RequiresApi(Build.VERSION_CODES.M)
private String getConnectionTransportType() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
// If current connection is VPN, check if it's over WIFI or Cellular
for (Network network: cm.getAllNetworks()) {
NetworkCapabilities otherNetworkCap = cm.getNetworkCapabilities(network);
if (otherNetworkCap.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return getString(R.string.vpn) + ": " + getString(R.string.wifi);
} else if (otherNetworkCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return getString(R.string.vpn) + ": " + getString(R.string.cellurar);
}
}
return getString(R.string.vpn);
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return getString(R.string.wifi);
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return getString(R.string.cellurar);
}
return getString(R.string.other_connection);
} else {
return getString(R.string.no_connection);
}
}
Важно: если получить getActiveNetwork() при подключенном VPN и WiFi, то проверка этого подключения на WiFi выдаст false. Необходимо проверить все доступные подключения, потому что VPN это только одно из них.
Реализованный пример мониторинга сетевого подключения
Пример можно скачать и посмотреть в Google play


