如何解决当我尝试在 Web 视图中使用 qr 扫描时,Android 崩溃
我尝试将 qr_code_scanner 的二维码扫描仪与 Webview 组件 webview_flutter 结合使用。
在 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
下面的代码显示了一个顶部有一个按钮的全屏网络视图。按下按钮,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 上运行?
解决方法
您是否在 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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。