将数据从Activity传递到在同一活动中的webView中加载的HTML文件中使用的JavaScript(Passing data from Activity to the JavaScript u

编程入门 行业动态 更新时间:2024-10-23 13:23:23
将数据从Activity传递到在同一活动中的webView中加载的HTML文件中使用的JavaScript(Passing data from Activity to the JavaScript used in the HTML file loaded at webView in the same activity)

我的Android应用程序目标是扫描条形码/ QR码并将其传递给webView元素加载的HTML文件。

该应用程序只有一个布局,包含一个按钮和webview元素。 单击按钮后,应用程序打开条形码/ QR扫描仪并将结果返回到活动,我需要将此结果传递给我的HTML文件以进行进一步处理。

MainActivity正常工作,如本教程中所示,并返回结果:

public void onActivityResult(int requestCode, int resultCode, Intent intent) { IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanningResult != null) { String scanContent = scanningResult.getContents(); String scanFormat = scanningResult.getFormatName(); formatTxt.setText("FORMAT: " + scanFormat); contentTxt.setText("CONTENT: " + scanContent); /*** I NEED to SEND the 'scanContent' to the my HTML file loaded at the WebView element ***/ } else{ Toast toast = Toast.makeText(getApplicationContext(), "No scan data received!", Toast.LENGTH_SHORT); toast.show(); } }

我读了这个和这个以及本和这个 ,并得到以下文件:

JavaScriptInterface.java

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(); }

}

和WebViewActivity.java:

public class WebViewActivity extends Activity { // private WebView webView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WebView webView = (WebView)findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new JavaScriptInterface(this), "Android"); /*** I think something wrong in this area **/ webView.loadUrl("file:///android_asset/myFile.html"); webView.setWebViewClient(new WebViewClient(){ public void onPageFinished(WebView view, String url){ view.loadUrl("javascript:init('" + url + "')"); } }); //webView.loadUrl("http://www.google.com"); // String customHtml = "<html><body>" + // ""+ // "</body></html>"; // webView.loadData(customHtml, "text/html", "UTF-8"); }

}

Android Studio IDE中没有出现任何错误,并且在运行应用程序时,按钮用于扫描工作,但webview中没有任何内容,只有白页! 白页始终,从启动起,并扫描代码后!

知道我迷路的地方,以及如何解决它!

注意我需要将数据发送到同一活动中webView上加载的HTML文件中使用的JavaScript,而不仅仅是发送要加载的URL。

My Android app objective is to scan a bar/QR code and pass it to the HTML file loaded at webView element.

The app has ONE layout only, that contain a button and the webview element. Once the button is clicked, the app open the bar/QR scanner and return the result to the activity, and I need to pass this result to my HTML file for further processing.

The MainActivity is working correctly, as in this tutorial, and return the result here:

public void onActivityResult(int requestCode, int resultCode, Intent intent) { IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanningResult != null) { String scanContent = scanningResult.getContents(); String scanFormat = scanningResult.getFormatName(); formatTxt.setText("FORMAT: " + scanFormat); contentTxt.setText("CONTENT: " + scanContent); /*** I NEED to SEND the 'scanContent' to the my HTML file loaded at the WebView element ***/ } else{ Toast toast = Toast.makeText(getApplicationContext(), "No scan data received!", Toast.LENGTH_SHORT); toast.show(); } }

I read this and this and this and this and thisand got the below below files:

JavaScriptInterface.java

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(); }

}

and the WebViewActivity.java:

public class WebViewActivity extends Activity { // private WebView webView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WebView webView = (WebView)findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new JavaScriptInterface(this), "Android"); /*** I think something wrong in this area **/ webView.loadUrl("file:///android_asset/myFile.html"); webView.setWebViewClient(new WebViewClient(){ public void onPageFinished(WebView view, String url){ view.loadUrl("javascript:init('" + url + "')"); } }); //webView.loadUrl("http://www.google.com"); // String customHtml = "<html><body>" + // ""+ // "</body></html>"; // webView.loadData(customHtml, "text/html", "UTF-8"); }

}

No errors appeared in the Android Studio IDE, and when running the app the button for scanning work, but nothing appear in the webview, only white page!! white page always, from the start up of the up, and after scanning the code!

Any idea where I got lost, and how to fix it!

Note I need to send the data to the JavaScript used in the HTML file loaded at webView in the same activity, not just sending URL to be loaded.

最满意答案

在阅读了这篇文章之后,我发现我的案例可归纳如下:

在Android App中将变量从类传递到另一个(即Java类) 在WebView加载的HTML文件中从JavaScript调用Android函数 将参数从Android类发送回JavaScript

因此,解决方案可归纳如下:

创建可以与JavaScript命令交互的JavaScriptInterface类 在与JavaScript交互所需的每个函数之前使用@JavascriptInterface批注 在JavaScript文件中定义要用作module的JavaScript交互的名称: myWebView.addJavascriptInterface(new JavaScriptInterface(this), "module"); 在此语句中, module是要在javaScript文件中作为module.function()调用的名称模块 使用getter和setter在Android类之间进行通信。

我的MainActivity.java文件变成这样:

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(); } } }

和assets -> index.html文件是:

<!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>

layout -> activity_main.xml文件是:

<?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>

values -> strings.xml文件是:

<resources> <string name="app_name">QR and BarCode reader</string> <string name="scan">Scan from Native Android button</string> </resources>

AndroidManifest.xml文件是:

<?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>

Final App应用程序结构是: 在此处输入图像描述

并在阅读时 这个二维码

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, the module is the name module to be called in the javaScript file as module.function() 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: enter image description here

and when reading This QR code.

更多推荐

本文发布于:2023-08-06 23:33:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1457553.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:加载   文件   活动中   数据   在同一

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!