Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect and handle needing to login for wifi

I'm using HttpClient 4.1 in an Android app and trying to make it smart about having my app's API requests intercepted by one of those "you need to login or pay for wifi" screens.

I want to pop up a webview allowing the user to login.

I've been trying to intercept the redirect in httpClient, but I am unsuccessful.

This is what I'm currently trying:

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

And then in my activity:

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

where the show wifi screen does this:

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

The thinking is this:

  • My API will never redirect legitimately
  • So I configure HttpClient to throw my special RuntimeException when it's redirected
  • Catch that exception in activity code and pop a Webview to get them directed to the login screen
  • Once they login, wifi-login congratulates them on a job well done and prompts them back into the app

The thing is, I never get that WifiLoginNeeded exception. What is the preferred way to accomplish this with Android?

like image 313
Matthew Runo Avatar asked Mar 22 '12 22:03

Matthew Runo


1 Answers

As a more general case: You can include something in your public API like a “Hello World” or “Ping” message.

    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 }

Attempt to connect and “ping” your server. If the response is not returned in the format you expect then, toss the same URL up as an Intent for the user to deal with the results using their web browser of choice.

This would also handle: corporate proxies (“company XYZ forbids you!”), and incompatible changes in your own API in future (“sorry, we no longer support that 12-year-old version of the API. Please download an update there.”)

like image 76
BRPocock Avatar answered Oct 12 '22 01:10

BRPocock