Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c4bc3c0
Update build.gradle
dardan-inecta Apr 15, 2025
af42b6c
Update build.gradle
dardan-inecta Apr 15, 2025
bb340c8
Fix web issue
Sweta0208 Apr 22, 2025
8cadbac
Merge pull request #1 from dardan-inecta/shweta_changes
dardan-inecta Apr 22, 2025
f4784d9
fixed web issue
Sweta0208 Apr 22, 2025
de5ccba
Merge pull request #2 from dardan-inecta/shweta_changes
swetav1996 Apr 23, 2025
ba3c4a4
Resolved issue for Dart SDK (3.3+)
Sweta0208 Apr 23, 2025
f7ad2cc
Merge pull request #3 from dardan-inecta/shweta_changes
swetav1996 Apr 23, 2025
9e7eec9
Fix
Sweta0208 Apr 23, 2025
1aac90d
Merge pull request #4 from dardan-inecta/shweta_changes
swetav1996 Apr 23, 2025
88f5f26
Upgrade flutter version
swetav1996 Oct 9, 2025
ca0bbce
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
7b2631f
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
5bd088c
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
73835fe
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
646cb3b
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
fa2c893
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
22d754b
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
8c93ed7
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
1bed5c8
Update lifecycle_event_handler.dart
swetav1996 Oct 9, 2025
3a38547
Update lifecycle_event_handler.dart
swetav1996 Oct 9, 2025
f093cc1
Update flutter_qr_web.dart
swetav1996 Oct 9, 2025
cd7da75
Update lifecycle_event_handler.dart
swetav1996 Oct 9, 2025
b9f5f6d
Update lifecycle_event_handler.dart
swetav1996 Oct 9, 2025
49eb3c9
Update pubspec.yaml
swetav1996 Oct 9, 2025
917a6df
Fixes
swetaVanjara Oct 9, 2025
6e37cba
Fixes
swetaVanjara Oct 9, 2025
b86c818
Update lifecycle_event_handler.dart
swetav1996 Oct 9, 2025
5cfe5d5
Update lifecycle_event_handler.dart
swetav1996 Oct 9, 2025
22e5f61
fixed
swetaVanjara Oct 9, 2025
204711c
Added hidden flag on app lifecycle state
swetaVanjara Oct 9, 2025
a9e1047
Merge branch 'master' of https://github.com/dardan-inecta/qr_code_sca…
swetaVanjara Oct 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,27 @@ apply plugin: 'kotlin-android'

android {
compileSdk 33
namespace 'net.touchcapture.qr.flutterqr' // ✅ Place it here

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// minSdkVersion is determined by Native View.
minSdkVersion 20
targetSdkVersion 33
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}

kotlinOptions {
jvmTarget = '11'
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 11
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
coreLibraryDesugaringEnabled true
}
if (project.android.hasProperty('namespace')) {
namespace 'net.touchcapture.qr.flutterqr'

kotlinOptions {
jvmTarget = '11'
}
}

Expand All @@ -59,5 +55,5 @@ dependencies {
implementation('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false }
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.zxing:core:3.5.2'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' // ✅ latest stable
}
2 changes: 2 additions & 0 deletions lib/src/lifecycle_event_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class LifecycleEventHandler extends WidgetsBindingObserver {
case AppLifecycleState.inactive:
case AppLifecycleState.paused:
case AppLifecycleState.detached:
case AppLifecycleState.hidden:
break;
}
}
}
53 changes: 22 additions & 31 deletions lib/src/web/flutter_qr_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import 'dart:async';
import 'dart:core';
import 'dart:html' as html;
import 'dart:js_util';
import 'dart:ui' as ui;

// ignore_for_file: avoid_web_libraries_in_flutter
import 'web_view_registry.dart';
import 'package:flutter/material.dart';

import '../../qr_code_scanner.dart';
Expand All @@ -24,21 +25,16 @@ class WebQrView extends StatefulWidget {
final CameraFacing? cameraFacing;

const WebQrView(
{Key? key,
required this.onPlatformViewCreated,
this.onPermissionSet,
this.cameraFacing = CameraFacing.front})
{Key? key, required this.onPlatformViewCreated, this.onPermissionSet, this.cameraFacing = CameraFacing.front})
: super(key: key);

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

static html.DivElement vidDiv =
html.DivElement(); // need a global for the registerViewFactory
static html.DivElement vidDiv = html.DivElement(); // need a global for the registerViewFactory

