> Please note, that the url is file:///android_asset and not file:///android_assets. This is one of the most common mistakes made by developers during development.
// load index.html from the assets folder
WebView
.
loadUrl
(
"file:///android_asset/index.html"
);
// load logo.png from the res folder
WebView
.
loadUrl
(
"file:///android_res/drawable/logo.png"
);
// load a web based URL, Oreilly's homepage in this case
WebView
.
loadUrl
(
"http://www.oreilly.com"
);
> For all other values of the parameter, including null, it is assumed that the data uses ASCII encoding for octets inside the range of safe URL characters.
String
data
=
"<!DOCTYPE html>"
;
data
+=
"<head><title>Hello World</title></head>"
;
data
+=
"<body>Welcome to the WebView</body>"
;
data
+=
"</html>"
;
// args: data, mimeType, encoding
WebView
.
loadData
(
data
,
"text/html"
,
"UTF-8"
);
This code will not load the logo.png image, as JavaScript’s same origin policy restricts all the resources on the web page to originate from the same site—in this case, data:[<MIME-type>]
and not file:///, as we have requested.
To avoid this restriction, Google recommends using loadDataWithBaseURL()
with an appropriate base URL, which is used both to resolve relative URLs and when applying JavaScript’s same origin policy.
> Android’s WebView is extensible and implements a number of delegatory classes including WebViewClient and WebChromeClient, which can be used by developers to customize the default behavior of WebView and inject data in the request/response call flows.
// Load an html file
String
html
=
loadFileFromSDCard
(
"file:///sdcard/oreilly/book/logo.png"
);
WebView
.
loadDataWithBaseURL
(
""
,
html
,
"text/html"
,
"UTF-8"
,
null
);
or:
// Load an image file
String
pngData
=
loadFileFromAssets
(
"file:///android_asset/images/logo.png"
);
WebView
.
loadData
(
pngData
,
"image/png"
,
"UTF-8"
);
>
Load Flash Files into the WebView
In order to load flash files from SDCard into the view, you can link your flash files in the embed tag using file:/// protocol.
<!-- flash.html -->
<html>
<head>
<title>
Playing Flash movie</title>
</head>
<body>
<object
width=
"200"
height=
"200"
>
<param
name=
"movie"
value=
"hybrid.swf"
>
<embed
src=
"file:///sdcard/hybrid.swf"
width=
"200"
height=
"200"
></embed>
</object>
</body>
</html>
Then, you need to load your flash.html file from SDCard using the loadUrl()
method.
String
base
=
Environment
.
getExternalStorageDirectory
().
getAbsolutePath
().
toString
();
String
html
=
"file://"
+
base
+
"/flash.html"
;
if
(
Environment
.
getExternalStorageState
().
equals
(
Environment
.
MEDIA_MOUNTED
))
{
WebView
.
loadUrl
(
html
);
}
Reading Files from the res/raw Directory
If you need to read a file (e.g., home.html) from the res/raw directory and display it in the WebView, you need to pass the resource ID (e.g., R.raw.home) to your reader function in order to get it as string.
WebView
.
loadData
(
getRawFileFromResource
(
R
.
raw
.
home
),
"text/html"
,
"UTF-8"
);
private
String
getRawFileFromResource
(
int
resourceId
)
{
StringBuilder
sb
=
new
StringBuilder
();
Scanner
s
=
new
Scanner
(
getResources
().
openRawResource
(
resourceId
));
while
(
s
.
hasNextLine
())
{
sb
.
append
(
s
.
nextLine
()
+
"\n"
);
}
return
sb
.
toString
();
}
The JavaScript protocol is of special interest to us for this topic. The syntax for the JavaScript protocol is JavaScript:sScript
.
》 From the JavaScript layer, all the public methods of the exposed Java objects can be accessed in Android versions below Jelly Bean MR1 (API Level - 17). For Jelly Bean MR1 API Level and above, exposed functions should specifically be annotated with @JavaScriptInterface
to prevent any unwanted methods from being exposed.
》 An HttpOnly
flagged cookie cannot be stolen easily via non-HTTP methods, such as JavaScript or Flash using document.cookie
as a pervasive attack technique.
Here’s an example of how the HttpOnly
attribute is visible in the HTTP headers:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: id=cdb6352b48e62e0691efe552e3e4cecb; path=/; HttpOnly
If you use the SSL protocol for delivering your web content and need to set cookies using JavaScript, then you need to enable the secure
flag in your cookie function in order to set a secure cookie.
document.cookie = "name=value; expires=date; path=path; domain=domain; secure";
》
For security reasons, if your app does not require access to the filesystem, it is a good practice to turn this setting off.
settings
.
setAllowFileAccess
(
false
);
You can enable/disable JavaScript using setJavaScriptEnabled()
method.
settings
.
setJavaScriptEnabled
(
true
);
if you are not using a Flash plug-in, turn it off using thesetPluginState(PluginState.OFF)
method, which may prevent attackers from compromising your app via third-party plug-ins.
WebView
WebView
=
new
WebView
(
this
);
WebSettings
settings
=
WebView
.
getSettings
();
settings
.
setDefaultFontSize
(
20
);
settings
.
setPluginState
(
PluginState
.
OFF
);
settings
.
setBuiltInZoomControls
(
false
);
settings
.
setDefaultZoom
(
ZoomDensity
.
FAR
);
settings
.
setSupportZoom
(
false
);
If you wish to enable hardware acceleration in your application or activity, you can setandroid:handwareAccelerated="true"
in your manifest.
// enable hardware acceleration using code (>= level 11)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
HONEYCOMB
)
{
WebView
.
setLayerType
(
View
.
LAYER_TYPE_HARDWARE
,
null
);
}
settings
.
setRenderPriority
(
WebSettings
.
RenderPriority
.
HIGH
);
settings
.
setCacheMode
(
WebSettings
.
LOAD_NO_CACHE
);