[英]I am getting "Uncaught ReferenceError: globalThis is not defined" HTML5-qrcode scanner in Android WebView, Works perfect on chrome and Web Browsers
I have a web app ( https://salon.techwithin.in ) that will be used on both Browsers and Android apps.我有一个 web 应用程序 ( https://salon.techwithin.in ) 将在浏览器和 Android 应用程序上使用。
Sample QR Code for my app https://i.postimg.cc/Fsm9bKwT/sample-qr-scan.jpg
我的应用程序的示例二维码https://i.postimg.cc/Fsm9bKwT/sample-qr-scan.jpg
To convert this web app to Android App I have created a simple Android application with WebView要将此 web 应用程序转换为 Android 应用程序,我创建了一个简单的 Android 应用程序,其中包含 WebView
public class MainActivity extends AppCompatActivity {
private WebView mywebView;
private String userAgent;
private static final int PERMISSION_REQUEST_CODE = 200;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (checkPermission()) {
} else {
requestPermission();
}
setContentView(R.layout.activity_main);
mywebView=findViewById(R.id.webview);
mywebView.setWebViewClient(new mywebClient());
// TO TEST ON DEVELOPERS DEMO PORTAL I USED THEIR PAGE TO LOAD IN WEBVIEW, BUT SAME ERROR ON THAT PAGE TOO.
//mywebView.loadUrl("https://blog.minhazav.dev/research/html5-qrcode.html");
mywebView.loadUrl("https://salon.techwithin.in");
WebSettings webSettings=mywebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setPluginState(WebSettings.PluginState.ON);
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
webSettings.setLoadWithOverviewMode(false);
webSettings.setAllowFileAccess(true);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(false);
webSettings.setSupportMultipleWindows(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
CookieManager.getInstance().setAcceptCookie(true);
//userAgent = System.getProperty("http.agent");
//webSettings.setUserAgentString(webSettings.getUserAgentString().replace("; wv",""));
mywebView.setWebChromeClient(new WebChromeClient(){
@Override
public void onPermissionRequest(final PermissionRequest request) {
request.grant(request.getResources());
}
});
}
I am getting the following error in logcat, and the QR scanner area remains blank.我在 logcat 中收到以下错误,QR 扫描仪区域保持空白。
2022-09-06 09:05:44.877 2932-2932/in.techwithin.thesalonman I/chromium: [INFO:CONSOLE(2)] "Uncaught ReferenceError: globalThis is not defined", source: https://blog.minhazav.dev/assets/research/html5qrcode/html5-qrcode.min.js (2) 2022-09-06 09:05:44.894 2932-2932/in.techwithin.thesalonman I/Choreographer: Skipped 33 frames.
2022-09-06 09:05:44.877 2932-2932/in.techwithin.thesalonman I/chromium: [INFO:CONSOLE(2)] “Uncaught ReferenceError: globalThis is not defined”,来源: https://blog.minhazav .dev/assets/research/html5qrcode/html5-qrcode.min.js (2) 2022-09-06 09:05:44.894 2932-2932/in.techwithin.thesalonman I/Choreographer:跳过 33 帧。 The application may be doing too much work on its main thread: 2022-09-06 09:05.44.975 2932-2932/in.techwithin:thesalonman I/chromium: [INFO:CONSOLE(432)] "Uncaught TypeError, Html5QrcodeScanner is not a constructor": source: https://blog.minhazav.dev/research/html5-qrcode.html (432)
应用程序可能在其主线程上做了太多工作:2022-09-06 09:05.44.975 2932-2932/in.techwithin:thesalonman I/chromium: [INFO:CONSOLE(432)] “Uncaught TypeError, Html5QrcodeScanner is不是构造函数”:来源: https://blog.minhazav.dev/research/html5-qrcode.html (432)
Current Plugin Used to scan qr codes in my web app当前插件用于扫描我的 web 应用程序中的二维码
https://github.com/mebjas/html5-qrcode
https://github.com/mebjas/html5-qrcode
I have tried using the developer's Html5-qrcode demo page in webview which throws the same error.我曾尝试使用开发人员在 webview 中的 Html5-qrcode 演示页面,它会引发相同的错误。 (Check the comments in code sample)
(查看代码示例中的注释)
The android app is requesting CAMERA Access properly, To test the camera working I have tested another plugins demo web page android 应用程序正确请求 CAMERA 访问,为了测试相机工作,我测试了另一个插件演示 web 页面
https://nimiq.github.io/qr-scanner/demo/
https://nimiq.github.io/qr-scanner/demo/
It opens the camera and scans QR codes properly,它打开相机并正确扫描二维码,
But for now, I won't be able to switch to this working plugin in my web app, hence I need a solution with a current plugin (html5-qrcode) only.但是现在,我无法在我的 web 应用程序中切换到这个工作插件,因此我只需要一个带有当前插件 (html5-qrcode) 的解决方案。 My current web app is built in Core PHP and Used html5-qrcode plugin directly in browser without any loader
<script src="https://unpkg.com/html5-qrcode" type="text/javascript">
我当前的 web 应用程序内置于核心 PHP 中,直接在浏览器中使用 html5-qrcode 插件,无需任何加载器
<script src="https://unpkg.com/html5-qrcode" type="text/javascript">
I am new to android app development hence any help will be appreciated.我是 android 应用程序开发的新手,因此我们将不胜感激。
I am new to android app too.我也是 android 应用程序的新手。
Based on your code and this answer of this comment html5-qrcode
plugin works in my WebView.根据您的代码和此评论的回答,
html5-qrcode
插件适用于我的 WebView。
Here is the code这是代码
AndroidManifest.xml AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<meta-data android:name="com.onesignal.suppressLaunchURLs" android:value="true"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
<uses-permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_stat_onesignal_default"
android:label="PRONOMIO"
android:roundIcon="@mipmap/ic_stat_onesignal_default_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:usesCleartextTraffic="true"
android:background="@android:color/black"
android:name=".PronomioTitanApplicationClass">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" />
</application>
</manifest>
MainActivity.java MainActivity.java
package com.test.myapp;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.util.Log;
import android.view.Window;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.widget.Toast;
import com.test.myapp.databinding.ActivityMainBinding;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.annotation.Target;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.WindowCompat;
public class MainActivity extends AppCompatActivity {
private WebView myapp;
Context context;
ActivityMainBinding binding;
private int currentApiVersion;
@Override
protected void onResume() {
super.onResume();
checkCameraPermission();
}
private void checkCameraPermission() {
int writeExternalStorage = ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA);
if (writeExternalStorage != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 1001);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1001) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Do your stuff
//openWebView();
} else {
checkCameraPermissionAndStartWebView();
}
}
}
private void checkCameraPermissionAndStartWebView() {
int writeExternalStorage = ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA);
if (writeExternalStorage != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 1001);
} else {
//openWebView();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
currentApiVersion = android.os.Build.VERSION.SDK_INT;
final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
if (currentApiVersion >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setSystemUiVisibility(flags);
final View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
decorView.setSystemUiVisibility(flags);
}
}
});
}
myapp = (WebView) findViewById(R.id.myapp);
myapp.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
myapp.loadUrl("file:///android_asset/error-page.html");
}
});
if(haveNetworkConnection()) {
myapp.getSettings().setMediaPlaybackRequiresUserGesture(true);
myapp.getSettings().setSupportZoom(true);
myapp.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
myapp.getSettings().setJavaScriptEnabled(true);
myapp.getSettings().setAllowFileAccessFromFileURLs(true);
myapp.getSettings().setAllowUniversalAccessFromFileURLs(true);
myapp.getSettings().setPluginState(WebSettings.PluginState.ON);
myapp.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
myapp.getSettings().setLoadWithOverviewMode(false);
myapp.getSettings().setAllowFileAccess(true);
myapp.getSettings().setBuiltInZoomControls(false);
myapp.getSettings().setSupportMultipleWindows(true);
myapp.setWebChromeClient(new WebChromeClient(){
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//Required functionality here
return super.onJsAlert(view, url, message, result);
}
@Override
public void onPermissionRequest(final PermissionRequest request) {
request.grant(request.getResources());
}
});
myapp.loadUrl("https://webview.example.com/");
} else {
myapp.loadUrl("file:///android_asset/error-page.html");
}
myapp.getSettings().setDomStorageEnabled(true);
myapp.getSettings().setJavaScriptEnabled(true);
}
public void onPermissionRequest(final PermissionRequest request) {
final String[] requestedResources = request.getResources();
for (String r : requestedResources) {
if (r.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
request.grant(new String[]{PermissionRequest.RESOURCE_VIDEO_CAPTURE});
break;
}
}
}
@SuppressLint("NewApi")
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (currentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
private boolean haveNetworkConnection() {
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedWifi || haveConnectedMobile;
}
}
And in website i have in <head></head>
在我的网站中
<head></head>
<script src="https://github.com/mebjas/html5-qrcode" id="scan-qr-js"></script>
In <body></body>
在
<body></body>
<div class="SCAN-QR-READER-AREA">
<div id="qr-reader"></div>
<div id="qr-reader-results"></div>
</div>
<script>
function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete"
|| document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
docReady(function () {
var resultContainer = document.getElementById("qr-reader-results");
var lastResult, countResults = 0;
function onScanSuccess(decodedText, decodedResult) {
if (decodedText !== lastResult) {
++countResults;
//lastResult = decodedText;
// Handle on success condition with the decoded message.
console.log(`Scan result ${decodedText}`, decodedResult);
alert(decodedText);
}
}
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", { fps: 10, qrbox: 250, rememberLastUsedCamera: false });
html5QrcodeScanner.render(onScanSuccess);
}
});
</script>
Hope it helps希望能帮助到你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.