static Future<bool> cameraAvailable() async {
final sources =
await html.window.navigator.mediaDevices!.enumerateDevices();
final sources = await html.window.navigator.mediaDevices!.enumerateDevices();
// List<String> vidIds = [];
var hasCam = false;
for (final e in sources) {
Expand Down Expand Up @@ -66,8 +62,7 @@ class _WebQrViewState extends State<WebQrView> {
html.VideoElement video = html.VideoElement();
String viewID = 'QRVIEW-' + DateTime.now().millisecondsSinceEpoch.toString();

final StreamController<Barcode> _scanUpdateController =
StreamController<Barcode>();
final StreamController<Barcode> _scanUpdateController = StreamController<Barcode>();
late CameraFacing facing;

Timer? _frameIntervall;
Expand All @@ -80,9 +75,14 @@ class _WebQrViewState extends State<WebQrView> {

// video = html.VideoElement();
WebQrView.vidDiv.children = [video];
// ignore: UNDEFINED_PREFIXED_NAME
ui.platformViewRegistry
.registerViewFactory(viewID, (int id) => WebQrView.vidDiv);
// ignore: undefined_prefixed_name
platformViewRegistry.registerViewFactory(
viewID,
(int id) => WebQrView.vidDiv,
);

print('[QR Scanner Web] viewID: $viewID');

// giving JavaScipt some time to process the DOM changes
Timer(const Duration(milliseconds: 500), () {
start();
Expand All @@ -92,8 +92,7 @@ class _WebQrViewState extends State<WebQrView> {
Future start() async {
await _makeCall();
_frameIntervall?.cancel();
_frameIntervall =
Timer.periodic(const Duration(milliseconds: 200), (timer) {
_frameIntervall = Timer.periodic(const Duration(milliseconds: 200), (timer) {
_captureFrame2();
});
}
Expand Down Expand Up @@ -137,8 +136,7 @@ class _WebQrViewState extends State<WebQrView> {
widget.onPermissionSet?.call(_controller!, true);
_localStream = stream;
video.srcObject = _localStream;
video.setAttribute('playsinline',
'true'); // required to tell iOS safari we don't want fullscreen
video.setAttribute('playsinline', 'true'); // required to tell iOS safari we don't want fullscreen
await video.play();
} catch (e) {
cancel();
Expand Down Expand Up @@ -177,16 +175,14 @@ class _WebQrViewState extends State<WebQrView> {
if (_localStream == null) {
return null;
}
final canvas =
html.CanvasElement(width: video.videoWidth, height: video.videoHeight);
final canvas = html.CanvasElement(width: video.videoWidth, height: video.videoHeight);
final ctx = canvas.context2D;
// canvas.width = video.videoWidth;
// canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0);
final imgData = ctx.getImageData(0, 0, canvas.width!, canvas.height!);

final size =
Size(canvas.width?.toDouble() ?? 0, canvas.height?.toDouble() ?? 0);
final size = Size(canvas.width?.toDouble() ?? 0, canvas.height?.toDouble() ?? 0);
if (size != _size) {
setState(() {
_setCanvasSize(size);
Expand All @@ -197,8 +193,7 @@ class _WebQrViewState extends State<WebQrView> {
final code = jsQR(imgData.data, canvas.width, canvas.height);
// ignore: unnecessary_null_comparison
if (code != null && code.data != null) {
_scanUpdateController
.add(Barcode(code.data, BarcodeFormat.qrcode, code.data.codeUnits));
_scanUpdateController.add(Barcode(code.data, BarcodeFormat.qrcode, code.data.codeUnits));
}
} on NoSuchMethodError {
// Do nothing, this exception occurs continously in web release when no
Expand Down Expand Up @@ -246,7 +241,7 @@ class _WebQrViewState extends State<WebQrView> {
);
}

void _setCanvasSize(ui.Size size) {
void _setCanvasSize(Size size) {
setState(() {
_size = size;
});
Expand All @@ -263,9 +258,7 @@ class QRViewControllerWeb implements QRViewController {
@override
Future<CameraFacing> flipCamera() async {
// TODO: improve error handling
_state.facing = _state.facing == CameraFacing.front
? CameraFacing.back
: CameraFacing.front;
_state.facing = _state.facing == CameraFacing.front ? CameraFacing.back : CameraFacing.front;
await _state.start();
return _state.facing;
}
Expand Down Expand Up @@ -325,9 +318,7 @@ class QRViewControllerWeb implements QRViewController {
}
}

Widget createWebQrView(
{onPlatformViewCreated, onPermissionSet, CameraFacing? cameraFacing}) =>
WebQrView(
Widget createWebQrView({onPlatformViewCreated, onPermissionSet, CameraFacing? cameraFacing}) => WebQrView(
onPlatformViewCreated: onPlatformViewCreated,
onPermissionSet: onPermissionSet,
cameraFacing: cameraFacing,
Expand Down
4 changes: 4 additions & 0 deletions lib/src/web/web_view_registry.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// ignore: avoid_web_libraries_in_flutter
import 'dart:ui_web' as ui_web;

final platformViewRegistry = ui_web.platformViewRegistry;
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ homepage: https://juliuscanute.com
repository: https://github.com/juliuscanute/qr_code_scanner

environment:
sdk: '>=2.17.0 <3.0.0'
flutter: ">=1.12.0"
sdk: '>=3.4.3 <4.0.0'
flutter: ">=1.17.0"

dependencies:
js: ^0.6.3
Expand Down