어떻게 처음부터 전진 QR코드 스캐너 플러그인을 실현합니까
장치
Dynamsoft Camera Enhancer :
allprojects {
repositories {
google()
jcenter()
maven {
url "https://download.dynamsoft.com/maven/dce/aar"
}
}
}
dependencies {
implementation 'com.dynamsoft:dynamsoftcameraenhancer:2.0.0@aar'
}
Dynamsoft Barcode Reader :
allprojects {
repositories {
google()
jcenter()
maven {
url "https://download2.dynamsoft.com/maven/dbr/aar"
}
}
}
dependencies {
implementation 'com.dynamsoft:dynamsoftbarcodereader:8.8.0@aar'
}
Android TextView에서 간단한 떨림 위젯 만들기
이 절에서, 우리는 Flutter's tutorial Flatter 소부품
TextView
에 안드로이드PlatformView
를 위탁 관리할 것이다.새 바이브레이션 플러그인 항목을 만들려면 다음과 같이 하십시오.
flutter create --org com.dynamsoft --template=plugin --platforms=android -a java flutter_qrcode_scanner
Dart의 경우
lib/flutter_qrcode_scanner.dart
에서 다음 코드를 확인할 수 있습니다.
import 'dart:async';
import 'package:flutter/services.dart';
class FlutterQrcodeScanner {
static const MethodChannel _channel = MethodChannel('flutter_qrcode_scanner');
static Future<String?> get platformVersion async {
final String? version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}
위의 코드 세그먼트를 삭제하고 다음과 같이 상태가 있는 작은 위젯을 정의합니다.class ScannerView extends StatefulWidget {
const ScannerView({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _ScannerViewState();
}
class _ScannerViewState extends State<ScannerView> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
const String viewType = 'com.dynamsoft.flutter_qrcode_scanner/nativeview';
final Map<String, dynamic> creationParams = <String, dynamic>{};
return AndroidView(
viewType: viewType,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);
}
}
플랫폼 쪽에서
NativeView
클래스를 만들었는데 이 클래스는 io.flutter.plugin.platform.PlatformView
를 확장하여 TextView
에 대한 인용을 제공합니다.import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.plugin.platform.PlatformView;
import java.util.Map;
class NativeView implements PlatformView {
@NonNull private final TextView textView;
NativeView(@NonNull Context context, int id, @Nullable Map<String, Object> creationParams) {
textView = new TextView(context);
textView.setTextSize(72);
textView.setBackgroundColor(Color.rgb(255, 255, 255));
textView.setText("Rendered on a native Android view (id: " + id + ")");
}
@NonNull
@Override
public View getView() {
return textView;
}
@Override
public void dispose() {}
}
그리고 NativeViewFactory
클래스를 만들어서 초기화NativeView
:import android.content.Context;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
import java.util.Map;
class NativeViewFactory extends PlatformViewFactory {
@NonNull private final BinaryMessenger messenger;
NativeViewFactory(@NonNull BinaryMessenger messenger) {
super(StandardMessageCodec.INSTANCE);
this.messenger = messenger;
}
@NonNull
@Override
public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
final Map<String, Object> creationParams = (Map<String, Object>) args;
return new NativeView(context, id, creationParams);
}
}
FlutterQrcodeScannerPlugin.java
파일에factory 클래스가 등록되어 있습니다.@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_qrcode_scanner");
channel.setMethodCallHandler(this);
flutterPluginBinding.getPlatformViewRegistry().registerViewFactory(
"com.dynamsoft.flutter_qrcode_scanner/nativeview",
new NativeViewFactory(flutterPluginBinding.getBinaryMessenger()));
}
example/lib/main.dart
를 정상적으로 작동하도록 변경했습니다.import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_qrcode_scanner/flutter_qrcode_scanner.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: ScannerView(),
),
),
);
}
}
다음 예제를 실행합니다.flutter run
Android Camera View에서 바이브레이션 카메라 위젯 구현
만약 위의 코드가 당신에게 유효하다면, 다음 단계는 텍스트 보기를 카메라 보기로 바꾸는 것입니다.여기서 우리는 다이나믹 소프트 카메라 증강기를 예로 들 수 있다.
구성
android/build.gradle
:rootProject.allprojects {
repositories {
google()
mavenCentral()
maven {
url "https://download.dynamsoft.com/maven/dce/aar"
}
}
}
android {
compileSdkVersion 30
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion 21
}
}
dependencies {
implementation 'com.dynamsoft:dynamsoftcameraenhancer:2.0.0@aar'
}
최소 Android SDK 버전을 21 이상으로 변경해야 합니다.NativeView.java
에서 카메라 패키지를 가져오려면 다음과 같이 하십시오.import com.dynamsoft.dce.*;
TextView
를 DCECameraView
로 변경합니다.CameraEnhancer
를 사용하여 카메라 미리보기를 시작하고 중지할 수 있습니다.private final DCECameraView cameraView;
private CameraEnhancer cameraEnhancer;
NativeView(BinaryMessenger messenger, @NonNull Activity context, int id,
@Nullable Map<String, Object> creationParams) {
this.context = context;
cameraEnhancer = new CameraEnhancer(context);
cameraView = new DCECameraView(context);
cameraEnhancer.setCameraView(cameraView);
try {
cameraEnhancer.open();
} catch (Exception e) {
e.printStackTrace();
}
}
캠페인 수명 주기 동안 카메라 상태를 전환하기 위해 구현Application.ActivityLifecycleCallbacks
:class NativeView implements PlatformView, Application.ActivityLifecycleCallbacks {
@Override
public void onActivityResumed(Activity activity) {
try {
cameraEnhancer.open();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onActivityPaused(Activity activity) {
try {
cameraEnhancer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Activity
클래스에서 Context
가 아닌 NativeView
클래스를 사용하고 있음을 알 수 있습니다.따라서 NativeViewFactory
클래스도 변경해야 합니다.class NativeViewFactory extends PlatformViewFactory {
@NonNull private final BinaryMessenger messenger;
@NonNull private Activity activity;
NativeViewFactory(@NonNull BinaryMessenger messenger, Activity activity) {
super(StandardMessageCodec.INSTANCE);
this.messenger = messenger;
this.activity = activity;
}
@NonNull
@Override
public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
final Map<String, Object> creationParams = (Map<String, Object>) args;
return new NativeView(messenger, activity, id, creationParams);
}
}
마지막으로
FlutterQrcodeScannerPlugin
클래스에서 우리는 활동 상태를 감시하고 활동 인용을 NativeViewFactory
실례에 전달한다.public class FlutterQrcodeScannerPlugin implements FlutterPlugin, ActivityAware {
private Activity activity;
private FlutterPluginBinding flutterPluginBinding;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
this.flutterPluginBinding = flutterPluginBinding;
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
this.flutterPluginBinding = null;
}
@Override
public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
bind(activityPluginBinding);
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
bind(activityPluginBinding);
}
@Override
public void onDetachedFromActivityForConfigChanges() {
activity = null;
}
@Override
public void onDetachedFromActivity() {
activity = null;
}
private void bind(ActivityPluginBinding activityPluginBinding) {
activity = activityPluginBinding.getActivity();
flutterPluginBinding.getPlatformViewRegistry().registerViewFactory(
"com.dynamsoft.flutter_qrcode_scanner/nativeview",
new NativeViewFactory(flutterPluginBinding.getBinaryMessenger(), activity));
}
}
example/android/build.gradle
로 변경해야 합니다.떨림 카메라 플러그인을 떨림 QR코드 스캐너로 바꾸다
일반적으로 우리는 미리 보기 리셋 함수에서 카메라 프레임을 가져와 진일보한 이미지 처리를 할 수 있다.개발자의 시간을 절약하기 위해서는 좋은 카메라 소부품이 시각 기능을 제공해야 한다.다음 단락에서 Dynamsoft 바코드 리더 SDK를 현재 Flatter cameraview 작은 위젯에 집적하는 방법을 보실 수 있습니다.
camera SDK를 사용하는 것과 마찬가지로 바코드 패키지를
build.gradle
에 추가합니다.rootProject.allprojects {
repositories {
google()
mavenCentral()
maven {
url "https://download.dynamsoft.com/maven/dce/aar"
}
maven {
url "https://download.dynamsoft.com/maven/dbr/aar"
}
}
}
android {
compileSdkVersion 30
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion 21
}
}
dependencies {
implementation 'com.dynamsoft:dynamsoftcameraenhancer:2.0.0@aar'
implementation 'com.dynamsoft:dynamsoftbarcodereader:8.8.0@aar'
}
Dynamsoft 카메라 증강기와 Dynamsoft 바코드 리더 SDK는 협동하여 일을 잘 할 수 있다.실시간 QR코드 검색을 위해
QRCodeScanner.java
파일에 넣습니다.public class QRCodeScanner {
private CameraEnhancer mCameraEnhancer;
private BarcodeReader reader;
private Activity context;
private DCECameraView cameraView;
private DetectionHandler handler;
public interface DetectionHandler {
public void onDetected(List<Map<String, Object>> data);
}
public QRCodeScanner(Activity context, DCECameraView cameraView) {
this.context = context;
this.cameraView = cameraView;
mCameraEnhancer = new CameraEnhancer(context);
mCameraEnhancer.setCameraView(cameraView);
cameraView.setOverlayVisible(true);
DCESettingParameters dceSettingParameters = new DCESettingParameters();
dceSettingParameters.cameraInstance = mCameraEnhancer;
dceSettingParameters.textResultCallback = mTextResultCallback;
try {
// mCameraEnhancer.open();
reader = new BarcodeReader();
reader.SetCameraEnhancerParam(dceSettingParameters);
PublicRuntimeSettings settings = reader.getRuntimeSettings();
settings.barcodeFormatIds = EnumBarcodeFormat.BF_QR_CODE;
reader.updateRuntimeSettings(settings);
} catch (Exception e) {
// TODO: handle exception
}
}
TextResultCallback mTextResultCallback = new TextResultCallback() {
@Override
public void textResultCallback(int i, TextResult[] results, Object userData) {
if (results != null) {
final List<Map<String, Object>> ret = new ArrayList<Map<String, Object>>();
for (TextResult result: results) {
final Map<String, Object> data = new HashMap<>();
data.put("format", result.barcodeFormatString);
data.put("text", result.barcodeText);
data.put("x1", result.localizationResult.resultPoints[0].x);
data.put("y1", result.localizationResult.resultPoints[0].y);
data.put("x2", result.localizationResult.resultPoints[1].x);
data.put("y2", result.localizationResult.resultPoints[1].y);
data.put("x3", result.localizationResult.resultPoints[2].x);
data.put("y3", result.localizationResult.resultPoints[2].y);
data.put("x4", result.localizationResult.resultPoints[3].x);
data.put("y4", result.localizationResult.resultPoints[3].y);
data.put("angle", result.localizationResult.angle);
ret.add(data);
}
if (handler != null) {
handler.onDetected(ret);
}
}
}
};
public void setDetectionHandler(DetectionHandler handler) {
this.handler = handler;
}
public void startScan() {
try {
// mCameraEnhancer.open();
cameraView.setOverlayVisible(true);
reader.StartCameraEnhancer();
} catch (Exception e) {
// TODO: handle exception
}
}
public void stopScan() {
try {
// mCameraEnhancer.close();
cameraView.setOverlayVisible(false);
reader.StopCameraEnhancer();
} catch (Exception e) {
// TODO: handle exception
}
}
public void setLicense(String license) {
try {
reader.initLicense(license);
} catch (Exception e) {
e.printStackTrace();
}
}
}
QR코드 감지 API를 활성화하려면 valid license가 필요합니다.QR코드가 감지되면 Java에서 Dart로 결과를 보내는 방법이 필요합니다.
MethodChannel
클래스는Dart와 로컬 코드 사이에서 메시지를 보내고 받는 데 사용됩니다.따라서 다음 코드를 NativeView.java
에 추가합니다.class NativeView implements PlatformView, MethodCallHandler, Application.ActivityLifecycleCallbacks, QRCodeScanner.DetectionHandler {
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
switch (call.method) {
case "startScanning":
qrCodeScanner.startScan();
result.success(null);
break;
case "stopScanning":
qrCodeScanner.stopScan();
result.success(null);
break;
case "setLicense":
final String license = call.argument("license");
qrCodeScanner.setLicense(license);
result.success(null);
break;
case "setBarcodeFormats":
final int formats = call.argument("formats");
qrCodeScanner.setBarcodeFormats(formats);
result.success(null);
break;
default:
result.notImplemented();
}
}
}
QR코드가 감지되면 콜백 함수onDetected
가 트리거됩니다.함수는 작업 라인에서 호출되고, 방법 채널 통신은 주 라인에서 호출되어야 한다는 것을 알아야 합니다.이를 위해 runOnUiThread
를 사용하여 주 스레드에 메시지를 보냅니다.@Override
public void onDetected(List<Map<String, Object>> data) {
context.runOnUiThread(new Runnable() {
@Override
public void run() {
methodChannel.invokeMethod("onDetected", data);
}
});
}
Dart의 경우
ScannerViewController
에 QR코드 검사 결과를 수신하기 위한 flutter_qrcode_scanner.dart
를 정의했습니다.class _ScannerViewState extends State<ScannerView> {
ScannerViewController? _controller;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
const String viewType = 'com.dynamsoft.flutter_qrcode_scanner/nativeview';
final Map<String, dynamic> creationParams = <String, dynamic>{};
return AndroidView(
viewType: viewType,
onPlatformViewCreated: _onPlatformViewCreated,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);
}
void _onPlatformViewCreated(int id) {
_controller = ScannerViewController(id);
widget.onScannerViewCreated(_controller!);
}
}
class ScannerViewController {
late MethodChannel _channel;
final StreamController<List<BarcodeResult>> _streamController =
StreamController<List<BarcodeResult>>();
Stream<List<BarcodeResult>> get scannedDataStream => _streamController.stream;
ScannerViewController(int id) {
_channel =
MethodChannel('com.dynamsoft.flutter_qrcode_scanner/nativeview_$id');
_channel.setMethodCallHandler((call) async {
switch (call.method) {
case 'onDetected':
if (call.arguments != null) {
List<BarcodeResult> data = fromPlatformData(call.arguments as List);
_streamController.sink.add(data);
}
break;
}
});
}
}
이 메서드를 호출하는 함수는 다음과 같습니다.Future<void> startScanning() async {
await _channel.invokeMethod('startScanning');
}
Future<void> stopScanning() async {
await _channel.invokeMethod('stopScanning');
}
/// Apply for a 30-day FREE trial license: https://www.dynamsoft.com/customer/license/trialLicense
Future<void> setLicense(String license) async {
await _channel.invokeMethod('setLicense', {'license': license});
}
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_camera_qrcode_scanner/flutter_qrcode_scanner.dart';
import 'package:flutter_camera_qrcode_scanner/dynamsoft_barcode.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ScannerViewController? controller;
String _barcodeResults = '';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('QR Code Scanner'),
),
body: Stack(children: <Widget>[
ScannerView(onScannerViewCreated: onScannerViewCreated),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
height: 100,
child: SingleChildScrollView(
child: Text(
_barcodeResults,
style: TextStyle(fontSize: 14, color: Colors.white),
),
),
),
Container(
height: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MaterialButton(
child: Text('Start Scan'),
textColor: Colors.white,
color: Colors.blue,
onPressed: () async {
controller!.startScanning();
}),
MaterialButton(
child: Text("Stop Scan"),
textColor: Colors.white,
color: Colors.blue,
onPressed: () async {
controller!.stopScanning();
})
]),
),
],
)
]),
),
);
}
void onScannerViewCreated(ScannerViewController controller) {
setState(() {
this.controller = controller;
});
controller.setLicense('LICENSE-KEY');
controller.startScanning(); // auto start scanning
controller.scannedDataStream.listen((results) {
setState(() {
_barcodeResults = getBarcodeResults(results);
});
});
}
String getBarcodeResults(List<BarcodeResult> results) {
StringBuffer sb = new StringBuffer();
for (BarcodeResult result in results) {
sb.write(result.format);
sb.write("\n");
sb.write(result.text);
sb.write("\n\n");
}
if (results.isEmpty) sb.write("No QR Code Detected");
return sb.toString();
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
술집에서 떨림 QR코드 스캐너를 다운로드하다.덕부
https://pub.dev/packages/flutter_camera_qrcode_scanner
소스 코드
https://github.com/yushulx/flutter_qrcode_scanner
Reference
이 문제에 관하여(어떻게 처음부터 전진 QR코드 스캐너 플러그인을 실현합니까), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/yushulx/how-to-implement-a-flutter-qr-code-scanner-plugin-from-scratch-1bpc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)