Задача: программно понять внутри приложения подключен ли смартфон к интернету. Узнать текущий источник — 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