2012-03-22 47 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版本。在那里下载更新。“)