7.5.2 Basic Interaction between WebView and JavaScript
Category Android Basic Tutorial
Introduction to This Section:
>
In the previous section, we studied the WebView (web view) in Android and have likely understood the basic usage of WebView;
In this section, we will learn to complete the interaction between the HTML5 end and the Android phone through: HTML -> JS -> Java. Alright, without further ado, let's see if there is any truth to this by writing code to experience this subtle connection~
PS: For convenience, the HTML used in this section is placed in the assets directory as a file, and can be loaded by simply using loadUrl("file:///android_asset/~").
1. Core Steps Explanation:
Firstly, we define a class to expose data, and JS calls the exposed methods of Android through this class (Public)!
Next, in the Activity where the WebView is located, use the following code: webview.getSettings().setJavaScriptEnabled(true); webview.addJavascriptInterface(object,"name");
Then, in the js or html, call the exposed methods of the object with name.xxx: This is only valid for systems before Android 4.4!!! We will discuss the changes in WebKit after Android 4.4 and the precautions to take in the next section!
2. Example Usage Explanation:
1) HTML displays Toast and a normal list dialog through JS
Running effect picture :
Code implementation :
First, prepare our HTML file and place it in the assets directory after creation:
demo1.html :
<html>
<head>
<title>Js calling Android</title>
</head>
<body>
<input type="button" value="Toast Prompt" onclick="myObj.showToast('Cao Shen comes to visit the dog~');"/>
<input type="button" value="List Dialog" onclick="myObj.showDialog();"/>
</body>
</html>
Customize an Object object, js calls Android through the exposed methods of this class
MyObject.java :
/**
* Created by Jay on 2015/9/11 0011.
*/
public class MyObject {
private Context context;
public MyObject(Context context) {
this.context = context;
}
//Expose the method of displaying Toast and the dialog to the JS script
public void showToast(String name) {
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
}
public void showDialog() {
new AlertDialog.Builder(context)
.setTitle("Contact List").setIcon(R.mipmap.ic_lion_icon)
.setItems(new String[]{"Ji Shen", "B Shen", "Cao Shen", "Jie Shen", "Xiang Shen"}, null)
.setPositiveButton("OK", null).create().show();
}
}
Finally, MainActivity.java, enable JavaScript support, and then expose the object through addJavascriptInterface~
public class MainActivity extends AppCompatActivity {
private WebView wView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wView = (WebView) findViewById(R.id.wView);
wView.loadUrl("file:///android_asset/demo1.html");
WebSettings webSettings = wView.getSettings();
//①Set WebView to allow calling js
webSettings.setJavaScriptEnabled(true);
webSettings.setDefaultTextEncodingName("UTF-8");
//②Expose the object to Js, call addjavascriptInterface
wView.addJavascriptInterface(new MyObject(MainActivity.this), "myObj");
}
}
2) HTML calls three different dialogs through JS
Running effect picture :
Implementation code :
First, put an HTML file into the assets directory: demo2.html :
<html>
<head>
<meta http-equiv = "Content-Type" content="text/html;charset=UTF-8"
<title>Test the three different dialog boxes of Js</title>
<script language="JavaScript">
function alertFun()
{
alert("Alert warning dialog box!");
}
function confirmFun()
{
if(confirm("Visit Baidu?"))
{location.href = "http://www.baidu.com";}
else alert("Cancel the visit!");
}
function promptFun()
{
var word = prompt("Prompt dialog box","Please enter something...:");
if(word)
{
alert("You entered:"+word)
}else{alert("Haha, you didn't write anything!");}
}
</script>
</head>
<body>
<p>The use of three
public boolean onJsConfirm(WebView view, String url, String message,
final JsResult result) {
new Builder(MainActivity.this).setTitle("Confirm Dialog").setMessage(message)
.setPositiveButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
}).setCancelable(false).show();
return true;
}
@Override
public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, final JsPromptResult result) {
//①Obtain a LayoutInflater object factory, load the specified layout into the corresponding object
final LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
final View myview = inflater.inflate(R.layout.prompt_view, null);
//Set the TextView to the prompt message from the web page, and set the EditText to the default text from the web page
((TextView) myview.findViewById(R.id.text)).setText(message);
((EditText) myview.findViewById(R.id.edit)).setText(defaultValue);
//Define the confirm button on the dialog
new Builder(MainActivity.this).setTitle("Prompt Dialog").setView(myview)
.setPositiveButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//After clicking OK, get the entered value and pass it to the web page for processing
String value = ((EditText) myview.findViewById(R.id.edit)).getText().toString();
result.confirm(value);
}
})
.setNegativeButton("Cancel", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
}).show();
return true;
}
}
---
### 3. HTML Accesses Android Contacts via JS and Displays Them
>
This code implements the functionality of reading the contact list from an Android phone via JavaScript and then displaying it in HTML.
When we click on a phone number, it will directly jump to the dial page.
Key to implementation:
Utilize the onload() to load the corresponding JS script when the web page is loaded, and a function defined in the JS script is
to retrieve the passed object, get the data inside, and print it out in a loop in the form of table rows!
**Running effect picture** :
---
Implementation code:
Write a **demo3.html** file in the assets folder, the content is as follows:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Display the Retrieved Contact List</title>
<script language="JavaScript">
function show(jsondata)
{
//Convert the passed Json into an object
var jsonobjs = eval(jsondata);
//Get the table defined below
var table = document.getElementById("PersonTable");
//Iterate over the created Json object above, and add each object as
//a row in the table, with each property as a column
for(var i = 0;i < jsonobjs.length;i++)
{
//Add a row with three cells:
var tr = table.insertRow(table.rows.length);
var td1 = tr.insertCell(0);
var td2 = tr.insertCell(1);
td2.align = "center";
var td3 = tr.insertCell(2);
//Set the content and attributes of the cells
//Where innerHTML is used to set or get the HTML inside the object's start and end tags
//jsonobjs[i] is the i-th object in the object array
td1.innerHTML = jsonobjs[i].id;
td2.innerHTML = jsonobjs[i].name;
//Add a hyperlink to the displayed content, which will call the
//call method in the Java code and pass the content as a parameter
td3.innerHTML = "<a href = 'javascript:sharp.call(\""+jsonobjs[i].phone + "\")'>"
+jsonobjs[i].phone + "</a>";
}
}
</script>
</head>
<!-- onload specifies the method to be called when the page is loaded, which is the contactlist method in the Java code here--> <body style="margin:0px; background-color:#FFFFFF; color:#000000;" onload = "javascript:sharp.contactlist()"> <!--Define a table--> <table border = "0" width = "100%" id = "PersonTable" cellspacing = "0"> <tr> <td width = "15%">User ID</td> <td align = "center">Name</td> <td width = "15 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Set up the WebView settings in order: //Enable JavaScript, do not save form data, do not save passwords, do not support zoom //At the same time, bind the Java object wView = (WebView) findViewById(R.id.wView); wView.getSettings().setJavaScriptEnabled(true); wView.getSettings().setSaveFormData(false); wView.getSettings().setSavePassword(false); wView.getSettings().setSupportZoom(false); wView.getSettings().setDefaultTextEncodingName("UTF-8"); wView.addJavascriptInterface(new SharpJS(), "sharp"); wView.loadUrl("file:///android_asset/demo3.html"); }
//Define a custom JavaScript business class, the object passed to JS is this one, when calling directly javascript:sharp.contactlist() public class SharpJS { public void contactlist() { try { System.out.println("The contactlist() method was executed!"); String json = buildJson(getContacts()); wView.loadUrl("javascript:show('" + json + "')"); } catch (Exception e) { System.out.println("Failed to set data" + e); } }
public void call(String phone) {
System.out.println("The call() method was executed!");
Intent it = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone));
startActivity(it);
}
}
//Write the obtained contact collection into the JsonObject object, and then add it to the JsonArray array public String buildJson(List<Contact> contacts) throws Exception { JSONArray array = new JSONArray(); for (Contact contact : contacts) { JSONObject jsonObject = new JSONObject(); jsonObject.put("id", contact.getId()); jsonObject.put("name", contact.getName()); jsonObject.put("phone", contact.getPhone()); array.put(jsonObject); } return array.toString(); }
//Define a method to obtain contacts, which returns data in the form of List<Contact> public List<Contact> getContacts() { List<Contact> Contacts = new ArrayList<Contact>(); //①Query the raw_contacts table to get the contact id ContentResolver resolver = getContentResolver(); Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; //Query contact data Cursor cursor = resolver.query(uri, null, null, null, null); while (cursor.moveToNext()) { Contact contact = new Contact(); //Get the contact name and mobile number contact.setId(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))); contact.setName(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); contact.setPhone(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); Contacts.add(contact); } cursor.close(); return Contacts; } }
Well, it's that simple, but when you see the effect diagram, I'm using my Lenovo instead of N5, which indicates that the above code cannot be executed on N5, because after 4.4, addJavascriptInterface() is no longer available~ As for why, we will discuss in the next class the precautions of WebView after 4.4~
Code Download:
WebViewDemo4: Download WebViewDemo4.zip
WebViewDemo5: Download WebViewDemo5.zip
Summary of This Section:
>
Well, in this section, we have simply learned about the interaction between WebView and JavaScript, which is quite interesting, right~ If you know HTML + CSS + JS, then you can try to create your own HTML5 mobile APP~ That's all for this section, thanks~
-1.0.1 Latest Android Basic Tutorial Catalog for 2015
-1.1 Background and System Architecture Analysis
-1.2 Development Environment Setup
-1.2.1 Developing Android APP with Eclipse + ADT + SDK
-1.2.2 Developing Android APP with Android Studio
-1.3 Solving SDK Update Issues
-1.4 Genymotion Emulator Installation
-1.5.1 Git Tutorial on Basic Operations of Local Repositories
-[1
4.4.2 Further Exploration of ContentProvider - Document Provider
[5.2.1 In-depth Explanation of Fragment - Implementing a Bottom Navigation Bar
8.3.4 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part 1)
8.3.5 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part 2)
8.3.6 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part 3)
8.3.7 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part 4)
8.3.8 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part 5)
8.3.14 Paint API - Several Enums/Constants and ShadowLayer Shadow Effects
8.3.17 Detailed Explanation of Canvas API (Part 2) - Collection of Clipping Methods
8.3.18 Detailed Explanation of Canvas API (Part 3) - Matrix and drawBitmapMesh
8.4.3 Android Animation Collection - Property Animation - First Encounter
8.4.4 Android Animation Collection - Property Animation - Revisited
[10.11