当我尝试将 qr 扫描与 Web 视图一起使用时,Android 崩溃

     2023-02-23     60

关键词:

【中文标题】当我尝试将 qr 扫描与 Web 视图一起使用时,Android 崩溃【英文标题】:Android crashes when I try to use qr scanning with a web view 【发布时间】:2021-06-18 22:02:08 【问题描述】:

我尝试将qr_code_scanner 的二维码扫描器与webview_flutter 的Webview 组件结合使用。

在 iOS 上一切正常,但在 Android 设备上无法正常工作,QR 扫描仪不显示,并且我得到重复的控制台打印。

D/mali_winsys(30667): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 

我已经在两台 Android 设备(Android 10 v29 和 Android 7 v24)上进行了尝试,结果相同。

以下是重现该问题的最小应用程序。它需要以下依赖项:

qr_code_scanner: ^0.3.5
webview_flutter: ^2.0.2 

下面的代码显示了一个顶部有一个按钮的全屏 web 视图。按下按钮,QR 扫描仪将/应该出现...

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  bool _showQr = false;

  @override
  void initState() 
    super.initState();
    // Enable hybrid composition.
    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
  

  void closeQr() 
    setState(() 
      _showQr = false;
    );
  

  @override
  Widget build(BuildContext context) 
    return Stack(
      children: [
        Stack(
          children: [
            WebView(
              initialUrl: 'https://flutter.dev',
            ),
            Center(
              child: TextButton(
                onPressed: () 
                  setState(() 
                    _showQr = !_showQr;
                  );
                ,
                child: Text('Show QR Scanner'),
                style: TextButton.styleFrom(
                  primary: Colors.white,
                  backgroundColor: Colors.teal,
                  onSurface: Colors.grey,
                ),
              ),
            ),
          ],
        ),
        Center(
          child: (_showQr) ? QRWidget(onClose: closeQr) : null,
        ),
      ],
    );
  


class QRWidget extends StatefulWidget 
  const QRWidget(
    Key key,
    this.onClose,
  ) : super(key: key);

  final Function onClose;

  @override
  State<StatefulWidget> createState() => _QRWidgetState();


class _QRWidgetState extends State<QRWidget> 
  Barcode result;
  QRViewController controller;
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');

  // In order to get hot reload to work we need to pause the camera if the platform
  // is android, or resume the camera if the platform is iOS.
  @override
  void reassemble() 
    super.reassemble();
    if (Platform.isAndroid) 
      controller.pauseCamera();
    
    controller.resumeCamera();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Stack(
        children: <Widget>[
          _buildQrView(context),
          Container(
            alignment: Alignment.bottomCenter,
            padding: EdgeInsets.only(bottom: 60.0),
            child: Row(
              children: <Widget>[
                Expanded(
                  child: RawMaterialButton(
                    onPressed: () 
                      setState(() 
                        widget.onClose();
                      );
                    ,
                    elevation: 2.0,
                    fillColor: Colors.white,
                    child: Icon(
                      Icons.close_sharp,
                      color: Color(0xff459d44),
                      size: 40.0,
                    ),
                    padding: EdgeInsets.all(8.0),
                    shape: CircleBorder(),
                  ),
                ),
              ],
            ),
          )
        ],
      ),
    );
  

  Widget _buildQrView(BuildContext context) 
    // For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
    var scanArea = (MediaQuery.of(context).size.width < 400 ||
            MediaQuery.of(context).size.height < 400)
        ? 150.0
        : 300.0;
    // To ensure the Scanner view is properly sizes after rotation
    // we need to listen for Flutter SizeChanged notification and update controller
    return QRView(
      key: qrKey,
      onQRViewCreated: _onQRViewCreated,
      overlay: QrScannerOverlayShape(
          borderColor: Color(0xff459d44),
          borderRadius: 10,
          borderLength: 30,
          borderWidth: 10,
          cutOutSize: scanArea),
    );
  

  void _onQRViewCreated(QRViewController controller) 
    setState(() 
      this.controller = controller;
    );
    controller.scannedDataStream.listen((scanData) 
      setState(() 
        result = scanData;
      );
    );
  

  @override
  void dispose() 
    controller?.dispose();
    super.dispose();
  

