Passing Data from Java Class to Web View HTML

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:

  1. Passing variable from class to another in Android App (i.e. Java Classes)
  2. Calling Android function from JavaScript in the HTML file loaded at the WebView
  3. Sending a parameter back from Android Class to the JavaScript

So, the solution can be summarized in the below:

  1. Create JavaScriptInterface class that can interact with JavaScript commands
  2. Use the @JavascriptInterface annotation before each function required to interact with the JavaScript
  3. 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, the module is the name module to be called in the javaScript file as module.function()
  4. Use getter and setter 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:
Sample Image

and when reading This QR code.

Passing data to local html file in android webView


Simple solution

  1. use Query when loadUrl()
  2. get document.location.href in script
  3. 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>

Sample Image

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



Leave a reply



Submit