Passing data from Activity to the JavaScript used in the HTML file loaded at webView in the same activity
After reading this and this and this, I found my case can be summarized in the below point:
- Passing variable from class to another in Android App (i.e. Java Classes)
- Calling Android function from JavaScript in the HTML file loaded at the WebView
- Sending a parameter back from Android Class to the JavaScript
So, the solution can be summarized in the below:
- Create
JavaScriptInterface
class that can interact with JavaScript commands - Use the
@JavascriptInterface
annotation before each function required to interact with the JavaScript - Define the name of the JavaScript interaction to be used as
module
in the JavaScript file as:myWebView.addJavascriptInterface(new JavaScriptInterface(this), "module");
in this statement, themodule
is the name module to be called in the javaScript file asmodule.function()
- Use
getter
andsetter
to communicate between Android classes.
My MainActivity.java
file became like this:
package com.fonix.qr;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements OnClickListener {
private Button scanBtn;
private TextView formatTxt, contentTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scanBtn = (Button) findViewById(R.id.scan_button);
formatTxt = (TextView) findViewById(R.id.scan_format);
contentTxt = (TextView) findViewById(R.id.scan_content);
scanBtn.setOnClickListener(this);
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
myWebView.addJavascriptInterface(new JavaScriptInterface(this), "fonix");
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("file:///android_asset/index.html");
}
public void onClick(View v) {
if (v.getId() == R.id.scan_button) {
scanCode();
// IntentIntegrator scanIntegrator = new IntentIntegrator(this);
// scanIntegrator.initiateScan();
}
}
public void scanCode(){
IntentIntegrator scanIntegrator = new IntentIntegrator(this);
scanIntegrator.initiateScan();
}
public String scanContent;
public String scanFormat;
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanningResult != null) {
scanContent = scanningResult.getContents();
scanFormat = scanningResult.getFormatName();
formatTxt.setText("FORMAT: " + scanFormat);
contentTxt.setText("CONTENT: " + scanContent);
} else {
Toast toast = Toast.makeText(getApplicationContext(),
"No scan data received!", Toast.LENGTH_SHORT);
toast.show();
}
}
public String getContent(){ return scanContent; }
public class JavaScriptInterface {
Context mContext;
/* Instantiate the interface and set the context */
JavaScriptInterface(Context c) {
mContext = c;
}
/* Show a toast from the web page */
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void scanJS() {
scanCode();
}
@JavascriptInterface
public String scanResult() {
return getContent();
}
}
}
and the assets -> index.html
file is:
<!DOCTYPE html>
<html>
<head>
<title>QR and BarCode Scanner using both Android Native and JavaScript Functionality</title>
</head>
<body>
Hello Android! <br/>
<br/>
The above button in Native Android, while the below one is JavaScript button. <br/>
<br/>
<input type="button" value="Scan from JavaScript button" onClick="scan()" />
<br/>
<br/>
<br/>
Below button will show the latest scan result, regardless read through Native Android button, or JavaScript button, and will display the result as Native Android Toast.
<br/>
<br/>
<input type="button" value="Show Scan result" onClick="showScanResult()" />
</body>
<script type="text/javascript">
function scan() {
fonix.scanJS();
}
function showScanResult() {
var scanResult = fonix.scanResult();
// (!scanResult) equal === null or === undefined
if(!scanResult)fonix.showToast("Nothing had been scanned");
else fonix.showToast(fonix.scanResult());
}
</script>
</html>
The layout -> activity_main.xml
file is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.fonix.qr.MainActivity">
<Button android:id="@+id/scan_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/scan"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<TextView
android:id="@+id/scan_format"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:layout_below="@id/scan_button"
android:layout_alignEnd="@+id/scan_button" />
<TextView
android:id="@+id/scan_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:layout_below="@+id/scan_format"
android:layout_alignEnd="@+id/webview" />
<WebView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/webview"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/scan_content" />
</RelativeLayout>
The values -> strings.xml
file is:
<resources>
<string name="app_name">QR and BarCode reader</string>
<string name="scan">Scan from Native Android button</string>
</resources>
The AndroidManifest.xml
file is:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fonix.qr">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
The Final App app structure is:
and when reading .
Passing data to local html file in android webView
Simple solution
- use Query when
loadUrl()
- get
document.location.href
inscript
- deal with your data
- decode string, split, etc
example
If data is json
android
val json = JsonObject().apply {
addProperty("age","28")
addProperty("name","john")
addProperty("contents","test")
}
val url = "file:///android_asset/test.html?$json"
binding.webView.loadUrl(url)
local .html
<!DOCTYPE html>
<html>
<body>
<H1>test</H1>
<oi id="list">
</oi>
<script type="text/javascript">
function makeList() {
const getOiTag = document.getElementById("list");
const decodeUrl = decodeURI(document.location.href);
const jsonStr = decodeUrl.split("?")[1];
const json = JSON.parse(jsonStr);
for(i in json){
const li = document.createElement("li")
li.textContent = i + " : " + json[i];
getOiTag.appendChild(li);
}
}
makeList()
</script>
</body>
</html>
How to pass Data From Javascript To Android WebView in this case?
You should use something like this:
<select name="colors"
onChange="Question.OnJsClick_SelectedItem(this.options[this.selectedIndex].text)">
Pass variable from Android to JavaScript launched in WebView
First of all you need to load the script only once (your onClick
is loading it every time), then call loadUrl("javascript:initialize(" + myNumber + ");")
how to pass a string value to webView from an activity
Depending on your use case, there are different ways of accomplishing this. The difficulty lies in that you want to do things in the onload method.
If it is possible to pass in the string after the page is loaded, you could use
String jsString = "javascript:addData('" + theString + "');");
webView.loadUrl(jsString);
if you really need the data accessible on the onload method of the page, you could modify the url called to to include query data if possible. Something like:
String urlWithData = yourUrl + "?data=" + theString;
webView.loadUrl(urlWithData);
and then use standard javascript to parse window.location.search to get the data.
Finally, if you can't modify the URL for some reason, you can use a callback object to let the javascript get the value:
private class StringGetter {
public String getString() {
return "some string";
}
}
and then when config your webView with this callback before loading the url:
webView.addJavascriptInterface(new StringGetter(), "stringGetter");
and in the onload method of the page you could use:
var theString = stringGetter.getString();
Hope this helps!
How to pass a value/variable from an android java class to javascript/.html file in android 4.4.2 kitkat
Have you seen this http://developer.android.com/guide/webapps/webview.html? You are interested in Binding JavaScript code to Android code section. First declare interface, then implement the method that will return your integer. Then inside your JS
code call this method to get the value.
EDIT
Interface for working with JS:
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Get the value */
@JavascriptInterface
public int getValue() {
return value
}
}
Add this interface to your WebView
:
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Inside your JS code:
var value = Android.getValue();
Pass JavaScript Value from Webview to Activity?Android
HTML JS CODE
<script type="text/javascript">
function Pa(value) {
//value is the param received from onClick
NewFUN.Print(value); //call the android method with value param
}
</script>
<center>
<h3>Sample HTML</h3>
<div id="content">Click on Button To thermal print</div>
<div>
<input type="button" onClick="Pa('26997')" /><br/>
</div>
</center>
& change your android code to be like this
@JavascriptInterface
public void Print(final String stringFromWebView) {
//use stringFromWebView
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("Alert");
alertDialog.setMessage("Are you sure you want to leave to next screen?");
alertDialog.setPositiveButton("YES",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent chnIntent = new Intent(Main_web.this, Print_activity.class);
chnIntent.putExtra("STRING_DATA", stringFromWebView);
startActivity(chnIntent);
}
});
alertDialog.setNegativeButton("NO",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
In next activity receive the web JS response by using
String data = getIntent().getStringExtra("STRING_DATA");
at oncreate
Related Topics
Export a Python Script to an Android Executable (.Apk) with Python-For-Android
Gradle - Library Duplicates in Dependencies
What Proguard Configuration Do I Need for Firebase on Android
How to Copy Text Programmatically in My Android App
Android - How to Unregister a Receiver Created in the Manifest
Adjustpan Not Preventing Keyboard from Covering Edittext
Display the Current Time and Date in an Android Application
How to Apply a Style to All Buttons of an Android Application
Android Drawable Images from Url
Difficulties with Calling an Android Ndk Function from Directly Delphi
Jelly Bean Datepickerdialog --- How to Cancel
Loading Existing .HTML File with Android Webview
Adt Will Not Allow Creation of Android Activity
Round Corner for Bottomsheetdialogfragment
How to Check If an Activity Is the Last One in the Activity Stack for an Application
Google Speech Recognition Timeout
Java.Lang.Illegalargumentexception: View Not Attached to Window Manager