2012-03-22 24 views
17

我在Android應用中使用HttpClient 4.1,並試圖讓我的應用的API請求被其中一個「您需要登錄或支付wifi」屏幕攔截的智能設備變得聰明。檢測並處理需要登錄的WiFi

我想彈出一個webview允許用戶登錄。

我一直在嘗試攔截httpClient中的重定向,但我不成功。

這是我目前想:

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

然後在我的活動:

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

,其中顯示的wifi屏幕做到這一點:

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

的思考是這樣的:

  • 我的API絕不會合法地重定向
  • 所以我配置的HttpClient把我的特殊的RuntimeException當它重定向
  • 捕獲了異常的活動代碼,並彈出一個網頁視圖,讓他們直接登錄屏幕
  • 一旦他們登錄,wifi登錄祝賀他們做得好,並提示他們回到應用程序

事情是,我從來沒有得到該WifiLoginNeeded異常。使用Android完成此操作的首選方法是什麼?

+2

首先,確保你的http服務器返回正確的httpReponse(301或302)。 – yorkw 2012-03-27 02:48:19

+0

事情是,這不是我的服務器做重定向。這是WiFi接入點之一,它將所有內容指向他們的「登錄到我們昂貴的WiFi」頁面。所以我需要抓住每個我們可以想到的重定向HTTP調用的情況。 – 2012-03-27 13:46:25

+2

它甚至可能不是您所期望的重定向類型 - 也請確保您所期望的代碼正在生成。接入點不必返回您期望的特定HTTP代碼,它可能會愉快地發送一個[200]指示您在接入點登錄屏幕時一切正常。 您可能希望存儲您的站點的IP地址,並將其與最新的http請求返回的IP地址進行比較。如果它們不同,請調出登錄屏幕。 – RightHandedMonkey 2012-08-29 23:41:18

回答

-2

請檢查以下代碼。您可能需要檢查您正在使用的連接類型。

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

這需要額外的權限,如果可能的話,我想避免這些權限。如果您已經使用了ACCESS_WIFI_STATE權限,那麼這是我認爲的一個好方法。 – 2012-03-27 20:38:58

-1

試試這個小的解決方案將幫助

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

作爲一個更一般的情況:你可以包括你的公共API中像一個「Hello World」或「平」的消息。

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 } 

嘗試連接並「ping」您的服務器。如果響應沒有以您期望的格式返回,請將相同的URL作爲用戶的意圖拋出,以便使用他們選擇的Web瀏覽器處理結果。

這也可以處理:企業代理(「XYZ公司禁止你!」),以及將來你自己的API不兼容的變化(「對不起,我們不再支持這個12年的API版本。在那裏下載更新。「)