Enhanced WebView component for Android that works as intended out of the box
- Android 2.2+
- Add this library to your project
Declare the Gradle repository in your root
build.gradleallprojects{repositories{maven{url "https://jitpack.io" } } }
Declare the Gradle dependency in your app module's
build.gradledependencies{compile 'com.github.delight-im:Android-AdvancedWebView:v3.0.0' }
<uses-permissionandroid:name="android.permission.INTERNET" /><im.delight.android.webview.AdvancedWebView android:id="@+id/webview"android:layout_width="match_parent"android:layout_height="match_parent" />publicclassMyActivityextendsActivityimplementsAdvancedWebView.Listener{privateAdvancedWebViewmWebView; @OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); mWebView = (AdvancedWebView) findViewById(R.id.webview); mWebView.setListener(this, this); mWebView.loadUrl("http://www.example.org/"); // ... } @SuppressLint("NewApi") @OverrideprotectedvoidonResume(){super.onResume(); mWebView.onResume(); // ... } @SuppressLint("NewApi") @OverrideprotectedvoidonPause(){mWebView.onPause(); // ...super.onPause()} @OverrideprotectedvoidonDestroy(){mWebView.onDestroy(); // ...super.onDestroy()} @OverrideprotectedvoidonActivityResult(intrequestCode, intresultCode, Intentintent){super.onActivityResult(requestCode, resultCode, intent); mWebView.onActivityResult(requestCode, resultCode, intent); // ... } @OverridepublicvoidonBackPressed(){if (!mWebView.onBackPressed()){return} // ...super.onBackPressed()} @OverridepublicvoidonPageStarted(Stringurl, Bitmapfavicon){} @OverridepublicvoidonPageFinished(Stringurl){} @OverridepublicvoidonPageError(interrorCode, Stringdescription, StringfailingUrl){} @OverridepublicvoidonDownloadRequested(Stringurl, StringsuggestedFilename, StringmimeType, longcontentLength, StringcontentDisposition, StringuserAgent){} @OverridepublicvoidonExternalPageRequest(Stringurl){} }Note: If you're using the Fragment class from the support library (android.support.v4.app.Fragment), please refer to the next section (see below) instead of this one.
publicclassMyFragmentextendsFragmentimplementsAdvancedWebView.Listener{privateAdvancedWebViewmWebView; publicMyFragment(){} @OverridepublicViewonCreateView(LayoutInflaterinflater, ViewGroupcontainer, BundlesavedInstanceState){ViewrootView = inflater.inflate(R.layout.fragment_my, container, false); mWebView = (AdvancedWebView) rootView.findViewById(R.id.webview); mWebView.setListener(this, this); mWebView.loadUrl("http://www.example.org/"); // ...returnrootView} @SuppressLint("NewApi") @OverridepublicvoidonResume(){super.onResume(); mWebView.onResume(); // ... } @SuppressLint("NewApi") @OverridepublicvoidonPause(){mWebView.onPause(); // ...super.onPause()} @OverridepublicvoidonDestroy(){mWebView.onDestroy(); // ...super.onDestroy()} @OverridepublicvoidonActivityResult(intrequestCode, intresultCode, Intentintent){super.onActivityResult(requestCode, resultCode, intent); mWebView.onActivityResult(requestCode, resultCode, intent); // ... } @OverridepublicvoidonPageStarted(Stringurl, Bitmapfavicon){} @OverridepublicvoidonPageFinished(Stringurl){} @OverridepublicvoidonPageError(interrorCode, Stringdescription, StringfailingUrl){} @OverridepublicvoidonDownloadRequested(Stringurl, StringsuggestedFilename, StringmimeType, longcontentLength, StringcontentDisposition, StringuserAgent){} @OverridepublicvoidonExternalPageRequest(Stringurl){} }Use the code for normal
Fragmentusage as shown aboveChange
mWebView.setListener(this, this);
to
mWebView.setListener(getActivity(), this);
Add the following code to the parent
FragmentActivityin order to forward the results from theFragmentActivityto the appropriateFragmentinstancepublicclassMyActivityextendsFragmentActivityimplementsAdvancedWebView.Listener{@OverridepublicvoidonActivityResult(intrequestCode, intresultCode, Intentintent){super.onActivityResult(requestCode, resultCode, intent); if (mFragment != null){mFragment.onActivityResult(requestCode, resultCode, intent)} } }
-keep class * extends android.webkit.WebChromeClient{*} -dontwarn im.delight.android.webview.** Optimized for best performance and security
Features are patched across Android versions
File uploads are handled automatically (check availability with
AdvancedWebView.isFileUploadAvailable())- Multiple file uploads via single input fields (
multipleattribute in HTML) are supported on Android 5.0+. The application that is used to pick the files (i.e. usually a gallery or file manager app) must provide controls for selecting multiple files, which some apps don't.
- Multiple file uploads via single input fields (
JavaScript and WebStorage are enabled by default
Includes localizations for the 25 most widely spoken languages
Receive callbacks when pages start/finish loading or have errors
@OverridepublicvoidonPageStarted(Stringurl, Bitmapfavicon){// a new page started loading } @OverridepublicvoidonPageFinished(Stringurl){// the new page finished loading } @OverridepublicvoidonPageError(interrorCode, Stringdescription, StringfailingUrl){// the new page failed to load }
Downloads are handled automatically and can be listened to
@OverridepublicvoidonDownloadRequested(Stringurl, StringsuggestedFilename, StringmimeType, longcontentLength, StringcontentDisposition, StringuserAgent){// some file is available for download// either handle the download yourself or use the code belowif (AdvancedWebView.handleDownload(this, url, suggestedFilename)){// download successfully handled } else{// download couldn't be handled because user has disabled download manager app on the device// TODO show some notice to the user } }
Enable geolocation support (needs
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />)mWebView.setGeolocationEnabled(true);
Add custom HTTP headers in addition to the ones sent by the web browser implementation
mWebView.addHttpHeader("X-Requested-With", "My wonderful app");
Define a custom set of permitted hostnames and receive callbacks for all other hostnames
mWebView.addPermittedHostname("example.org");
and
@OverridepublicvoidonExternalPageRequest(Stringurl){// the user tried to open a page from a non-permitted hostname }
Prevent caching of HTML pages
booleanpreventCaching = true; mWebView.loadUrl("http://www.example.org/", preventCaching);
Check for alternative browsers installed on the device
if (AdvancedWebView.Browsers.hasAlternative(this)){AdvancedWebView.Browsers.openUrl(this, "http://www.example.org/")}
Disable cookies
// disable third-party cookies onlymWebView.setThirdPartyCookiesEnabled(false); // or disable cookies in generalmWebView.setCookiesEnabled(false);
Disallow mixed content (HTTP content being loaded inside HTTPS sites)
mWebView.setMixedContentAllowed(false);
Switch between mobile and desktop mode
mWebView.setDesktopMode(true); // or// mWebView.setDesktopMode(false);
Load HTML file from “assets” (e.g. at
app/src/main/assets/html/index.html)mWebView.loadUrl("file:///android_asset/html/index.html");
Load HTML file from SD card
// <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){mWebView.getSettings().setAllowFileAccess(true); mWebView.loadUrl("file:///sdcard/Android/data/com.my.app/my_folder/index.html")}
Load HTML source text and display as page
myWebView.loadHtml("<html>...</html>"); // orfinalStringmyBaseUrl = "http://www.example.com/"; myWebView.loadHtml("<html>...</html>", myBaseUrl);
Enable multi-window support
myWebView.getSettings().setSupportMultipleWindows(true); // myWebView.getSettings().setJavaScriptEnabled(true);// myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);myWebView.setWebChromeClient(newWebChromeClient(){@OverridepublicbooleanonCreateWindow(WebViewview, booleanisDialog, booleanisUserGesture, MessageresultMsg){AdvancedWebViewnewWebView = newAdvancedWebView(MyNewActivity.this); // myParentLayout.addView(newWebView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);WebView.WebViewTransporttransport = (WebView.WebViewTransport) resultMsg.obj; transport.setWebView(newWebView); resultMsg.sendToTarget(); returntrue} }
All contributions are welcome! If you wish to contribute, please create an issue first so that your feature, problem or question can be discussed.
This project is licensed under the terms of the MIT License.