{"id":15027541,"url":"https://github.com/delight-im/android-advancedwebview","last_synced_at":"2025-04-14T20:54:08.351Z","repository":{"id":25511359,"uuid":"28942939","full_name":"delight-im/Android-AdvancedWebView","owner":"delight-im","description":"Enhanced WebView component for Android that works as intended out of the box","archived":false,"fork":false,"pushed_at":"2021-04-02T13:32:20.000Z","size":438,"stargazers_count":2403,"open_issues_count":53,"forks_count":576,"subscribers_count":88,"default_branch":"master","last_synced_at":"2025-04-07T15:03:57.977Z","etag":null,"topics":["android","android-webview","mobile","mobile-development","web","web-app","web-application","webview"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/delight-im.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-08T01:33:59.000Z","updated_at":"2025-04-03T16:48:20.000Z","dependencies_parsed_at":"2022-07-13T15:59:29.940Z","dependency_job_id":null,"html_url":"https://github.com/delight-im/Android-AdvancedWebView","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delight-im%2FAndroid-AdvancedWebView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delight-im%2FAndroid-AdvancedWebView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delight-im%2FAndroid-AdvancedWebView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delight-im%2FAndroid-AdvancedWebView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/delight-im","download_url":"https://codeload.github.com/delight-im/Android-AdvancedWebView/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248961084,"owners_count":21189990,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-webview","mobile","mobile-development","web","web-app","web-application","webview"],"created_at":"2024-09-24T20:06:38.551Z","updated_at":"2025-04-14T20:54:08.306Z","avatar_url":"https://github.com/delight-im.png","language":"Java","readme":"# AdvancedWebView\n\nEnhanced WebView component for Android that works as intended out of the box\n\n## Requirements\n\n * Android 2.2+\n\n## Installation\n\n * Add this library to your project\n   * Declare the Gradle repository in your root `build.gradle`\n\n     ```gradle\n     allprojects {\n         repositories {\n             maven { url \"https://jitpack.io\" }\n         }\n     }\n     ```\n\n   * Declare the Gradle dependency in your app module's `build.gradle`\n\n     ```gradle\n     dependencies {\n         implementation 'com.github.delight-im:Android-AdvancedWebView:v3.2.1'\n     }\n     ```\n\n## Usage\n\n### AndroidManifest.xml\n\n```xml\n\u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n```\n\n### Layout (XML)\n\n```xml\n\u003cim.delight.android.webview.AdvancedWebView\n    android:id=\"@+id/webview\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\" /\u003e\n```\n\n### Activity (Java)\n\n#### Without Fragments\n\n```java\npublic class MyActivity extends Activity implements AdvancedWebView.Listener {\n\n    private AdvancedWebView mWebView;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_my);\n\n        mWebView = (AdvancedWebView) findViewById(R.id.webview);\n        mWebView.setListener(this, this);\n        mWebView.setMixedContentAllowed(false);\n        mWebView.loadUrl(\"http://www.example.org/\");\n\n        // ...\n    }\n\n    @SuppressLint(\"NewApi\")\n    @Override\n    protected void onResume() {\n        super.onResume();\n        mWebView.onResume();\n        // ...\n    }\n\n    @SuppressLint(\"NewApi\")\n    @Override\n    protected void onPause() {\n        mWebView.onPause();\n        // ...\n        super.onPause();\n    }\n\n    @Override\n    protected void onDestroy() {\n        mWebView.onDestroy();\n        // ...\n        super.onDestroy();\n    }\n\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {\n        super.onActivityResult(requestCode, resultCode, intent);\n        mWebView.onActivityResult(requestCode, resultCode, intent);\n        // ...\n    }\n\n    @Override\n    public void onBackPressed() {\n        if (!mWebView.onBackPressed()) { return; }\n        // ...\n        super.onBackPressed();\n    }\n\n    @Override\n    public void onPageStarted(String url, Bitmap favicon) { }\n\n    @Override\n    public void onPageFinished(String url) { }\n\n    @Override\n    public void onPageError(int errorCode, String description, String failingUrl) { }\n\n    @Override\n    public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) { }\n\n    @Override\n    public void onExternalPageRequest(String url) { }\n\n}\n```\n\n#### With Fragments (`android.app.Fragment`)\n\n**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.\n\n```java\npublic class MyFragment extends Fragment implements AdvancedWebView.Listener {\n\n    private AdvancedWebView mWebView;\n\n    public MyFragment() { }\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        View rootView = inflater.inflate(R.layout.fragment_my, container, false);\n\n        mWebView = (AdvancedWebView) rootView.findViewById(R.id.webview);\n        mWebView.setListener(this, this);\n        mWebView.setMixedContentAllowed(false);\n        mWebView.loadUrl(\"http://www.example.org/\");\n\n        // ...\n\n        return rootView;\n    }\n\n    @SuppressLint(\"NewApi\")\n    @Override\n    public void onResume() {\n        super.onResume();\n        mWebView.onResume();\n        // ...\n    }\n\n    @SuppressLint(\"NewApi\")\n    @Override\n    public void onPause() {\n        mWebView.onPause();\n        // ...\n        super.onPause();\n    }\n\n    @Override\n    public void onDestroy() {\n        mWebView.onDestroy();\n        // ...\n        super.onDestroy();\n    }\n\n    @Override\n    public void onActivityResult(int requestCode, int resultCode, Intent intent) {\n        super.onActivityResult(requestCode, resultCode, intent);\n        mWebView.onActivityResult(requestCode, resultCode, intent);\n        // ...\n    }\n\n    @Override\n    public void onPageStarted(String url, Bitmap favicon) { }\n\n    @Override\n    public void onPageFinished(String url) { }\n\n    @Override\n    public void onPageError(int errorCode, String description, String failingUrl) { }\n\n    @Override\n    public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) { }\n\n    @Override\n    public void onExternalPageRequest(String url) { }\n\n}\n```\n\n#### With Fragments from the support library (`android.support.v4.app.Fragment`)\n\n * Use the code for normal `Fragment` usage as shown above\n * Change\n\n   ```java\n   mWebView.setListener(this, this);\n   ```\n\n   to\n\n   ```java\n   mWebView.setListener(getActivity(), this);\n   ```\n\n * Add the following code to the parent `FragmentActivity` in order to forward the results from the `FragmentActivity` to the appropriate `Fragment` instance\n\n   ```java\n   public class MyActivity extends FragmentActivity implements AdvancedWebView.Listener {\n\n    @Override\n    public void onActivityResult(int requestCode, int resultCode, Intent intent) {\n        super.onActivityResult(requestCode, resultCode, intent);\n        if (mFragment != null) {\n            mFragment.onActivityResult(requestCode, resultCode, intent);\n        }\n    }\n\n   }\n   ```\n\n### ProGuard (if enabled)\n\n```\n-keep class * extends android.webkit.WebChromeClient { *; }\n-dontwarn im.delight.android.webview.**\n```\n\n### Cleartext (non-HTTPS) traffic\n\nIf you want to serve sites or just single resources over plain `http` instead of `https`, there’s usually nothing to do if you’re targeting Android 8.1 (API level 27) or earlier. On Android 9 (API level 28) and later, however, [cleartext support is disabled by default](https://developer.android.com/training/articles/security-config). You may have to set `android:usesCleartextTraffic=\"true\"` on the `\u003capplication\u003e` element in `AndroidManifest.xml` or provide a custom [network security configuration](https://developer.android.com/training/articles/security-config).\n\n## Features\n\n * Optimized for best performance and security\n * Features are patched across Android versions\n * File uploads are handled automatically (check availability with `AdvancedWebView.isFileUploadAvailable()`)\n   * Multiple file uploads via single input fields (`multiple` attribute 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.\n * JavaScript and WebStorage are enabled by default\n * Includes localizations for the 25 most widely spoken languages\n * Receive callbacks when pages start/finish loading or have errors\n\n   ```java\n   @Override\n   public void onPageStarted(String url, Bitmap favicon) {\n       // a new page started loading\n   }\n\n   @Override\n   public void onPageFinished(String url) {\n       // the new page finished loading\n   }\n\n   @Override\n   public void onPageError(int errorCode, String description, String failingUrl) {\n       // the new page failed to load\n   }\n   ```\n\n * Downloads are handled automatically and can be listened to\n\n   ```java\n   @Override\n   public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) {\n       // some file is available for download\n       // either handle the download yourself or use the code below\n\n       if (AdvancedWebView.handleDownload(this, url, suggestedFilename)) {\n           // download successfully handled\n       }\n       else {\n           // download couldn't be handled because user has disabled download manager app on the device\n           // TODO show some notice to the user\n       }\n   }\n   ```\n\n * Enable geolocation support (needs `\u003cuses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" /\u003e`)\n\n   ```java\n   mWebView.setGeolocationEnabled(true);\n   ```\n\n * Add custom HTTP headers in addition to the ones sent by the web browser implementation\n\n   ```java\n   mWebView.addHttpHeader(\"X-Requested-With\", \"My wonderful app\");\n   ```\n\n * Define a custom set of permitted hostnames and receive callbacks for all other hostnames\n\n   ```java\n   mWebView.addPermittedHostname(\"example.org\");\n   ```\n\n   and\n\n   ```java\n   @Override\n   public void onExternalPageRequest(String url) {\n       // the user tried to open a page from a non-permitted hostname\n   }\n   ```\n\n * Prevent caching of HTML pages\n\n   ```java\n   boolean preventCaching = true;\n   mWebView.loadUrl(\"http://www.example.org/\", preventCaching);\n   ```\n\n * Check for alternative browsers installed on the device\n\n   ```java\n   if (AdvancedWebView.Browsers.hasAlternative(this)) {\n       AdvancedWebView.Browsers.openUrl(this, \"http://www.example.org/\");\n   }\n   ```\n\n * Disable cookies\n\n   ```java\n   // disable third-party cookies only\n   mWebView.setThirdPartyCookiesEnabled(false);\n   // or disable cookies in general\n   mWebView.setCookiesEnabled(false);\n   ```\n\n * Allow or disallow (both passive and active) mixed content (HTTP content being loaded inside HTTPS sites)\n\n   ```java\n   mWebView.setMixedContentAllowed(true);\n   // or\n   mWebView.setMixedContentAllowed(false);\n   ```\n\n * Switch between mobile and desktop mode\n\n   ```java\n   mWebView.setDesktopMode(true);\n   // or\n   // mWebView.setDesktopMode(false);\n   ```\n\n * Load HTML file from “assets” (e.g. at `app/src/main/assets/html/index.html`)\n\n   ```java\n   mWebView.loadUrl(\"file:///android_asset/html/index.html\");\n   ```\n\n * Load HTML file from SD card\n\n   ```java\n   // \u003cuses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" /\u003e\n\n   if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {\n       mWebView.getSettings().setAllowFileAccess(true);\n       mWebView.loadUrl(\"file:///sdcard/Android/data/com.my.app/my_folder/index.html\");\n   }\n   ```\n\n * Load HTML source text and display as page\n\n   ```java\n   myWebView.loadHtml(\"\u003chtml\u003e...\u003c/html\u003e\");\n\n   // or\n\n   final String myBaseUrl = \"http://www.example.com/\";\n   myWebView.loadHtml(\"\u003chtml\u003e...\u003c/html\u003e\", myBaseUrl);\n   ```\n\n * Enable multi-window support\n\n   ```java\n   myWebView.getSettings().setSupportMultipleWindows(true);\n   // myWebView.getSettings().setJavaScriptEnabled(true);\n   // myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);\n\n   myWebView.setWebChromeClient(new WebChromeClient() {\n\n       @Override\n       public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {\n           AdvancedWebView newWebView = new AdvancedWebView(MyNewActivity.this);\n           // myParentLayout.addView(newWebView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);\n           WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;\n           transport.setWebView(newWebView);\n           resultMsg.sendToTarget();\n\n           return true;\n       }\n\n   }\n   ```\n\n## Contributing\n\nAll contributions are welcome! If you wish to contribute, please create an issue first so that your feature, problem or question can be discussed.\n\n## License\n\nThis project is licensed under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelight-im%2Fandroid-advancedwebview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdelight-im%2Fandroid-advancedwebview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelight-im%2Fandroid-advancedwebview/lists"}