/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.webkit; import android.content.Context; import android.content.Intent; import java.io.File; import java.util.List; import java.util.Map; /** *
* A View that displays web pages. This class is the basis upon which you can * roll your own web browser or simply display some online content within your * Activity. It uses the WebKit rendering engine to display web pages and * includes methods to navigate forward and backward through a history, zoom in * and out, perform text searches and more. * *
* Note that, in order for your Activity to access the Internet and load web * pages in a WebView, you must add the {@code INTERNET} permissions to your * Android Manifest file: * *
* {@code }
*
*
*
* This must be a child of the {@code
* For more information, read * Building Web Apps in * WebView. * *
* By default, a WebView provides no browser-like widgets, does not enable * JavaScript and web page errors are ignored. If your goal is only to display * some HTML as a part of your UI, this is probably fine; the user won't need to * interact with the web page beyond reading it, and the web page won't need to * interact with the user. If you actually want a full-blown web browser, then * you probably want to invoke the Browser application with a URL Intent rather * than show it with a WebView. For example: * *
* Uri uri = Uri.parse("https://www.example.com");
* Intent intent = new Intent(Intent.ACTION_VIEW, uri);
* startActivity(intent);
*
* * See {@link android.content.Intent} for more information. * *
* To provide a WebView in your own Activity, include a {@code
* Then load the desired web page:
*
*
* A WebView has several customization points where you can add your own
* behavior. These are:
*
*
* Here's a more complicated example, showing error handling, settings, and
* progress notification:
*
*
* To enable the built-in zoom, set {@link #getSettings()
* WebSettings}.{@link WebSettings#setBuiltInZoomControls(boolean)} (introduced
* in API level {@link android.os.Build.VERSION_CODES#CUPCAKE}).
*
*
* Note: Using zoom if either the height or width is set to
* {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} may lead to
* undefined behavior and should be avoided.
*
*
* For obvious security reasons, your application has its own cache, cookie
* store etc.—it does not share the Browser application's data.
*
*
* By default, requests by the HTML to open new windows are ignored. This is
* {@code true} whether they be opened by JavaScript or by the target attribute
* on a link. You can customize your {@link WebChromeClient} to provide your own
* behavior for opening multiple windows, and render them in whatever manner you
* want.
*
*
* The standard behavior for an Activity is to be destroyed and recreated when
* the device orientation or any other configuration changes. This will cause
* the WebView to reload the current page. If you don't want that, you can set
* your Activity to handle the {@code orientation} and {@code keyboardHidden}
* changes, and then just leave the WebView alone. It'll automatically re-orient
* itself as appropriate. Read
* Handling
* Runtime Changes for more information about how to handle configuration
* changes during runtime.
*
*
*
* The screen density of a device is based on the screen resolution. A screen
* with low density has fewer available pixels per inch, where a screen with
* high density has more — sometimes significantly more — pixels per
* inch. The density of a screen is important because, other things being equal,
* a UI element (such as a button) whose height and width are defined in terms
* of screen pixels will appear larger on the lower density screen and smaller
* on the higher density screen. For simplicity, Android collapses all actual
* screen densities into three generalized densities: high, medium, and low.
*
* By default, WebView scales a web page so that it is drawn at a size that
* matches the default appearance on a medium density screen. So, it applies
* 1.5x scaling on a high density screen (because its pixels are smaller) and
* 0.75x scaling on a low density screen (because its pixels are bigger).
* Starting with API level {@link android.os.Build.VERSION_CODES#ECLAIR},
* WebView supports DOM, CSS, and meta tag features to help you (as a web
* developer) target screens with different screen densities.
*
* Here's a summary of the features you can use to handle different screen
* densities:
*
* The {@code hdpi.css} stylesheet is only used for devices with a screen pixel
* ratio of 1.5, which is the high density pixel ratio.
* In order to support inline HTML5 video in your application you need to have
* hardware acceleration turned on.
*
*
* In order to support full screen — for video or other HTML content
* — you need to set a {@link android.webkit.WebChromeClient} and
* implement both
* {@link WebChromeClient#onShowCustomView(View, WebChromeClient.CustomViewCallback)}
* and {@link WebChromeClient#onHideCustomView()}. If the implementation of
* either of these two methods is missing then the web contents will not be
* allowed to enter full screen. Optionally you can implement
* {@link WebChromeClient#getVideoLoadingProgressView()} to customize the View
* displayed whilst a video is loading.
*
*
* For applications targeting Android N and later releases (API level >
* {@link android.os.Build.VERSION_CODES#M}) the geolocation api is only
* supported on secure origins such as https. For such applications requests to
* geolocation api on non-secure origins are automatically denied without
* invoking the corresponding
* {@link WebChromeClient#onGeolocationPermissionsShowPrompt(String, GeolocationPermissions.Callback)}
* method.
*
*
* It is recommended to set the WebView layout height to a fixed value or to
* {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} instead of using
* {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}. When using
* {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} for the height none
* of the WebView's parents should use a
* {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} layout height since
* that could result in incorrect sizing of the views.
*
*
* Setting the WebView's height to
* {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} enables the
* following behaviors:
*
* Using a layout width of
* {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} is not supported. If
* such a width is used the WebView will attempt to use the width of the parent
* instead.
*
*
* WebView may upload anonymous diagnostic data to Google when the user has
* consented. This data helps Google improve WebView. Data is collected on a
* per-app basis for each app which has instantiated a WebView. An individual
* app can opt out of this feature by putting the following tag in its
* manifest's {@code
* Data will only be uploaded for a given app if the user has consented AND the
* app has not opted out.
*
*
* With Safe Browsing, WebView will block malicious URLs and present a warning
* UI to the user to allow them to navigate back safely or proceed to the
* malicious page.
*
* Safe Browsing is enabled by default on devices which support it. If your app
* needs to disable Safe Browsing for all WebViews, it can do so in the
* manifest's {@code
*
*
* Otherwise, see {@link WebSettings#setSafeBrowsingEnabled}.
*
*/
// Implementation notes.
// The WebView is a thin API class that delegates its public API to a backend
// WebViewProvider
// class instance. WebView extends {@link AbsoluteLayout} for backward
// compatibility reasons.
// Methods are delegated to the provider implementation: all public API methods
// introduced in this
// file are fully delegated, whereas public and protected methods from the View
// base classes are
// only delegated where a specific need exists for them to do so.
public class WebView {
/**
* Constructs a new WebView with an Activity Context object.
*
*
* Note: WebView should always be instantiated with an Activity Context.
* If instantiated with an Application Context, WebView will be unable to
* provide several features, such as JavaScript dialogs and autofill.
*
* @param context an Activity Context to access application assets
*/
public WebView(Context context) {
}
/**
* Loads the given URL with the specified additional HTTP headers.
*
* Also see compatibility note on {@link #evaluateJavascript}.
*
* @param url the URL of the resource to load
* @param additionalHttpHeaders the additional headers to be used in the HTTP
* request for this URL, specified as a map from
* name to value. Note that if this map contains
* any of the headers that are set by default by
* this WebView, such as those controlling caching,
* accept types or the User-Agent, their values may
* be overridden by this WebView's defaults.
*/
public void loadUrl(String url, Map
* Also see compatibility note on {@link #evaluateJavascript}.
*
* @param url the URL of the resource to load
*/
public void loadUrl(String url) {
}
/**
* Loads the URL with postData using "POST" method into this WebView. If url is
* not a network URL, it will be loaded with {@link #loadUrl(String)} instead,
* ignoring the postData param.
*
* @param url the URL of the resource to load
* @param postData the data will be passed to "POST" request, which must be be
* "application/x-www-form-urlencoded" encoded.
*/
public void postUrl(String url, byte[] postData) {
}
/**
* Loads the given data into this WebView using a 'data' scheme URL.
*
* Note that JavaScript's same origin policy means that script running in a page
* loaded using this method will be unable to access content loaded using any
* scheme other than 'data', including 'http(s)'. To avoid this restriction, use
* {@link #loadDataWithBaseURL(String,String,String,String,String)
* loadDataWithBaseURL()} with an appropriate base URL.
*
* The {@code encoding} parameter specifies whether the data is base64 or URL
* encoded. If the data is base64 encoded, the value of the encoding parameter
* must be 'base64'. HTML can be encoded with
* {@link android.util.Base64#encodeToString(byte[],int)} like so:
*
*
* For all other values of {@code encoding} (including {@code null}) it is
* assumed that the data uses ASCII encoding for octets inside the range of safe
* URL characters and use the standard %xx hex encoding of URLs for octets
* outside that range. See
* RFC 3986 for
* more information.
*
* The {@code mimeType} parameter specifies the format of the data. If WebView
* can't handle the specified MIME type, it will download the data. If
* {@code null}, defaults to 'text/html'.
*
* The 'data' scheme URL formed by this method uses the default US-ASCII
* charset. If you need to set a different charset, you should form a 'data'
* scheme URL which explicitly specifies a charset parameter in the mediatype
* portion of the URL and call {@link #loadUrl(String)} instead. Note that the
* charset obtained from the mediatype portion of a data URL always overrides
* that specified in the HTML or XML document itself.
*
* Content loaded using this method will have a {@code window.origin} value of
* {@code "null"}. This must not be considered to be a trusted origin by the
* application or by any JavaScript code running inside the WebView (for
* example, event sources in DOM event handlers or web messages), because
* malicious content can also create frames with a null origin. If you need to
* identify the main frame's origin in a trustworthy way, you should use
* {@link #loadDataWithBaseURL(String,String,String,String,String)
* loadDataWithBaseURL()} with a valid HTTP or HTTPS base URL to set the origin.
*
* @param data a String of data in the given encoding
* @param mimeType the MIME type of the data, e.g. 'text/html'.
* @param encoding the encoding of the data
*/
public void loadData(String data, String mimeType, String encoding) {
}
/**
* Loads the given data into this WebView, using baseUrl as the base URL for the
* content. The base URL is used both to resolve relative URLs and when applying
* JavaScript's same origin policy. The historyUrl is used for the history
* entry.
*
* The {@code mimeType} parameter specifies the format of the data. If WebView
* can't handle the specified MIME type, it will download the data. If
* {@code null}, defaults to 'text/html'.
*
* Note that content specified in this way can access local device files (via
* 'file' scheme URLs) only if baseUrl specifies a scheme other than 'http',
* 'https', 'ftp', 'ftps', 'about' or 'javascript'.
*
* If the base URL uses the data scheme, this method is equivalent to calling
* {@link #loadData(String,String,String) loadData()} and the historyUrl is
* ignored, and the data will be treated as part of a data: URL. If the base URL
* uses any other scheme, then the data will be loaded into the WebView as a
* plain string (i.e. not part of a data URL) and any URL-encoded entities in
* the string will not be decoded.
*
* Note that the baseUrl is sent in the 'Referer' HTTP header when requesting
* subresources (images, etc.) of the page loaded using this method.
*
* If a valid HTTP or HTTPS base URL is not specified in {@code baseUrl}, then
* content loaded using this method will have a {@code window.origin} value of
* {@code "null"}. This must not be considered to be a trusted origin by the
* application or by any JavaScript code running inside the WebView (for
* example, event sources in DOM event handlers or web messages), because
* malicious content can also create frames with a null origin. If you need to
* identify the main frame's origin in a trustworthy way, you should use a valid
* HTTP or HTTPS base URL to set the origin.
*
* @param baseUrl the URL to use as the page's base URL. If {@code null}
* defaults to 'about:blank'.
* @param data a String of data in the given encoding
* @param mimeType the MIME type of the data, e.g. 'text/html'.
* @param encoding the encoding of the data
* @param historyUrl the URL to use as the history entry. If {@code null}
* defaults to 'about:blank'. If non-null, this must be a
* valid URL.
*/
public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {
}
/**
* Sets the WebViewClient that will receive various notifications and
* requests. This will replace the current handler.
*
* @param client an implementation of WebViewClient
* @see #getWebViewClient
*/
public void setWebViewClient(WebViewClient client) {
}
/**
* Gets the WebViewClient.
*
* @return the WebViewClient, or a default client if not yet set
* @see #setWebViewClient
*/
public WebViewClient getWebViewClient() {
return null;
}
/**
* Injects the supplied Java object into this WebView. The object is
* injected into the JavaScript context of the main frame, using the
* supplied name. This allows the Java object's methods to be
* accessed from JavaScript. For applications targeted to API
* level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
* and above, only public methods that are annotated with
* {@link android.webkit.JavascriptInterface} can be accessed from JavaScript.
* For applications targeted to API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below,
* all public methods (including the inherited ones) can be accessed, see the
* important security note below for implications.
* Note that injected objects will not appear in JavaScript until the page is next
* (re)loaded. JavaScript should be enabled before injecting the object. For example:
*
* IMPORTANT:
*
* WebView webview = new WebView(this);
* setContentView(webview);
*
*
*
* // Simplest usage: note that an exception will NOT be thrown
* // if there is an error loading this page (see below).
* webview.loadUrl("https://example.com/");
*
* // OR, you can also load from an HTML string:
* String summary = "<html><body>You scored <b>192</b> points.</body></html>";
* webview.loadData(summary, "text/html", null);
* // ... although note that there are restrictions on what this HTML can do.
* // See {@link #loadData(String,String,String)} and {@link
* #loadDataWithBaseURL(String,String,String,String,String)} for more info.
* // Also see {@link #loadData(String,String,String)} for information on encoding special
* // characters.
*
*
*
*
*
*
* // Let's display the progress in the activity title bar, like the
* // browser app does.
* getWindow().requestFeature(Window.FEATURE_PROGRESS);
*
* webview.getSettings().setJavaScriptEnabled(true);
*
* final Activity activity = this;
* webview.setWebChromeClient(new WebChromeClient() {
* public void onProgressChanged(WebView view, int progress) {
* // Activities and WebViews measure progress with different scales.
* // The progress meter will automatically disappear when we reach 100%
* activity.setProgress(progress * 1000);
* }
* });
* webview.setWebViewClient(new WebViewClient() {
* public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
* Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
* }
* });
*
* webview.loadUrl("https://developer.android.com/");
*
*
* Zoom
*
* Cookie and window management
*
* Building web pages to support different screen densities
*
*
*
*
*
* <link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio:1.5)" href="hdpi.css" />
*
* HTML5 Video support
*
* Full screen support
*
* HTML5 Geolocation API support
*
* Layout size
*
*
*
* Metrics
*
*
* <manifest>
* <application>
* ...
* <meta-data android:name="android.webkit.WebView.MetricsOptOut"
* android:value="true" />
* </application>
* </manifest>
*
* Safe Browsing
*
*
* <manifest>
* <application>
* ...
* <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
* android:value="false" />
* </application>
* </manifest>
*
*
*
* String unencodedHtml = "<html><body>'%28' is the code for '('</body></html>";
* String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING);
* webView.loadData(encodedHtml, "text/html", "base64");
*
*
* class JsObject {
* {@literal @}JavascriptInterface
* public String toString() { return "injectedObject"; }
* }
* webview.getSettings().setJavaScriptEnabled(true);
* webView.addJavascriptInterface(new JsObject(), "injectedObject");
* webView.loadData("
*
*
*
* @param object the Java object to inject into this WebView's JavaScript
* context. {@code null} values are ignored.
* @param name the name used to expose the object in JavaScript
*/
public void addJavascriptInterface(Object object, String name) {
}
/**
* Removes a previously injected Java object from this WebView. Note that
* the removal will not be reflected in JavaScript until the page is next
* (re)loaded. See {@link #addJavascriptInterface}.
*
* @param name the name used to expose the object in JavaScript
*/
public void removeJavascriptInterface(String name) {
}
/**
* Gets the WebSettings object used to control the settings for this
* WebView.
*
* @return a WebSettings object that can be used to control this WebView's
* settings
*/
public WebSettings getSettings() {
return null;
}
}