Flutter自制插件之r_scan二维码&条形码扫描(支持文件
2020-02-27 本文已影响0人
rhyme_lph
image
介绍
二维码作为信息的载体,广泛应用于我们生活的方方面面,例如:使用支付宝支付,二维码加好友,二维码推广等等,能举例的例子多不胜数,而如果你的应用支持二维码的扫描,用户和体验将会翻倍的增长,如果你是应用的开发者,欢迎来使用此二维码扫描插件!并希望能给予项目一个star,谢谢!项目地址:https://github.com/rhymelph/r_scan
使用
你可以在pub.dev网站上面搜索r_scan
即可找到该插件,添加下面代码到pubspec.yaml
文件
dependencies:
r_scan: last version
- last version 可以在pub.dev网站搜索
r_scan
得到
各设备注意事项
- Android平台下
android6.0系统以上请动态授权,可以结合permission_handler
插件使用,代码如下:
import 'package:permission_handler/permission_handler.dart';
Future<bool> canReadStorage() async {
if(Platform.isIOS) return true;
var status = await PermissionHandler()
.checkPermissionStatus(PermissionGroup.storage);
if (status != PermissionStatus.granted) {
var future = await PermissionHandler()
.requestPermissions([PermissionGroup.storage]);
for (final item in future.entries) {
if (item.value != PermissionStatus.granted) {
return false;
}
}
} else {
return true;
}
return true;
}
Future<bool> canOpenCamera() async {
var status =
await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
if (status != PermissionStatus.granted) {
var future = await PermissionHandler()
.requestPermissions([PermissionGroup.camera]);
for (final item in future.entries) {
if (item.value != PermissionStatus.granted) {
return false;
}
}
} else {
return true;
}
return true;
}
- IOS平台下
需要在info.plist
文件下添加如下代码:
<key>NSCameraUsageDescription</key>
<string>扫描二维码时需要使用您的相机</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>扫描二维码时需要访问您的相册</string>
<key>io.flutter.embedded_views_preview</key>
<true/>
导包
import 'package:r_scan/r_scan.dart';
1.扫描文件图片二维码
final result=await RScan.scanImagePath('你的文件路径');
if(result.isNotEmpty){
//result 为二维码内容
}
2.扫描图片链接二维码
final result=await RScan.scanImagePath('你的图片链接');
if(result.isNotEmpty){
//result 为二维码内容
}
3.扫描内存图片二维码
ByteData data=await rootBundle.load('images/qrCode.png');
final result=await RScan.scanImageMemory(data.buffer.asUint8List());
if(result.isNotEmpty){
//result 为二维码内容
}
4.(NEW)基于Texture使用相机扫描二维码/条形码
- 步骤1:获取可用相机
List<RScanCameraDescription> rScanCameras = await availableRScanCameras();;
如果你在main()
方法下获取可用相机,请使用下面代码
List<RScanCameraDescription> rScanCameras;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
rScanCameras = await availableRScanCameras();
runApp(...);
}
- 步骤2:开始使用
class RScanCameraDialog extends StatefulWidget {
@override
_RScanCameraDialogState createState() => _RScanCameraDialogState();
}
class _RScanCameraDialogState extends State<RScanCameraDialog> {
RScanCameraController _controller;
bool isFirst = true;
@override
void initState() {
super.initState();
//判断当前是否有可用相机
if (rScanCameras != null && rScanCameras.length > 0) {
//初始化相机控制器,一般rScanCameras[0]为后置,rScanCameras[1]为前置摄像头
_controller = RScanCameraController(
rScanCameras[0], RScanCameraResolutionPreset.max)
..addListener(() {
//监听扫码返回结果
final result = _controller.result;
if (result != null) {
if (isFirst) {
//如果扫描到二维码将结果返回到上一页
Navigator.of(context).pop(result);
isFirst = false;
}
}
})
..initialize().then((_) {
//初始化相机
if (!mounted) {
return;
}
setState(() {});
});
}
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
//判断是否有可用相机
if (rScanCameras == null || rScanCameras.length == 0) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: Text('not have available camera'),
),
);
}
//判断相机如果没有初始化,给它一个加载页面
if (!_controller.value.isInitialized) {
return Container();
}
//获取到相机
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
children: <Widget>[
ScanImageView(
child: AspectRatio(
//拿到相机的aspectRatio
aspectRatio: _controller.value.aspectRatio,
child: RScanCamera(_controller),
),
),
//闪光灯
Align(
alignment: Alignment.bottomCenter,
child: FutureBuilder(
future: getFlashMode(),
builder: _buildFlashBtn,
))
],
),
);
}
//获取闪光灯是否打开
Future<bool> getFlashMode() async {
bool isOpen = false;
try {
isOpen = await _controller.getFlashMode();
} catch (_) {}
return isOpen;
}
//构建闪光灯按钮
Widget _buildFlashBtn(BuildContext context, AsyncSnapshot<bool> snapshot) {
return snapshot.hasData
? Padding(
padding: EdgeInsets.only(bottom:24+MediaQuery.of(context).padding.bottom),
child: IconButton(
icon: Icon(snapshot.data ? Icons.flash_on : Icons.flash_off),
color: Colors.white,
iconSize: 46,
onPressed: () {
if (snapshot.data) {
_controller.setFlashMode(false);
} else {
_controller.setFlashMode(true);
}
setState(() {});
}),
)
: Container();
}
}
5.(已弃用)基于PlatformView使用相机扫描二维码/条形码
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:r_scan/r_scan.dart';
class RScanDialog extends StatefulWidget {
@override
_RScanDialogState createState() => _RScanDialogState();
}
class _RScanDialogState extends State<RScanDialog> {
RScanController _controller;
@override
void initState() {
super.initState();
initController();
}
bool isFirst=true;
Future<void> initController() async {
_controller = RScanController();
_controller.addListener(() {//监听扫描到的二维码
final result = _controller.result;
if (result != null) {
if(isFirst){
Navigator.of(context).pop(result);
isFirst=false;
}
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
body: FutureBuilder<bool>(
future: canOpenCameraView(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData && snapshot.data == true) {
return ScanImageView(//这个为自己写的前景
child: RScanView(
controller: _controller,
),
);
} else {
return Container();
}
},
),
),
);
}
Future<bool> canOpenCameraView() async {
var status =
await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
if (status != PermissionStatus.granted) {
var future = await PermissionHandler()
.requestPermissions([PermissionGroup.camera]);
for (final item in future.entries) {
if (item.value != PermissionStatus.granted) {
return false;
}
}
} else {
return true;
}
return true;
}
}
6. 打开闪光灯/获取闪光灯状态
使用RScanController
类的实例直接调用
//关闭闪光灯
await _controller.setFlashMode(false);
//打开闪光灯
await _controller.setFlashMode(true);
// 获取闪光灯状态
bool isOpen = await _controller.getFlashMode();
7.RScanResult(二维码扫描结果)
当扫描到二维码&条形码将返回该对象,包含如下内容
class RScanResult {
/// 条形码类型
final RScanBarType type;
///附带的信息
final String message;
///条形码对应的区域 包含 [x , y] 坐标
final List<RScanPoint> points;
}
后续开发
- 支持自定义区域触发扫描
- 还有更多...