Brian Nickel
Brian Nickel

Reputation: 27550

HTTP proxy in Android Emulator works for browser, not for WebView

My development environment is behind and HTTP proxy. In the Android emulator, I am able to set my proxy address and credentials in the wifi preferences. Then when I view the page in the browser, I get prompted to reenter my credentials for the host I specified. Not sure why I have to enter them again, but it works and I'm able to view the page.

I then have an app with a WebView which loads the same page. The app has internet permission:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

and supports platform notifications:

WebView.enablePlatformNotifications();

But... when I try viewing the page I get the proxy's error page saying the username and password weren't entered correctly. This suggests to me that the app is successfully reading the proxy address, but like the browser isn't reading the credentials. It is then lacking the ability to show the same dialog as the browser asking for the credentials before completing the request.

Is there a way to enable this dialog (is it built in?) or a way to manually specify the proxy details?

Upvotes: 2

Views: 4557

Answers (1)

Brian Nickel
Brian Nickel

Reputation: 27550

Looking at the android browser source code, the following is clear:

  1. WebViews have access to the HTTP proxy hostname and port as configured in Settings.
  2. WebViews (and apps) do not have access to the HTTP proxy username and password as configured in Settings.
  3. WebViews treat proxy authentication requests like other HTTP authentication requests, triggering onReceivedHttpAuthRequest of the attached WebViewClient with host set to "{proxy}:{port}" and realm set to an empty string.
  4. The browser is using its own custom dialog to handle authentication requests, and this dialog is not exposed to other apps.

As such, the easiest approach to duplicate the code and dialog layout from Android Browser:

  1. Copy res/layout/http_authentication.xml into your own project.
  2. Copy src/com/android/browser/HttpAuthenticationDialog.java
  3. Copy relevant strings from res/values/strings.xml
  4. Create a new class that implements WebViewClient and copy the onReceivedHttpAuthRequest method from com.android.browser.Controller.
  5. Modify the method to not depend on mPagesDialogHandler. context is your activity.

    HttpAuthenticationDialog dialog = new HttpAuthenticationDialog(context, host, realm);
    
    dialog.setOkListener(new HttpAuthenticationDialog.OkListener() {
        public void onOk(String host, String realm, String username, String password) {
            handler.proceed(username, password);
        }
    });
    
    dialog.setCancelListener(new HttpAuthenticationDialog.CancelListener() {
        public void onCancel() {
            handler.cancel();
        }
    });
    
    dialog.show();
    
  6. Use this new WebViewClient for your web views.

Upvotes: 7

Related Questions