Applications that retrieve and display content from the Web often end up displaying that
data on the screen. Instead of customizing various screens with custom controls,Android
applications can simply use the WebView control to display web content to the screen.You
can think of the WebView control as a browser-like view.
The WebView control uses the WebKit rendering engine to draw HTML content on
the screen.This content could be HTML pages on the Web or it can be locally sourced.
WebKit is an open source browser engine.You can read more about it on its official website
at http://webkit.org.
Using the WebView control requires the android.permission.INTERNET permission.You
can add this permission to your application's Android manifest file as follows:
<uses-permission android:name="android.permission.INTERNET" />
When deciding if the WebView control is right for your application, consider that you
can always launch the Browser application using an Intent.When you want the user to
have full access to all Browser features, such as bookmarking and browsing, you're better
off launching into the Browser application to a specific website, letting users do their
browsing, and having them return to your application when they're done.You can do this
as follows:
Uri uriUrl = Uri.parse("http://androidbook.blogspot.com/");
Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(launchBrowser);
Launching the Browser via an Intent does not require any special permissions.This means
that your application is not required to have the android.permission.INTERNET permission.
In addition, because Android transitions from your application's current activity to a
specific Browser application's activity, and then returns when the user presses the back key,
the experience is nearly as seamless as implementing your own Activity class with an
embedded WebView.
Loading Content into a WebView Control
You can load content into a WebView control in a variety of ways. For example, a WebView
control can load a specific website or render raw HTML content.Web pages can be stored
on a remote web server or stored on the device.
Here is an example of how to use a WebView control to load content from a specific
website:
final WebView wv = (WebView) findViewById(R.id.web_holder);
wv.loadUrl("http://www.perlgurl.org/");
You do not need to add any additional code to load the referenced web page on the
screen. Similarly, you could load an HTML file called webby.html stored in the application's
assets directory like this:
wv.loadUrl("file:///android_asset/webby.html");
If, instead, you want to render raw HTML, you can use the loadData() method:
String strPageTitle = "The Last Words of Oscar Wilde";
String strPageContent = "<h1>" + strPageTitle +
": </h1>\"Either that wallpaper goes, or I do.\"";
String myHTML = "<html><title>" + strPageTitle
+"</title><body>"+ strPageContent +"</body></html>";
wv.loadData(myHTML, "text/html", "utf-8");
Unfortunately, not all websites are designed for mobile devices. It can be handy to
change the scale of the web content to fit comfortably within the WebView control.You
can achieve this by setting the initial scale of the control, like this:
wv.setInitialScale(30);
The call to the setInitialScale() method scales the view to 30 percent of the original
size. For pages that specify absolute sizes, scaling the view is necessary to see the entire
page on the screen. Some text might become too small to read, though, so you might
need to test and make page design changes (if the web content is under your control) for a
good user experience.
Adding Features to the WebView Control
You might have noticed that the WebView control does not have all the features of a full
browser. For example, it does not display the title of a webpage or provide buttons for reloading
pages. In fact, if the user clicks on a link within the WebView control, that action
does not load the new page within the view. Instead, it fires up the Browser application.
By default, all the WebView control does is display the web content provided by the developer
using its internal rendering engine,WebKit.You can enhance the WebView control
in a variety of ways, though.You can use three classes, in particular, to help modify the behavior
of the control: the WebSettings class, the WebViewClient class, and the
WebChromeClient class.
Modifying WebView Settings with WebSettings
By default, a WebView control has various default settings: no zoom controls, JavaScript
disabled, default font sizes, user-agent string, and so on.You can change the settings of a
WebView control using the getSettings() method.The getSettings() method returns
a WebSettings object that can be used to configure the desired WebView settings. Some
useful settings include
・Enabling and disabling zoom controls using the setSupportZoom() and
setBuiltInZoomControls() methods
・Enabling and disabling JavaScript using the setJavaScriptEnabled() method
・Enabling and disabling mouseovers using the setLightTouchEnabled() method
・Configuring font families, text sizes, and other display characteristics
You can also use the WebSettings class to configure WebView plug-ins and allow for multiple
windows.
Handling WebView Events with WebViewClient
The WebViewClient class enables the application to listen for certain WebView events, such
as when a page is loading, when a form is submitted, and when a new URL is about to be
loaded.You can also use the WebViewClient class to determine and handle any errors that
occur with page loading.You can tie a valid WebViewClient object to a WebView using the
setWebViewClient() method.
The following is an example of how to use WebViewClient to handle the
onPageFinished() method to draw the title of the page on the screen:
WebViewClient webClient = new WebViewClient() {
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String title = wv.getTitle();
pageTitle.setText(title);
}};
wv.setWebViewClient(webClient);
When the page finishes loading, as indicated by the call to onPageFinished(), a call to
the getTitle() method of the WebView object retrieves the title for use.
Adding Browser Chrome with WebChromeClient
You can use the WebChromeClient class in a similar way to the WebViewClient.However,
WebChromeClient is specialized for the sorts of items that will be drawn outside the region
in which the web content is drawn, typically known as browser chrome.The
WebChromeClient class also includes callbacks for certain JavaScript calls, such as
onJsBeforeUnload(), to confirm navigation away from a page.A valid WebChromeClient
object can be tied to a WebView using the setWebChromeClient() method.
The following code demonstrates using WebView features to enable interactivity with
the user.An EditText and a Button control are added below the WebView control, and a
Button handler is implemented as follows:
Button go = (Button) findViewById(R.id.go_button);
go.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
wv.loadUrl(et.getText().toString());
}
});
Calling the loadUrl() method again, as shown, is all that is needed to cause the WebView
control to download another HTML page for display, as shown in Figure 13.3. From here,
you can build a generic web browser in to any application, but you can apply restrictions
so that the user is restricted to browsing relevant materials.
Using WebChromeClient can help add some typical chrome on the screen. For instance,
you can use it to listen for changes to the title of the page, various JavaScript dialogs
that might be requested, and even for developer-oriented pieces, such as the console
messages.
WebChromeClient webChrome = new WebChromeClient() {
@Override
public void onReceivedTitle
(WebView view, String title) {
Log.v(DEBUG_TAG, "Got new title");
super.onReceivedTitle(view, title);
pageTitle.setText(title);
}
};
wv.setWebChromeClient(webChrome);
Here the default WebChromeClient is overridden to receive changes to the title of the
page.This title of the web page is then set to a TextView visible on the screen.
Whether you use WebView to display the main user interface of your application or use
it sparingly to draw such things as help pages, there are circumstances where it might be
the ideal control for the job to save coding time, especially when compared to a custom
screen design. Leveraging the power of the open source engine, WebKit, WebView can provide
a powerful, standards-based HTML viewer for applications. Support for WebKit is
widespread because it is used in various desktop browsers, including Apple Safari and
Google Chrome, a variety of mobile browsers, including those on the Apple iOS, Nokia,
Palm WebOS, and BlackBerry handsets, and various other platforms, such as Adobe AIR.
Building Web Extensions Using WebKit
All HTML rendering on the Android platform is done using the WebKit rendering engine.
The android.webkit package provides a number of APIs for browsing the Internet
using the powerful WebView control.You should be aware of the WebKit interfaces and
classes available, as you are likely to need them to enhance the WebView user experience.
These are not classes and interfaces to the Browser app (although you can interact with
the Browser data using contact providers). Instead, these are the classes and interfaces that
you must use to control the browsing abilities of WebView controls you implement in your
applications.
Browsing the WebKit APIs
Some of the most helpful classes of the android.webkit package are
・The CacheManager class gives you some control over cache items of a WebView.
・The ConsoleMessage class can be used to retrieve JavaScript console output from a
WebView.
・The CookieManager class is used to set and retrieve user cookies for a WebView.
・The URLUtil class is handy for validating web addresses of different types.
・The WebBackForwardList and WebHistoryItem classes can be used to inspect the
web history of the WebView.
Now let's take a quick look at how you might use some of these classes to enhance a
WebView.
Extending Web Application Functionality to Android
Let's take some of the WebKit features we have discussed so far in this chapter and work
through an example. It is fairly common for mobile developers to design their applications
as web applications in order to reach users across a variety of platforms.This minimizes
the amount of platform-specific code to develop and maintain. However, on its own, a
web application cannot call into native platform code and take advantage of the features
that native apps (such as those written in Java for the Android platform) can, such as using
a built-in camera or accessing some other underlying Android feature.
Developers can enhance web applications by designing a lightweight shell application
in Java and using a WebView control as a portal to the web application content.Two-way
communication between the web application and the native Java application is possible
through scripting languages such as JavaScript.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final WebView wv = (WebView) findViewById(R.id.html_viewer);
WebSettings settings = wv.getSettings();
settings.setJavaScriptEnabled(true);
WebChromeClient webChrome = new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.v(DEBUG_TAG, consoleMessage.lineNumber()
+ ": " + consoleMessage.message());
return true;
}
};
wv.setWebChromeClient(webChrome);
wv.addJavascriptInterface(new JavaScriptExtensions(), "jse");
wv.loadUrl("file:///android_asset/sample.html");
A custom WebChromeClient class is set so that any JavaScript console.log messages go
out to LogCat output, using a custom debug tag as usual to enable easy tracking of log
output specific to the application. Next, a new JavaScript interface is defined with the
namespace called jse?the namespace is up to you.To call from JavaScript to this Java
class, the JavaScript calls must all start with namespace jse., followed by the appropriate
exposed method?for instance, jse.javaMethod().
You can define the JavaScriptExtensions class as a subclass within the activity as a
subclass with a single method that can trigger Android Toast messages:
class JavaScriptExtensions {
public static final int TOAST_LONG = Toast.LENGTH_LONG;
public static final int TOAST_SHORT = Toast.LENGTH_SHORT;
public void toast(String message, int length) {
Toast.makeText(SimpleWebExtension.this, message, length).show();
}
}
The JavaScript code has access to everything in the JavaScriptExtensions class, including
the member variables as well as the methods. Return values work as expected from
the methods, too.
Now switch your attention to defining the web page to load in the WebView control.
For this example, simply create a file called sample.html in the /assets directory of the application.
The contents of the sample.html file are shown here:
<html>
<head>
<script type="text/javascript">
function doToast() {
jse.toast("'"+document.getElementById('form_text').value +
"' -From Java!", jse.TOAST_LONG);
}
function doConsoleLog() {
console.log("Console logging.");
}
function doAlert() {
alert("This is an alert.");
}
function doSetFormText(update) {
document.getElementById('form_text').value = update;
}
</script>
</head>
<body>
<h2>This is a test.</h2>
<input type="text" id="form_text" value="Enter something here..." />
<input type="button" value="Toast" onclick="doToast();" /><br />
<input type="button" value="Log" onclick="doConsoleLog();" /><br />
<input type="button" value="Alert" onclick="doAlert();" />
</body>
</html>
The sample.html file defines four JavaScript functions and displays the form shown within
the WebView:
・The doToast() function calls into the Android application using the jse object defined
earlier with the call to the addJavaScriptInterface() method.The
addJavaScriptInterface() method, for all practical intents and purposes, can be
treated literally as the JavaScriptExtensions class as if that class had been written
in JavaScript. If the doToast() function had returned a value,we could assign it to a
variable here.
・The doConsoleLog() function writes into the JavaScript console log, which is
picked up by the onConsoleMessage() callback of the WebChromeClient.
・The doAlert() function illustrates how alerts work within the WebView control by
launching a dialog. If you want to override what the alert looks like, you can override
the WebChromeClient.onJSAlert() method.
・The doSetFormText() function illustrates how native Java code can communicate
back through the JavaScript interface and provide data to the web application.
Finally, to demonstrate making a call from Java back to JavaScript, you need to define the
click handler for the Button control within your Activity class. Here, the onClick handler,
called setHTMLText(), executes some JavaScript on the currently loaded page by
calling a JavaScript function called doSetFormText(), which we defined earlier in the web
page. Here is an implementation of the setHTMLText() method:
public void setHTMLText(View view) {
WebView wv = (WebView) findViewById(R.id.html_viewer);
wv.loadUrl("javascript:doSetFormText('Java->JS call');");
This method of making a call to the JavaScript on the currently loaded page does not allow
for return values.There are ways, however, to structure your design to allow checking
of results, generally by treating the call as asynchronous and implementing another
method for determining the response.
This style of development has been popularized by the open source PhoneGap project,
which aims to provide a set of standard JavaScript interfaces to native code across a variety
of platforms, including iOS,Android, BlackBerry, Symbian, and Palm. Learn more about
PhoneGap at http://phonegap.com.
0 件のコメント:
コメントを投稿