检测并处理需要登录WiFi的情况。

17

我在一款Android应用程序中使用HttpClient 4.1,并尝试让它能够智能地处理我的应用程序API请求被那些“您需要登录或支付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;
    }
});

然后在我的Activity中:

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

展示无线网络屏幕的位置:

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

思路如下:

  • 我的 API 永远不会合法重定向
  • 所以我配置了 HttpClient,在它被重定向时抛出我的特殊 RuntimeException
  • 在 activity 代码中捕获该异常并弹出 Webview,将它们引导到登录屏幕
  • 一旦他们登录,wifi-login 就会祝贺他们做得很好,并提示他们返回应用程序

问题是,我从未收到那个 WifiLoginNeeded 异常。使用 Android,有哪种首选的方法来完成这个目标?


2
首先,确保您的http服务器返回正确的http响应(301或302)。 - yorkw
问题是,这不是我的服务器进行重定向。它是那些WiFi接入点之一,将所有内容指向其“登录我们昂贵的WiFi”页面。因此,我需要捕获我们可以想到的每种情况,以处理重定向的HTTP调用。 - Matthew Runo
2
它可能甚至不是你预期的重定向类型 - 还要确保生成了你期望的代码。访问点不一定返回你期望的特定HTTP代码,它可能会愉快地发送[200],表示一切正常,同时将你引导到他们的接入点登录屏幕。你可能想要存储你站点的IP地址,并将其与最新的HTTP请求返回的IP地址进行比较。如果它们不同,则调用登录屏幕。 - RightHandedMonkey
3个回答

2
作为一个更普遍的情况:您可以在您的公共API中包含一些像“Hello World”或“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 }

尝试连接并“ping”您的服务器。如果响应未以您期望的格式返回,则将相同的URL作为Intent抛出,让用户使用其选择的Web浏览器处理结果。

这也可以处理:企业代理(“公司XYZ禁止您!”)和未来自己API中不兼容的更改(“抱歉,我们不再支持那个12年前的API版本。请在那里下载更新。”)


-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
请查看下面的代码。这可能对您检查使用了哪种连接很有用。
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
}

如果可能的话,我想要避免这需要额外的权限。如果您已经在使用ACCESS_WIFI_STATE权限,那么这是一个不错的选择。 - Matthew Runo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接