我在 Android WebView 中收到“Uncaught ReferenceError: globalThis is not defined”HTML5-qrcode 扫描器,在 chrome 和 Web 浏览器上运行完美

问题描述 投票:0回答:2

我有一个网络应用程序 (https://salon.techwithin.in) 将在浏览器和 Android 应用程序上使用。

我的应用程序的示例二维码 https://i.postimg.cc/Fsm9bKwT/sample-qr-scan.jpg

为了将此 Web 应用程序转换为 Android 应用程序,我使用 WebView 创建了一个简单的 Android 应用程序

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

我在 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”,来源: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/编舞:跳过 33 帧!应用程序可能在其主线程上做了太多工作。 2022-09-06 09:05:44.975 2932-2932/in.techwithin.thesalonman I/chromium: [INFO:CONSOLE(432)] “Uncaught TypeError: Html5QrcodeScanner is not a constructor”,来源:https://blog .minhazav.dev/research/html5-qrcode.html (432)

当前插件用于扫描我的网络应用程序中的二维码

https://github.com/mebjas/html5-qrcode

我试过在 webview 中使用开发人员的 Html5-qrcode 演示页面,它抛出了同样的错误。 (查看代码示例中的注释)

Android 应用程序正确请求 CAMERA 访问, 为了测试相机的工作情况,我测试了另一个插件演示网页

https://nimiq.github.io/qr-scanner/demo/

它打开相机并正确扫描QR码,

但是现在,我无法在我的网络应用程序中切换到这个工作插件,因此我需要一个仅包含当前插件 (html5-qrcode) 的解决方案。 我当前的网络应用程序是在 Core PHP 中构建的,并直接在浏览器中使用 html5-qrcode 插件,无需任何加载程序

<script src="https://unpkg.com/html5-qrcode" type="text/javascript">

我是 Android 应用程序开发的新手,因此我们将不胜感激。

javascript android webview qr-code
2个回答
0
投票

我也是安卓应用的新手。

根据你的代码和这个评论answer

html5-qrcode
插件在我的WebView中工作。

这是代码

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

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

我在网站上有

<head></head>

<script src="https://github.com/mebjas/html5-qrcode" id="scan-qr-js"></script>

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

希望有帮助


0
投票

问题不在于你的安卓代码 根据项目的问题列表,问题出在 2.3.1 版本之后的 html5-qrcode.min.js 文件中

所以我从以下链接复制了文件,它开始工作了。 https://github.com/mebjas/html5-qrcode/releases/tag/v2.3.1

© www.soinside.com 2019 - 2024. All rights reserved.