2012-03-22 12 views
17

Sto usando HttpClient 4.1 in un'app Android e sto cercando di rendere più intelligente il fatto che le richieste API della mia app siano intercettate da uno di quegli schermi "è necessario accedere o pagare per il wifi".Rileva e gestisce la necessità di accedere per il wifi

Desidero visualizzare una visualizzazione Web che consente all'utente di accedere.

Ho cercato di intercettare il reindirizzamento in httpClient, ma non ho successo.

Questo è quello che sto attualmente cercando:

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

E poi nella mia attività:

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

dove l'esposizione dello schermo wifi fa questo:

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

Il pensiero is this:

  • mio API sarà mai reindirizzare legittimamente
  • Così ho configurato HttpClient di gettare il mio RuntimeException speciale quando è reindirizzato
  • Cattura tale eccezione nel codice attività e pop un Webview per farli indirizzati alla schermata di login
  • Una volta login, wifi-login si congratula con loro per un lavoro ben fatto e li richiama nell'app

Il fatto è che non ho mai ricevuto l'eccezione WifiLoginNeeded. Qual è il modo preferito per realizzare questo con Android?

+2

Innanzitutto, assicurarsi che il proprio server http restituisca la risposta http corretta (301 o 302). – yorkw

+0

Il fatto è che non è il mio server che esegue il reindirizzamento. È uno di quei punti di accesso Wi-Fi che punta tutto sulla pagina "Accedi alle nostre costose WiFi". Quindi ho bisogno di cogliere ogni caso che possiamo pensare per le chiamate HTTP reindirizzate. –

+2

Potrebbe anche non essere il tipo di reindirizzamento che ti aspetti, assicurati anche che i codici che ti aspetti vengano generati. Il punto di accesso non deve restituire il particolare codice HTTP che ci si aspetta e potrebbe inviare felicemente un [200] che indica che tutto va bene mentre si indirizza alle schermate di accesso del proprio punto di accesso. Si consiglia di memorizzare l'indirizzo IP del proprio sito e confrontarlo con l'indirizzo IP restituito dall'ultima richiesta http. Se sono diversi, richiama la schermata di accesso. – RightHandedMonkey

risposta

-2

Si prega di controllare il codice sottostante. Potrebbe essere utile per controllare quale tipo di connessioni stai usando.

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

Ciò richiede autorizzazioni extra, che vorrei evitare se possibile. Se stai già utilizzando il permesso ACCESS_WIFI_STATE, questo è un buon modo per andare, penso. –

-1

Prova questa piccola soluzione che aiuterà

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

Come caso più generale: È possibile includere qualcosa nella vostra API pubblica come un messaggio “Ciao Mondo” o “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 } 

Tentativo di connessione e "ping" del server. Se la risposta non viene restituita nel formato previsto, lancia lo stesso URL come un Intento affinché l'utente gestisca i risultati utilizzando il browser Web prescelto.

Questo dovrebbe anche gestire: i proxy aziendali ("la società XYZ vieta!") E le modifiche incompatibili nella vostra API in futuro ("mi dispiace, non supportiamo più la versione dell'API di 12 anni. scaricare un aggiornamento lì. ")

Problemi correlati