Использование нескольких сетевых интерфейсов в приложении
Я написал приложение, которое запускает подключаемую камеру Sony qx для подключения смартфона через Wi-Fi. Однако мне нужно передавать изображения с телефона через другую локальную сеть в режиме реального времени. Поскольку Wi-Fi-карта используется для подключения qx, мне нужно иметь возможность использовать ethernet через USB для передачи изображений с телефона. Запросы Http будут использоваться для запуска камеры и отправки изображений с телефона.
Возможно ли в одном приложении Android на телефоне с настройкой двух сетевых интерфейсов указать определенные HTTP-запросы для использования одного сетевого интерфейса, а другим - использовать другой сетевой интерфейс? Нужно ли это делать через таблицы маршрутизации, а не java?
Телефон, который я использую, - это корневая связь 6p.
Update:
В настоящее время я смог получить адаптер Ethernet, работающий с устройством (Nexus 6P). Устройство подключено к локальной сети через Ethernet. Когда Wi-Fi интерфейс выключен, я могу выполнить ping все устройства в локальной сети, к которой подключено устройство через Ethernet. Тем не менее, я не могу получить доступ к веб-серверам (не используя DNS) любого из устройств в этой сети (которые, как я знаю, они работают), т.е. Http, через браузер. Nexus 6p подключается к сети через Ethernet через Ubiquiti Station. Это, по-видимому, проблема маршрутизации.
Я могу привязать (интерфейс usb) и использовать Wi-Fi в одном приложении, поэтому мне кажется, что можно использовать Ethernet и Wi-Fi.
Update2
После большего тестирования, похоже, что это проблема с разрешениями. Поскольку, когда я пингую сеть, устройство подключено к сети Ethernet без первого запуска su
в терминале, сеть не существует. Однако, когда я запускаю su
, тогда пинг, я могу выполнить ping сеть. Таким образом, кажется, что моему приложению нужно получить разрешение суперпользователя до доступа к Ethernet. Я предоставил ему доступ к суперпользователю, но ничего не изменилось. Я читал, что просто запустить su
недостаточно из одного из комментариев в этом сообщении . Это потому, что su
просто порождает корневую оболочку, которая умирает. Это также объясняет, почему я не мог получить доступ к любому веб-серверу в этой сети через приложение-браузер. Возможно ли предоставить доступ моему приложению к интерфейсу Ethernet при выполнении HTTP-вызовов, например, предоставить HttpURLConnection
root-доступ, если это имеет смысл (работает su
не работает)? Кажется, что определенно существует решение, так как HttpURLConnection может совершать вызовы через USB-модемный интерфейс (Nexus 6P называет его rndis0
).
Обновление 3:
Я нашел онлайн здесь, что я могу сделать свое приложение системным приложением (подумал, что это может предоставить доступ к нему eth0). Я просто перенес свое приложение на /system/app
, а затем перезагрузился. Однако, похоже, это больше не придает приложениям больше привилегий (таким образом, не решая проблему), или есть что-то еще, требуемое для создания системы приложений, а не просто копирование ее на /system/app
.
Обновление 4:
Итак, я смог получить Ethernet, работающий над каждым приложением без прав root! Казалось, что он работает только через DHCP и не любит статические соединения, которые я использовал. Он работает с включенным Wi-Fi, однако я не могу связаться ни с одним из устройств в сети Wi-Fi, когда включен Ethernet. Есть ли способ обойти это? Это связано с установкой двух шлюзов по умолчанию?
Ответы
Ответ 1
Поскольку вы программировали в Nexus 6P, вы можете попробовать использовать новый API, добавленный в ConnectivityManager
, чтобы выбрать ethernet в качестве предпочтительного сетевого подключения для вашего процесса.
Поскольку я не могу создать подобную среду, подобную вашей, я не уверен, что она работает. Это просто предлагаемое решение, полностью не проверенное и проверенное.
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
Network etherNetwork = null;
for (Network network : connectivityManager.getAllNetworks()) {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
if (networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
etherNetwork = network;
}
}
Network boundNetwork = connectivityManager.getBoundNetworkForProcess();
if (boundNetwork != null) {
NetworkInfo boundNetworkInfo = connectivityManager.getNetworkInfo(boundNetwork);
if (boundNetworkInfo.getType() != ConnectivityManager.TYPE_ETHERNET) {
if (etherNetwork != null) {
connectivityManager.bindProcessToNetwork(etherNetwork);
}
}
}
Ответ 2
Большинство ящиков Android могут использовать Wi-Fi и Ethernet вместе. В моем устройстве я могу включить ethernet с этого пути ---
Настройки → Подробнее... > Ethernet ---
Но ваше устройство не будет иметь такое меню, как я понимаю. Поэтому вы должны сделать приложение, чтобы сделать это. Это приложение должно получить доступ к некоторым системным ресурсам, поэтому ваше устройство должно быть внедрено или приложение должно подписаться с сигнатурой системы.
Также этот раздел поможет вам ссылка
Ответ 3
Просто чтобы дать немного больше объяснений о том, как это окончательно разрешилось.
Используя ответ @alijandro, я смог переключиться между Ethernet и Wi-Fi в одном приложении. По какой-то причине для работы Ethernet это потребовало, чтобы сетевой шлюз предоставлял адрес DHCP, а не статический. Тогда, поскольку bindProcessToNetwork
, используемый в ответе @alijandro, предназначен для каждого процесса, я решил разделить связь с камерой QX на Service
, которая запускается в отдельном Процессе. Основное приложение (другой процесс) будет размещать изображения через Ethernet в локальной сети. Я смог успешно связаться с устройствами в локальной сети через HTTP через Ethernet, одновременно запуская QX через Wi-Fi. В настоящее время я использовал Messenger
для связи с помощью IPC, чтобы сообщить о запуске QX Service
, какие методы вызывать.