为什么它不能在 Android 上运行?

【问题讨论】:

你见过github.com/juliuscanute/qr_code_scanner/issues/289 是的,这是我报告的问题。但由于到目前为止我没有得到任何反馈,而且我不确定问题是在 QR 模块中还是在 web 视图中,所以我认为最好也在这里发布一个问题。 【参考方案1】:

您是否在 AndroidManifest.xml 中添加了权限

<uses-permission android:name="android.permission.CAMERA" />

如果它的 webview,你为什么不使用 flutter_inappwebview 。它很好用,并且具有您以后可能需要的许多附加功能。它仍然需要 androidmanifest 的许可。如果您决定选择flutter_inappwebview,以下是示例。

class _HomePageState extends State<HomePage> 
  InAppWebViewController webView;
  String url = "";

  @override
  void initState()
    checkPermissions();
    super.initState();
  

  @override
  void dispose() 
    super.dispose();
  

    checkPermissions() async
    await [
      Permission.camera,
      Permission.storage,
    ].request();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: SafeArea(
        child: Container(
          child: Column(children: <Widget>[
            Expanded(
              child: Container(
                child: InAppWebView(
                  initialUrl: 'https://flutter.dev',
                  initialHeaders: ,
                  initialOptions: InAppWebViewGroupOptions(
                    crossPlatform: InAppWebViewOptions(
                        debuggingEnabled: true,
                    )
                  ),
                  onWebViewCreated: (InAppWebViewController controller) 
                    webView = controller;
                  ,
                  onLoadStart: (InAppWebViewController controller, String url) 
                    setState(() 
                      this.url = url;
                    );
                  ,
                  onLoadStop: (InAppWebViewController controller, String url) async 
                    setState(() 
                      this.url = url;
                    );
                  ,
                  /// this is the important one to pass the permission
                  androidOnPermissionRequest: (InAppWebViewController controller, String origin, List<String> resources) async 
                    return PermissionRequestResponse(resources: resources, action: PermissionRequestResponseAction.GRANT);
                  ,
                ),
              ),
            ),
          ])
        ),
      ),
    );
  

别忘了在你的 pubspec.yaml 中添加这个 permission_handler

【讨论】:

我选择了 webview_flutter,因为我需要在 webview 顶部添加小部件,inapp_webview 不支持我忘了提及,但是如果我删除 webview,QR 扫描仪工作正常,所以它不应该是权限问题。 @jola, on top 是指上面的警报还是在页面顶部? 像警报一样,即在顶部我的意思是按 z 顺序堆叠在顶部。

当我尝试将 HTML 与 `JOptionPane` 一起使用时,会打印 HTML 标签而不是 HTML 格式

】当我尝试将HTML与`JOptionPane`一起使用时,会打印HTML标签而不是HTML格式【英文标题】:WhenItrytouseHTMLwith`JOptionPane`,HTMLtagsareprintedinsteadofHTMLformatting【发布时间】:2012-02-2212:49:52【问题描述】:由于某些奇怪的原因,当我尝试将HTML... 查看详情

当我尝试将 Analytics 与通知一起使用时,Firebase 中没有静态方法 zzUr()

】当我尝试将Analytics与通知一起使用时,Firebase中没有静态方法zzUr()【英文标题】:NostaticmethodzzUr()inFirebasewhenItrytouseAnalyticswithNotifications【发布时间】:2016-11-0705:51:32【问题描述】:我开始使用Firebase云消息传递。我只有使用通... 查看详情

尝试将指针与结构一起使用时出错

...我正在尝试将RGB值编码到一个结构中,它工作正常,但是当我尝试运行一个访问该结构的函数时,我收到一个异常,说我的结构是nullptr。代码如下:structColorunsignedcharR;unsignedcharG;unsignedch 查看详情

将 web3.js 与 Jest 一起使用时出错

...web3.jswithJest【发布时间】:2018-03-2204:52:01【问题描述】:当我运行以下使用web3.js包的Jest测试时constWeb3=require("web3");test("Web3version",function()expect(Web3.version).toEqual("1.0.0-beta.23"););我收到以 查看详情

如何将列表视图与其他小部件一起使用?

