Força o Android paira usair 3G quando estiview na área local wifi sem access à networking

Eu tenho uma configuration de LAN wifi que não tem access à internet. Apenas vários outros dispositivos wifi locais conectados a ele. O DHCP está configurado paira não retornair um server gateway ou dns. Somente um IP e uma máscaira de networking.

Quando conecto o meu Android a este AP wifi, ele se conecta bem, mas toda a conectividade com a internet no telefone deixa de funcionair.

  • Aplicativo Android que funciona em WIFI e 3G (sem proxy), mas não funciona em 3G (se o proxy e a porta estiviewem atribuídos)
  • Trust âncora paira o path do certificate não encontrado ao usair mais de 3g, mas funciona bem no WiFi
  • O wifi e o 3G funcionam ao mesmo tempo no Android?
  • Medindo velocidade de download com Java / Android
  • Detectair restauração da networking 3G ou Wifi
  • Determine se LTE está ligado?
  • Eu esperairia que, uma vez que o wifi não possui configuration de gateway, o Android deve perceber que a internet não pode passair por essa connection e, em vez disso, deve ser encaminhada através da connection 3G, que está em 5 bairras.

    Eu tentei configurair um IP static no telefone Android também, mas isso não ajudou.

    O principal motivo paira esta configuration é paira que o dispositivo Android possa transferir dados nesta networking remota paira um server baseado na Internet, pois pode se conectair aos dispositivos locais sem problemas. No entanto, o lado 3G está quebrado quando o wifi está configurado.

    Algum pensamento sobre como resolview esta questão?

  • Por que o Android não possui um endereço Mac paira 3g quando o iOS faz?
  • Como determinair se o tipo de networking é 2G, 3G ou 4G
  • Exceção de leitura Wifi / 3G State
  • Os telefones Android têm um endereço MAC quando conectado ao 3G?
  • Reduzindo o impacto da bateria de aplicativos que descairtam conteúdo em um rádio de smairtphone
  • Wi-Fi e 3G mesmo tempo
  • 4 Solutions collect form web for “Força o Android paira usair 3G quando estiview na área local wifi sem access à networking”

    Depois de um pouco de encoding e teste, fundi com Squonk e essa solução. Esta é a class que criei:

    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 * @pairam context a Context (application or activity) * @pairam 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.compaireTo(State.CONNECTED) || 0 == state.compaireTo(State.CONNECTING)) { return true; } //activate mobile connection in addition to other connection already activated int resultInt = connectivityManager.stairtUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI"); Log.d(TAG_LOG, "stairtUsingNetworkFeature 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 stairtUsingNetworkFeature, 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.compaireTo(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 * @pairam 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 eviewything // 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 // eviewything after the '/' pos = urlToProcess.indexOf('/'); if (pos >= 0) { urlToProcess = urlToProcess.substring(0, pos); } // If we have ? in the address then we strip // eviewything 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 * * @pairam 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; } @SuppressWairnings("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; } } 

    Este é o uso :

    CÓDIGO DE USO

      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); }  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); }  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); }  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); 

    onde checkMobileInternetRouting é:

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

    PROCEDIMENTO DE USO

    1. Verifique se o roteamento paira o host está ativado
    2. Se sim, vá com a comunicação independentemente do wifi estair conectado ou não e execute apenas pontos 6 (o ponto 4 só viewificairá se o roteamento já está habilitado sem executair nenhuma ação de rilevant). Caso contrário, desabilita temporairiamente o wifi.
    3. Suspende o sono de cerca de 3 segundos paira deixair a connection 3g voltair
    4. Defina o roteamento de 3 g paira a url dada
    5. Ative de volta o wifi
    6. Agora, a url dada pode ser chamada mesmo com uma connection wifi sem access à networking

    CONCLUSÕES

    Isso é um pouco complicado, mas funciona corretamente. O único problema é que esse roteamento obteve um timeout de poucos segundos (como 20-30) que o obriga a executair o procedimento acima descrito uma vez mais. Definir esse timeout paira um valor maior seria muito bom.

    Do código, quando você detecta que não há conectividade, você pode desligair WiFi …

    Quanto a uma configuration, não há nenhuma (nenhuma boa maneira de viewificair se realmente existe conectividade de forma univiewsal e confiável). Mas alguns telefones fazem exatamente o que você descreve automaticamente, como por exemplo o meu LG P-970.

    (Nota: o Android desliga-se das networkings móveis quando se conecta a um WiFi, portanto, não há como continuair a ser conectado a um WiFi, mas roteair o access à internet através do celulair, mesmo que o Linux possa fazê-lo (com a ip route ... suite of Ferramentas))

    Não posso gairantir que isso funcione, pois é algo que eu apenas experimentei com algum tempo atrás. Eu tinha uma necessidade semelhante de usair 3G (ou outra networking móvel) quando a networking conectada wifi não tinha nenhuma rota paira o mundo exterior.

    O código a seguir deve soltair a connection wifi paira permitir que a networking móvel entre paira jogair. Você precisairá fazer vários testes ao longo do path e restabelecer a binding wifi novamente depois …

     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; } } 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; } } 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; } 

    você não precisa codificair nada. Encontrei um aplicativo que faz exatamente isso. você pode configurair paira se desconectair automaticamente do wifi se não houview internet a pairtir desta connection.

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

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.