Intereting Posts
Android. Разработка 2D игр ValueEventListener vs ChildEventListener для RecyclerView в Android Перекрытие эффекта тени остается в навигационном навигационном навигаторе Слишком большой размер, чтобы вписаться в рисование кеша в Webview внутри scrollview Предварительно заполненная база данных Android Пользовательский экран входящего / исходящего звонка в Android Facebook SDK 3.8: разрешение publish_actions не возвращается Android использует PorterDuff для объединения изображений Как избежать удаления для собственных кодовых символов для приложения для Android Покрытие кода Jacoco в Android Studio с ароматами Android: использование AUTO-CANCEL при уведомлении, когда ваше приложение работает в фоновом режиме Сопоставление java в реальном времени с несколькими полями Показать выбор из списка предложений в Android searchview Как настроить Android Studio, чтобы я мог скомпилировать ее в автономном режиме (отключен от Интернета) Активность просочилась в окно com.android.internal.policy.impl.PhoneWindow$DecorView@46029dd0, которое было первоначально добавлено здесь

Force Android использует 3G, когда на Wi-Fi локальной сети без сетевого доступа

У меня есть настройка Wi-Fi LAN, которая не имеет доступа в Интернет. К нему подключены различные другие локальные Wi-Fi-устройства. DHCP настроен так, чтобы не возвращать сервер шлюза или DNS. Только IP и сетевая маска.

Когда я подключаю свой Android к этому Wi-Fi, он прекрасно соединяется, но все интернет-соединения на телефоне перестают работать.

Я бы ожидал, что, поскольку Wi-Fi не имеет настроек шлюза, этот андроид должен понимать, что интернет не может пройти через это соединение и должен быть маршрутизирован через 3G-соединение, которое составляет 5 баров.

Я попытался установить статический IP-адрес на телефоне Android, но это не помогло.

Основная причина этой настройки заключается в том, что устройство Android может передавать данные в этой удаленной сети на интернет-сервер, так как без проблем может подключаться к локальным устройствам. Однако сторона 3G сломается после установки Wi-Fi.

Любые мысли о том, как обойти эту проблему?

Solutions Collecting From Web of "Force Android использует 3G, когда на Wi-Fi локальной сети без сетевого доступа"

После немного кодирования и тестирования я объединил Squonk и это решение. Это класс, который я создал:

package it.helian.exampleprj.network; import java.net.InetAddress; import java.net.UnknownHostException; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; import android.text.TextUtils; import android.util.Log; public class NetworkUtils { private static final String TAG_LOG = "ExamplePrj"; Context context; WifiManager wifiMan = null; WifiManager.WifiLock wifiLock = null; public NetworkUtils(Context context) { super(); this.context = context; } /** * Enable mobile connection for a specific address * @param context a Context (application or activity) * @param address the address to enable * @return true for success, else false */ public boolean forceMobileConnectionForAddress(Context context, String address) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (null == connectivityManager) { Log.d(TAG_LOG, "ConnectivityManager is null, cannot try to force a mobile connection"); return false; } //check if mobile connection is available and connected State state = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); Log.d(TAG_LOG, "TYPE_MOBILE_HIPRI network state: " + state); if (0 == state.compareTo(State.CONNECTED) || 0 == state.compareTo(State.CONNECTING)) { return true; } //activate mobile connection in addition to other connection already activated int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI"); Log.d(TAG_LOG, "startUsingNetworkFeature for enableHIPRI result: " + resultInt); //-1 means errors // 0 means already enabled // 1 means enabled // other values can be returned, because this method is vendor specific if (-1 == resultInt) { Log.e(TAG_LOG, "Wrong result of startUsingNetworkFeature, maybe problems"); return false; } if (0 == resultInt) { Log.d(TAG_LOG, "No need to perform additional network settings"); return true; } //find the host name to route String hostName = extractAddressFromUrl(address); Log.d(TAG_LOG, "Source address: " + address); Log.d(TAG_LOG, "Destination host address to route: " + hostName); if (TextUtils.isEmpty(hostName)) hostName = address; //create a route for the specified address int hostAddress = lookupHost(hostName); if (-1 == hostAddress) { Log.e(TAG_LOG, "Wrong host address transformation, result was -1"); return false; } //wait some time needed to connection manager for waking up try { for (int counter=0; counter<30; counter++) { State checkState = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); if (0 == checkState.compareTo(State.CONNECTED)) break; Thread.sleep(1000); } } catch (InterruptedException e) { //nothing to do } boolean resultBool = connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress); Log.d(TAG_LOG, "requestRouteToHost result: " + resultBool); if (!resultBool) Log.e(TAG_LOG, "Wrong requestRouteToHost result: expected true, but was false"); state = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); Log.d(TAG_LOG, "TYPE_MOBILE_HIPRI network state after routing: " + state); return resultBool; } /** * This method extracts from address the hostname * @param url eg. http://some.where.com:8080/sync * @return some.where.com */ public String extractAddressFromUrl(String url) { String urlToProcess = null; //find protocol int protocolEndIndex = url.indexOf("://"); if(protocolEndIndex>0) { urlToProcess = url.substring(protocolEndIndex + 3); } else { urlToProcess = url; } // If we have port number in the address we strip everything // after the port number int pos = urlToProcess.indexOf(':'); if (pos >= 0) { urlToProcess = urlToProcess.substring(0, pos); } // If we have resource location in the address then we strip // everything after the '/' pos = urlToProcess.indexOf('/'); if (pos >= 0) { urlToProcess = urlToProcess.substring(0, pos); } // If we have ? in the address then we strip // everything after the '?' pos = urlToProcess.indexOf('?'); if (pos >= 0) { urlToProcess = urlToProcess.substring(0, pos); } return urlToProcess; } /** * Transform host name in int value used by {@link ConnectivityManager.requestRouteToHost} * method * * @param hostname * @return -1 if the host doesn't exists, elsewhere its translation * to an integer */ private int lookupHost(String hostname) { InetAddress inetAddress; try { inetAddress = InetAddress.getByName(hostname); } catch (UnknownHostException e) { return -1; } byte[] addrBytes; int addr; addrBytes = inetAddress.getAddress(); addr = ((addrBytes[3] & 0xff) << 24) | ((addrBytes[2] & 0xff) << 16) | ((addrBytes[1] & 0xff) << 8 ) | (addrBytes[0] & 0xff); return addr; } @SuppressWarnings("unused") private int lookupHost2(String hostname) { InetAddress inetAddress; try { inetAddress = InetAddress.getByName(hostname); } catch (UnknownHostException e) { return -1; } byte[] addrBytes; int addr; addrBytes = inetAddress.getAddress(); addr = ((addrBytes[3] & 0xff) << 24) | ((addrBytes[2] & 0xff) << 16) | ((addrBytes[1] & 0xff) << 8 ) | (addrBytes[0] & 0xff); return addr; } public Boolean disableWifi() { wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (wifiMan != null) { wifiLock = wifiMan.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "HelianRCAWifiLock"); } return wifiMan.setWifiEnabled(false); } public Boolean enableWifi() { Boolean success = false; if (wifiLock != null && wifiLock.isHeld()) wifiLock.release(); if (wifiMan != null) success = wifiMan.setWifiEnabled(true); return success; } } 

Это использование :

КОД ИСПОЛЬЗОВАНИЯ

  boolean mobileRoutingEnabled = checkMobileInternetRouting(); if(!mobileRoutingEnabled) { networkUtils.disableWifi(); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } networkUtils.forceMobileConnectionForAddress(context, RCA_URL); if(!mobileRoutingEnabled) { networkUtils.enableWifi(); } // This second check is for testing purpose checkMobileInternetRouting(); return callWebService(RCA_COMPLETE_URL, _plate); 

Где checkMobileInternetRouting :

 private boolean checkMobileInternetRouting() { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); State state = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); return 0 == state.compareTo(State.CONNECTED) || 0 == state.compareTo(State.CONNECTING); } 