...述】:我想将ListView与其他小部件一起使用,但我不能。当我为Listview使用容器时,我无法查看任何其他小部件。我该怎么做?Scaffold(body:SingleChildScrollView(child:Column(children:<Widg 查看详情

使用 raspberryPi 相机 nodeJS 进行 QR 扫描

...使用USB摄像头并使用Instascan节点模块扫描二维码。但是,当我尝试使用Raspberrypi相机时,Insta扫描无法找到它并且无法显示相机。 查看详情

当我有大量对象时,如何将 insertMany 与 Mongoose 一起使用?

】当我有大量对象时,如何将insertMany与Mongoose一起使用?【英文标题】:HowdoIuseinsertManywithMongoosewhenIhaveabigarrayofobject?【发布时间】:2018-03-0713:03:33【问题描述】:我正在尝试使用insertMany方法,但没有成功...我阅读了这个***answer... 查看详情

与核心数据一起使用时预览崩溃

...e-data【发布时间】:2020-08-2912:23:53【问题描述】:我正在尝试使用swiftui和core-data创建一个简单的待办事项应用程序,但是在添加视图时遇到了一些问题。我有一个TaskView视图,它将用于显示有关列表中任务的一些信息(标题、日... 查看详情

不能将 @Res() 与 FilesInterceptor() 一起使用

...应发送回用户以确认成功或失败。直到今天一切都很好,当我尝试上传响应时不会出现。经过一番挖掘,我发现当我将@res与@UploadedFile一起使用时,它不会执行控制器。我是 查看详情

当我尝试将错误处理程序与 discord.py 一起使用时,“忽略 on_command_error 中的异常”

】当我尝试将错误处理程序与discord.py一起使用时,“忽略on_command_error中的异常”【英文标题】:"Ignoringexceptioninon_command_error"whenItrytousemyerrorhandlerwithdiscord.py【发布时间】:2021-02-1704:07:41【问题描述】:我为任何有参数提... 查看详情

将 presentViewController 与 UITabbarController 一起使用时如何传递数据

...题描述】:我是ios的新手。我尝试使用UITabbarController,但当我尝试将数据从ViewController(此Vi 查看详情

将 Tensorflow 与 GPU 一起使用时出错

...试了一堆不同的Tensorflow示例,它们在CPU上运行良好,但当我尝试在GPU上运行它们时会产生相同的错误。一个小例子是这样的:importtensorflowastf#Createsagraph.a=tf.constant([1.0,2.0,3.0,4 查看详情

将领域与回收者视图一起使用的最佳实践?

...个通用问题,但我在互联网上什么也没找到。例如,我在尝试对一行进行简单的颜色更改时遇到了很多麻烦。例如考虑这个典型的用法:publicclassUserextendsRea 查看详情

将视图与包含标签一起使用时不可见

】将视图与包含标签一起使用时不可见【英文标题】:Viewisnotvisiblewhileusingitwithincludetag【发布时间】:2020-11-2110:35:50【问题描述】:我有一个布局activity_main.xml,它使用include标签添加了另一个布局(login_screen.xmlsignup_screen.xml)。使... 查看详情

将 jquery 与 nodejs 一起使用时的基本错误

...问题描述】:我正在尝试在我的项目中使用一些jquery,但当我尝试使用它时,我在复制代码时遇到了一个错误,并且无法获得任何谷歌帮助varjquery=require(\'jquery\');var$=jquery.create();^TypeError: 查看详情

将数据库与弹性 beantalk 一起使用

...查应用程序。在这方面,我对AWS和Web应用程序完全陌生。当我构建我的应用程序时,它在本地服务器上运行良好,我在我的settings.py中使用了它:DATABASES=\'default\':\'ENG 查看详情

尝试将 gSoap 与 WCF 和 WSHttpBinding 一起使用

...服务器通信。我似乎遇到了gSoap的WS-Addressing插件的问题。当我启用WS-Addressing插件时,通过使用#import"wsa5.h"我无 查看详情

将 retfofit 与 MVVM 一起使用时出现错误

...述】:我正在尝试使用带有MVVM架构的改造来获取数据。当我想在控制台上打印数据时,它可以工作。但是当我想在RecyclerView上使用它们时,我得到了这个错误:E/AndroidRuntime:致命异常:main进程:com.examp 查看详情