Обходное сопоставление между NetworkInfo и NetworkInterface
В 2011 году я столкнулся с проблемой, о которой сообщалось в этой проблеме трекера, и хотел бы разработать подходящее решение. Я хотел бы показать пользователю все сетевые интерфейсы устройств Android, а также классифицировать их по их типу и независимо от того, активны они или нет. Я нацелен на API 15 как минимум.
Насколько я знаю, есть два способа получить информацию о сетевом интерфейсе:
-
С помощью встроенного класса Java NetworkInterface
с помощью NetworkInterface.getNetworkInterfaces()
. Это вернет объекты NetworkInterface
, содержащие информацию, такую как имя интерфейса, все IP-адреса, связанные с интерфейсом, и т.д. Для моего устройства (LG G3) я получаю интерфейсы, такие как lo
, wlan0
и rmnet0
. Это также возвращает информацию, такую как IP-адрес, MTU, маску подсети и широковещательный адрес, которые мне нужны.
-
Используя службу Android API ConnectivityManager
, используя aConnManager.getAllNetworkInfo()
. Это возвращает около 20 объектов NetworkInfo
для моего устройства, большинство из них не используются, но они включают типы MOBILE
, WIFI
, BLUETOOTH
и т.д. Это не включает в себя какие-либо сетевые параметры, такие как IP-адреса, MTU и т.д. как упоминалось выше.
Проблема, как объясняется в трекер, заключается в том, что нет встроенного способа сопоставления NetworkInfo
с NetworkInterface
или наоборот, и я хотел бы избежать использования имени интерфейса для сопоставления с соответствующим NetworkInfo
если это вообще возможно.
Поскольку у меня есть догадка, что это невозможно, есть ли список большинства потенциальных имен сетевых интерфейсов для большинства вендоров? rmnet[0-9]
представляется обычным для устройств с процессорами baseband Qualcomm и wlan[0-9]
для WiFi и т.д.
В худшем случае, я полагаю, я мог бы указать тип интерфейса как неизвестный, если имя интерфейса не соответствует общим шаблонам. Спасибо заранее.
Ответы
Ответ 1
Начиная с API 21 вы можете использовать LinkProperties
, чтобы получить NetworkInterface
из Network
Network
object:
ConnectivityManager manager = getSystemService(ConnectivityManager.class);
LinkProperties prop = manager.getLinkProperties(network);
NetworkInterface iface = NetworkInterface.getByName(prop.getInterfaceName());
Однако, хотя getAllNetworks()
предполагается заменить getAllNetworkInfo()
(первый, представленный в API 21, устарел последним в API 23), как и на Android 6.0.1, это не так. getAllNetworks()
не содержит список всех сетей (см. SO Q # 33374766). Похож на ошибку.
В качестве альтернативы, чтобы информировать пользователя о состоянии всех сетевых подключений, может быть зарегистрирован набор обратных вызовов для каждого типа транспорта, доступного в NetworkCapabilities (т.е. TRANSPORT_CELLULAR
, TRANSPORT_WIFI
, TRANSPORT_ETHERNET
, TRANSPORT_BLUETOOTH
и TRANSPORT_VPN
))
используя registerNetworkCallback
.