Use the plug-in
flutter_qr_reader / / code
image_picker // Select the image
permission_handler // Permission control
Copy the code
# flutter_qr_reader: ^1.0. 5Dynamic authentication permission_handler: ^7.1. 0# Image_picker: ^0.74.
#flutter_picker: ^2.01.
Copy the code
Android configuration in/android/SRC/main/AndroidManifest. The XML
<uses-permission android:name="android.permission.CAMERA"/ > <! -- camera --> <uses-permission Android :name="android.permission.WRITE_EXTERNAL_STORAGE"/ > <! -- Storage permission -->Copy the code
The IOS configuration is in info.plist
<key>io.flutter.embedded_views_preview</key>
<true/ > < key > NSAppleMusicUsageDescription < / key > < string > App need your approval, to access the media database < / string > < key > NSCameraUsageDescription < / key > < string > App need your approval to access the camera < / string > < key > NSPhotoLibraryUsageDescription < / key > < string > App need your approval, to access photo album < / string > limit -- -- >Copy the code
scanPage.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_qr_reader/flutter_qr_reader.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
class ScanPage extends StatefulWidget {
@override
_ScanPageState createState() => _ScanPageState();
}
class _ScanPageState extends State<ScanPage> {
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
bool flashlightState = false;
bool showScanView = false;
bool _openAction = false;
QrReaderViewController _controller;
Widget mainUi = Container();
@override
void initState() {
super.initState();
Future.delayed(Duration(milliseconds: 0)).then((_) async {
if (false= =await permission()) {
// openAppSettings();
// Navigator.pop(context);
return;
}
setState(() {
mainUi = getScanUI();
});
});
}
// Scan interface
Widget getScanUI() {
return Container(
child: Stack(
children: [
QrReaderView(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
callback: (controller) {
setState(() {
_controller = controller;
this.startScan();
});
},
),
Container(
height: 30,
padding: EdgeInsets.symmetric(horizontal: 30),
margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 20),
// color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
Navigator.pop(context);
},
child: ClipOval(
child: Container(
width: 24,
height: 24,
color: Color.fromRGBO(0.34.51.0.25),
child: Icon(Icons.clear, color: Colors.white, size: 18),
),
),
),
InkWell(
onTap: imgScan,
child: Image.asset('assets/images/img_img.png', width: 24),
),
],
),
),
Align(
child: Container(
height: MediaQuery.of(context).size.height * 0.8,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.width * 0.65,
width: MediaQuery.of(context).size.width * 0.65.// decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.redAccent)),
child: Image.asset('assets/images/scan_frame.png', fit: BoxFit.fitWidth),
),
Container(
margin: EdgeInsets.only(top: 30),
child: InkWell(
onTap: flashlight,
child: Image.asset('assets/images/icon_light.png', width: 17(() [(() [(() [() [() [() [() [() }void alert(String tip) {
ScaffoldMessenger.of(scaffoldKey.currentContext).showSnackBar(SnackBar(content: Text(tip)));
}
// Camera permission dialog
void showJurisdictionDialog(String text) {
showDialog(
context: context,
builder: (ctx) {
return AlertDialog(
title: Text('tip'),
// content: Text(' Camera permissions are not open, do you want to open camera permissions? '),
content: Text(text),
actions: <Widget>[
TextButton(
child: Text('cancel'),
onPressed: () {
Navigator.pop(context);
},
),
TextButton(
child: Text('confirm'),
onPressed: () {
openAppSettings(); // Enable permission Settings},),,); }); } Future<bool> permission() async {
if (_openAction) return false;
_openAction = true;
var status = await Permission.camera.status;
// print(status);
if (status.isDenied || status.isPermanentlyDenied) {
status = await Permission.camera.request();
// print(status);
}
if (status.isRestricted) {
// alert(" Please authorize camera permissions ");
showJurisdictionDialog("Please grant camera permission.");
// await Future.delayed(Duration(seconds: 3));
openAppSettings();
_openAction = false;
return false;
}
if(! status.isGranted) {// alert(" Please authorize camera permissions ");
showJurisdictionDialog("Please grant camera permission.");
_openAction = false;
return false;
}
_openAction = false;
return true;
}
// Start scanning
Future startScan() async {
assert(_controller ! =null); _controller? .startCamera((String result, _) async {
await stopScan();
debugPrint(result);
Navigator.pop(context, result);
});
}
// Pause scanning
Future stopScan() async {
assert(_controller ! =null);
await_controller? .stopCamera(); setState(() { showScanView =false;
});
}
// Turn on the flashlight
Future flashlight() async {
assert(_controller ! =null);
final state = await_controller? .setFlashlight(); setState(() { flashlightState = state ??false;
});
}
// Select image scan
Future imgScan() async {
if (flashlightState) {
final state = await_controller? .setFlashlight(); setState(() { flashlightState = state ??false;
});
}
var image = await ImagePicker().getImage(source: ImageSource.gallery);
if (image == null) return;
final result = await FlutterQrReader.imgScan(image.path);
debugPrint(result);
Navigator.pop(context, result);
}
@override
Widget build(BuildContext context) {
returnScaffold( body: mainUi, ); }}Copy the code
call
// Scan and click
void onScan() async {
var result = await Navigator.pushNamed(context, '/scanPage');
debugPrint('-- Scan code result --$result');
}
Copy the code
Image resources
FIG. 1Figure 2FIG. 3