2012-03-22 17 views
17

Estoy usando HttpClient 4.1 en una aplicación de Android y trato de que sea inteligente que las aplicaciones de mi aplicación sean interceptadas por una de esas pantallas de "necesitas iniciar sesión o pagar por wifi".Detecta y maneja la necesidad de iniciar sesión en wifi

Quiero mostrar una vista web que permita al usuario iniciar sesión.

He intentado interceptar la redirección en httpClient, pero no he tenido éxito.

Esto es lo que estoy tratando actualmente:

this.client = new DefaultHttpClient(connectionManager, params); 

((DefaultHttpClient) this.client).setRedirectStrategy(new DefaultRedirectStrategy() { 
    public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) { 
     boolean isRedirect = Boolean.FALSE; 
     try { 
      isRedirect = super.isRedirected(request, response, context); 
     } catch (ProtocolException e) { 
      Log.e(TAG, "Failed to run isRedirected", e); 
     } 
     if (!isRedirect) { 
      int responseCode = response.getStatusLine().getStatusCode(); 
      if (responseCode == 301 || responseCode == 302) { 
       throw new WifiLoginNeeded(); 
       // The "real implementation" should return true here.. 
      } 
     } else { 
      throw new WifiLoginNeeded(); 
     } 

     return isRedirect; 
    } 
}); 

Y luego, en mi actividad:

try { 
    response = httpClient.get(url); 
} catch (WifiLoginNeeded e){ 
    showWifiLoginScreen(); 
} 

donde la pantalla Show WiFi hace esto:

Uri uri = Uri.parse("http://our-site.com/wifi-login"); 
Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent); 

El pensamiento es esto:

  • Mi API nunca se volverá a dirigir legítimamente
  • Así configuro HttpClient a tirar mi RuntimeException especial cuando es redirigido
  • Catch esa excepción en el código de actividad y hacer estallar una vista Web para conseguir que dirigen a la pantalla
  • entrada Una vez que se iniciar sesión, wifi-login los felicita por un trabajo bien hecho y los solicita de nuevo en la aplicación

El hecho es que nunca recibo esa excepción de WifiLoginNeeded. ¿Cuál es la forma preferida de lograr esto con Android?

+2

Primero, asegúrese de que su servidor http devuelve la httpReponse correcta (301 o 302). – yorkw

+0

El problema es que no es mi servidor el que hace la redirección. Es uno de esos puntos de acceso WiFi que apunta todo a su página "Iniciar sesión en nuestro costoso WiFi". Así que tengo que atrapar todos los casos que podamos pensar para las llamadas HTTP redirigidas. –

+2

Puede que ni siquiera sea el tipo de redireccionamiento que espera; también asegúrese de que se generen los códigos que espera. El punto de acceso no tiene que devolver el código HTTP particular que espera y puede enviar un [200] que indica que todo está bien mientras lo dirige a las pantallas de inicio de sesión del punto de acceso. Es posible que desee almacenar la dirección IP de su sitio y compararla con la dirección IP devuelta por la última solicitud HTTP. Si son diferentes, abre la pantalla de inicio de sesión. – RightHandedMonkey

Respuesta

-2

Por favor, compruebe el siguiente código. Puede serle útil verificar qué tipo de Conexiones está utilizando.

WifiManager lWifiManager = (WifiManager) OpenYouTubePlayerActivity.this.getSystemService(Context.WIFI_SERVICE); 
TelephonyManager lTelephonyManager = (TelephonyManager) OpenYouTubePlayerActivity.this.getSystemService(Context.TELEPHONY_SERVICE); 

//////////////////////////// 
// if we have a fast connection (wifi or 3g) 
if((lWifiManager.isWifiEnabled() && lWifiManager.getConnectionInfo() != null && lWifiManager.getConnectionInfo().getIpAddress() != 0) || 
    ((lTelephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS || 

    /* icky... using literals to make backwards compatible with 1.5 and 1.6 */  
    lTelephonyManager.getNetworkType() == 9 /*HSUPA*/ || 
    lTelephonyManager.getNetworkType() == 10 /*HSPA*/ || 
    lTelephonyManager.getNetworkType() == 8 /*HSDPA*/ || 
    lTelephonyManager.getNetworkType() == 5 /*EVDO_0*/ || 
    lTelephonyManager.getNetworkType() == 6 /*EVDO A*/) 

    && lTelephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED) 
    ){ 
     //Do some thing here 
} 
+0

Esto requiere permisos adicionales, que me gustaría evitar si es posible. Si ya está usando el permiso ACCESS_WIFI_STATE, creo que esta es una buena forma de hacerlo. –

-1

probar este pequeño solución que ayudará

public boolean haveNetworkConnection() { 
    cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 
      Boolean haveConnectedWifi = false; 
      Boolean haveConnectedMobile = false; 

      NetworkInfo[] netInfo = cm.getAllNetworkInfo(); 
      for (NetworkInfo ni : netInfo) { 
       if (ni.getTypeName().equalsIgnoreCase("WIFI")) 
        if (ni.isConnected()) 
         haveConnectedWifi = true; 
       if (ni.getTypeName().equalsIgnoreCase("MOBILE")) 
        if (ni.isConnected()) 
         haveConnectedMobile = true; 
      } 
      return haveConnectedWifi || haveConnectedMobile; 
     } 
2

Como caso más general: Puede incluir algo en su API pública o como un mensaje “Hola mundo” “ping”.

GET http://api.example.com/1.0/ping HTTP/1.1 
    Accepts: text/json 

    Content-Type: text/json 
    { ping: "ok", currentAPIVersion: 1.1, minAPIVersion: 1.0 } 

Intenta conectar y "hacer ping" a tu servidor. Si la respuesta no se devuelve en el formato que espera entonces, agregue el mismo URL como Intento para que el usuario maneje los resultados usando su navegador web de su elección.

Esto también manejaría: proxies corporativos ("la compañía XYZ te lo prohibe"), y cambios incompatibles en tu propia API en el futuro ("lo siento, ya no admitimos esa versión de la API de 12 años. descargue una actualización allí. ")

Cuestiones relacionadas