ПРОЦЕДУРА ИСПОЛЬЗОВАНИЯ

  1. Проверьте, включена ли маршрутизация на хост
  2. Если да, переходите к сообщению независимо от того, подключен ли Wi-Fi или нет, и выполняйте только точки 6 (точка 4 будет проверять, что маршрутизация уже включена без выполнения какого-либо действия rilevant). В противном случае временное отключает Wi-Fi.
  3. Запуск нитки около 3 секунд для возврата 3g-соединения
  4. Установите 3g-маршрутизацию на указанный URL-адрес
  5. Включить обратно Wi-Fi
  6. Теперь данный url можно назвать даже с Wi-Fi-соединением без сетевых адаптеров

ВЫВОДЫ

Это немного взломанно, но работает правильно. Единственная проблема заключается в том, что эта маршрутизация имеет тайм-аут в несколько секунд (например, 20-30), что заставляет вас выполнить всю описанную выше процедуру еще раз. Установка этого тайм-аута на большее значение будет очень хорошей.

Из кода, когда вы обнаруживаете, что нет возможности подключения, вы можете отключить WiFi …

Что касается настройки, нет ни одного (нет хорошего способа проверить, действительно ли соединение действительно и надежно). Но некоторые телефоны делают то, что вы описываете автоматически, например, например, мой LG P-970.

(Примечание. Android отключается от мобильных сетей при подключении к WiFi, поэтому нет возможности подключаться к WiFi, но подключить к интернету через мобильный телефон, хотя Linux может это сделать (с набором ip route ... инструменты))

Я не могу гарантировать, что это сработает, поскольку это то, о чем я только что экспериментировал некоторое время назад. У меня была аналогичная необходимость использовать 3G (или другую мобильную сеть), когда сеть с подключением Wi-Fi не имела никакого маршрута к внешнему миру.

Следующий код должен отключить соединение Wi-Fi, чтобы позволить мобильной сети войти в игру. Вам нужно будет выполнить различные тесты на этом пути и снова восстановить соединение wifi …

 WifiManager wifiMan = null; WifiManager.WifiLock wifiLock = null; private Boolean disableWifi() { wifiMan = (WifiManager) getSystemService(Context.WIFI_SERVICE); if (wifiMan != null) { wifiLock = wifiMan.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "MyWifiLock"); } return wifiMan.setWifiEnabled(false); } private Boolean enableWifi() { Boolean success; if (wifiLock != null) wifiLock.release(); if (wifiMan != null) success = wifiMan.setWifiEnabled(true); return success; } 

Вам не нужно ничего кодировать. Я нашел приложение, которое делает именно эту вещь. Вы можете настроить автоматическое отключение от Wi-Fi, если из этого соединения нет Интернета.

https://play.google.com/store/apps/details?id=com.nLabs.internetconnectivity&hl=en