diff --git a/README.md b/README.md index 4b076fd7..e30b49ac 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Barcode Scanner -A flutter plugin for scanning 2D barcodes and QR codes. +A flutter plugin for scanning 2D barcodes and QR codes. This provides a simple wrapper for two commonly used iOS and Android libraries: @@ -14,6 +14,7 @@ iOS: https://github.com/mikebuss/MTBBarcodeScanner Android: https://github.com/dm77/barcodescanner ### Features + - [x] Scan 2D barcodes - [x] Scan QR codes - [x] Control the flash while scanning @@ -22,15 +23,17 @@ Android: https://github.com/dm77/barcodescanner ## Getting Started ### Android + For Android, you must do the following before you can use the plugin: -* Add the camera permission to your AndroidManifest.xml - - `` +- Add the camera permission to your AndroidManifest.xml + + `` -* This plugin is written in Kotlin. Therefore, you need to add Kotlin support to your project. See [installing the Kotlin plugin](https://kotlinlang.org/docs/tutorials/kotlin-android.html#installing-the-kotlin-plugin). +- This plugin is written in Kotlin. Therefore, you need to add Kotlin support to your project. See [installing the Kotlin plugin](https://kotlinlang.org/docs/tutorials/kotlin-android.html#installing-the-kotlin-plugin). Edit your project-level build.gradle file to look like this: + ```groovy buildscript { ext.kotlin_version = '1.3.61' @@ -58,12 +61,14 @@ Now you can depend on the barcode_scan plugin in your pubspec.yaml file: ```yaml dependencies: - # ... - barcode_scan: any + # ... + barcode_scan: any ``` + Click "Packages get" in Android Studio or run `flutter packages get` in your project folder. ### iOS + To use on iOS, you must add the the camera usage description to your Info.plist ```xml @@ -75,7 +80,6 @@ To use on iOS, you must add the the camera usage description to your Info.plist ``` - ## Usage ```dart @@ -84,7 +88,7 @@ import 'package:barcode_scan/barcode_scan.dart'; void main() async { var result = await BarcodeScanner.scan(); - + print(result.type); // The result type (barcode, cancelled, failed) print(result.rawContent); // The barcode content print(result.format); // The barcode format (as enum) @@ -92,8 +96,8 @@ void main() async { } ``` - ## Advanced usage + You can pass options to the scan method: ```dart @@ -101,40 +105,45 @@ You can pass options to the scan method: import 'package:barcode_scan/barcode_scan.dart'; void main() async { - + var options = ScanOptions( // set the options ); var result = await BarcodeScanner.scan(options: options); - + // ... } ``` ### Supported options -| Option | Type | Description | Supported by | -|----------------------------|-------------------|-------------------------------------------------------------------------------------------|---------------| -| `strings.cancel` | `String` | The cancel button text on iOS | iOS only | -| `strings.flash_on` | `String` | The flash on button text | iOS + Android | -| `strings.flash_off` | `String` | The flash off button text | iOS + Android | -| `restrictFormat` | `BarcodeFormat[]` | Restrict the formats which are recognized | iOS + Android | -| `useCamera` | `int` | The index of the camera which is used for scanning (See `BarcodeScanner.numberOfCameras`) | iOS + Android | -| `autoEnableFlash` | `bool` | Enable the flash when start scanning | iOS + Android | -| `android.aspectTolerance` | `double` | Enable auto focus on Android | Android only | -| `android.useAutoFocus` | `bool` | Set aspect ratio tolerance level used in calculating the optimal Camera preview size | Android only | + +| Option | Type | Description | Supported by | +| ------------------------- | ----------------- | ----------------------------------------------------------------------------------------- | ------------- | +| `strings.cancel` | `String` | The cancel button text on iOS | iOS only | +| `strings.flash_on` | `String` | The flash on button text | iOS + Android | +| `strings.flash_off` | `String` | The flash off button text | iOS + Android | +| `restrictFormat` | `BarcodeFormat[]` | Restrict the formats which are recognized | iOS + Android | +| `useCamera` | `int` | The index of the camera which is used for scanning (See `BarcodeScanner.numberOfCameras`) | iOS + Android | +| `autoEnableFlash` | `bool` | Enable the flash when start scanning | iOS + Android | +| `android.aspectTolerance` | `double` | Enable auto focus on Android | Android only | +| `android.useAutoFocus` | `bool` | Set aspect ratio tolerance level used in calculating the optimal Camera preview size | Android only | +| `android.title` | `String` | Set title of activity | Android only | +| `android.statusbarColor` | `String` | Set statusbar color | Android only | +| `android.actionBarColor` | `String` | Set actionbar/toolbar color | Android only | ## Development setup -### Setup protobuf +### Setup protobuf Mac: + ```bash $ brew install protobuf $ brew install swift-protobuf ``` -Windows / Linux: https://github.com/protocolbuffers/protobuf#protocol-compiler-installation +Windows / Linux: https://github.com/protocolbuffers/protobuf#protocol-compiler-installation Activate the protobuf dart plugin: `$ pub global activate protoc_plugin` @@ -143,12 +152,9 @@ Install the`Protobuf Support` plugin for IDEA / Android Studio or `vscode-proto3 If you changed the protos.proto you've to execute the ./generate_proto.sh to update the dart / swift sources - - - - - ## Common problems + ### Android "Could not find org.jetbrains.kotlin:kotlin-stdlib-jre..." + Change `org.jetbrains.kotlin:kotlin-stdlib-jre` to `org.jetbrains.kotlin:kotlin-stdlib-jdk` ([StackOverflow](https://stackoverflow.com/a/53358817)) diff --git a/android/src/main/kotlin/de/mintware/barcode_scan/BarcodeScannerActivity.kt b/android/src/main/kotlin/de/mintware/barcode_scan/BarcodeScannerActivity.kt index 7e27ebe3..43571510 100644 --- a/android/src/main/kotlin/de/mintware/barcode_scan/BarcodeScannerActivity.kt +++ b/android/src/main/kotlin/de/mintware/barcode_scan/BarcodeScannerActivity.kt @@ -2,9 +2,13 @@ package de.mintware.barcode_scan import android.app.Activity import android.content.Intent +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Build import android.os.Bundle import android.view.Menu import android.view.MenuItem +import android.view.WindowManager import com.google.zxing.BarcodeFormat import com.google.zxing.Result import me.dm7.barcodescanner.zxing.ZXingScannerView @@ -46,6 +50,34 @@ class BarcodeScannerActivity : Activity(), ZXingScannerView.ResultHandler { super.onCreate(savedInstanceState) config = Protos.Configuration.parseFrom(intent.extras!!.getByteArray(EXTRA_CONFIG)) + title = config.android.title ?: "" + + val statusBarColor = try { + Color.parseColor(config.android.statusbarColor) + } catch (e: IllegalArgumentException) { + Int.MAX_VALUE + } catch (e: StringIndexOutOfBoundsException) { + Int.MAX_VALUE + } + val actionBarColor = try { + Color.parseColor(config.android.actionBarColor) + } catch (e: IllegalArgumentException) { + Int.MIN_VALUE + } catch (e: StringIndexOutOfBoundsException) { + Int.MIN_VALUE + } + + if (statusBarColor != Int.MAX_VALUE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + window?.let { + it.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) + it.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + it.statusBarColor = statusBarColor + } + } + if (actionBarColor != Int.MIN_VALUE) { + actionBar?.setBackgroundDrawable(ColorDrawable(actionBarColor)) + } + } private fun setupScannerView() { diff --git a/example/lib/main.dart b/example/lib/main.dart index 3a984bbd..859091d7 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -252,9 +252,11 @@ class _MyAppState extends State<_MyApp> { useCamera: _selectedCamera, autoEnableFlash: _autoEnableFlash, android: AndroidOptions( - aspectTolerance: _aspectTolerance, - useAutoFocus: _useAutoFocus, - ), + aspectTolerance: _aspectTolerance, + useAutoFocus: _useAutoFocus, + title: "Flutter Barcode Reader", + statusbarColor: "#e67e22", + actionBarColor: "#f1c40f"), ); var result = await BarcodeScanner.scan(options: options); diff --git a/ios/Classes/protos/protos.pb.swift b/ios/Classes/protos/protos.pb.swift index c53ec028..cbd3f3e5 100644 --- a/ios/Classes/protos/protos.pb.swift +++ b/ios/Classes/protos/protos.pb.swift @@ -1,4 +1,5 @@ // DO NOT EDIT. +// swift-format-ignore-file // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: protos/protos.proto @@ -16,7 +17,7 @@ import SwiftProtobuf // If the compiler emits an error on this type, it is because this file // was generated by a version of the `protoc` Swift plug-in that is // incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that your are building against the same version of the API +// Please ensure that you are building against the same version of the API // that was used to generate this file. fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} @@ -165,6 +166,18 @@ struct AndroidConfiguration { /// This parameter is only supported on Android devices. var useAutoFocus: Bool = false + //// Change the title of activities + //// This parameter is only supported on Android devices. + var title: String = String() + + //// Set statusbar color + //// This parameter is only supported on Android devices. + var statusbarColor: String = String() + + //// Set actionBar color + //// This parameter is only supported on Android devices. + var actionBarColor: String = String() + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -177,44 +190,32 @@ struct Configuration { // methods supported on all messages. /// Strings which are displayed to the user - var strings: Dictionary { - get {return _storage._strings} - set {_uniqueStorage()._strings = newValue} - } + var strings: Dictionary = [:] /// Restricts the barcode format which should be read - var restrictFormat: [BarcodeFormat] { - get {return _storage._restrictFormat} - set {_uniqueStorage()._restrictFormat = newValue} - } + var restrictFormat: [BarcodeFormat] = [] /// Index of the camera which should used. -1 uses the default camera - var useCamera: Int32 { - get {return _storage._useCamera} - set {_uniqueStorage()._useCamera = newValue} - } + var useCamera: Int32 = 0 /// Android specific configuration var android: AndroidConfiguration { - get {return _storage._android ?? AndroidConfiguration()} - set {_uniqueStorage()._android = newValue} + get {return _android ?? AndroidConfiguration()} + set {_android = newValue} } /// Returns true if `android` has been explicitly set. - var hasAndroid: Bool {return _storage._android != nil} + var hasAndroid: Bool {return self._android != nil} /// Clears the value of `android`. Subsequent reads from it will return its default value. - mutating func clearAndroid() {_uniqueStorage()._android = nil} + mutating func clearAndroid() {self._android = nil} /// Set to true to automatically enable flash on camera start - var autoEnableFlash: Bool { - get {return _storage._autoEnableFlash} - set {_uniqueStorage()._autoEnableFlash = newValue} - } + var autoEnableFlash: Bool = false var unknownFields = SwiftProtobuf.UnknownStorage() init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _android: AndroidConfiguration? = nil } struct ScanResult { @@ -272,13 +273,22 @@ extension AndroidConfiguration: SwiftProtobuf.Message, SwiftProtobuf._MessageImp static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "aspectTolerance"), 2: .same(proto: "useAutoFocus"), + 3: .same(proto: "title"), + 4: .same(proto: "statusbarColor"), + 5: .same(proto: "actionBarColor"), ] mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularDoubleField(value: &self.aspectTolerance) - case 2: try decoder.decodeSingularBoolField(value: &self.useAutoFocus) + case 1: try { try decoder.decodeSingularDoubleField(value: &self.aspectTolerance) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.useAutoFocus) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.title) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.statusbarColor) }() + case 5: try { try decoder.decodeSingularStringField(value: &self.actionBarColor) }() default: break } } @@ -291,12 +301,24 @@ extension AndroidConfiguration: SwiftProtobuf.Message, SwiftProtobuf._MessageImp if self.useAutoFocus != false { try visitor.visitSingularBoolField(value: self.useAutoFocus, fieldNumber: 2) } + if !self.title.isEmpty { + try visitor.visitSingularStringField(value: self.title, fieldNumber: 3) + } + if !self.statusbarColor.isEmpty { + try visitor.visitSingularStringField(value: self.statusbarColor, fieldNumber: 4) + } + if !self.actionBarColor.isEmpty { + try visitor.visitSingularStringField(value: self.actionBarColor, fieldNumber: 5) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: AndroidConfiguration, rhs: AndroidConfiguration) -> Bool { if lhs.aspectTolerance != rhs.aspectTolerance {return false} if lhs.useAutoFocus != rhs.useAutoFocus {return false} + if lhs.title != rhs.title {return false} + if lhs.statusbarColor != rhs.statusbarColor {return false} + if lhs.actionBarColor != rhs.actionBarColor {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -312,84 +334,47 @@ extension Configuration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa 5: .same(proto: "autoEnableFlash"), ] - fileprivate class _StorageClass { - var _strings: Dictionary = [:] - var _restrictFormat: [BarcodeFormat] = [] - var _useCamera: Int32 = 0 - var _android: AndroidConfiguration? = nil - var _autoEnableFlash: Bool = false - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _strings = source._strings - _restrictFormat = source._restrictFormat - _useCamera = source._useCamera - _android = source._android - _autoEnableFlash = source._autoEnableFlash - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - switch fieldNumber { - case 1: try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: &_storage._strings) - case 2: try decoder.decodeRepeatedEnumField(value: &_storage._restrictFormat) - case 3: try decoder.decodeSingularInt32Field(value: &_storage._useCamera) - case 4: try decoder.decodeSingularMessageField(value: &_storage._android) - case 5: try decoder.decodeSingularBoolField(value: &_storage._autoEnableFlash) - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: &self.strings) }() + case 2: try { try decoder.decodeRepeatedEnumField(value: &self.restrictFormat) }() + case 3: try { try decoder.decodeSingularInt32Field(value: &self.useCamera) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._android) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.autoEnableFlash) }() + default: break } } } func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if !_storage._strings.isEmpty { - try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: _storage._strings, fieldNumber: 1) - } - if !_storage._restrictFormat.isEmpty { - try visitor.visitPackedEnumField(value: _storage._restrictFormat, fieldNumber: 2) - } - if _storage._useCamera != 0 { - try visitor.visitSingularInt32Field(value: _storage._useCamera, fieldNumber: 3) - } - if let v = _storage._android { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } - if _storage._autoEnableFlash != false { - try visitor.visitSingularBoolField(value: _storage._autoEnableFlash, fieldNumber: 5) - } + if !self.strings.isEmpty { + try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: self.strings, fieldNumber: 1) + } + if !self.restrictFormat.isEmpty { + try visitor.visitPackedEnumField(value: self.restrictFormat, fieldNumber: 2) + } + if self.useCamera != 0 { + try visitor.visitSingularInt32Field(value: self.useCamera, fieldNumber: 3) + } + if let v = self._android { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } + if self.autoEnableFlash != false { + try visitor.visitSingularBoolField(value: self.autoEnableFlash, fieldNumber: 5) } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: Configuration, rhs: Configuration) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._strings != rhs_storage._strings {return false} - if _storage._restrictFormat != rhs_storage._restrictFormat {return false} - if _storage._useCamera != rhs_storage._useCamera {return false} - if _storage._android != rhs_storage._android {return false} - if _storage._autoEnableFlash != rhs_storage._autoEnableFlash {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.strings != rhs.strings {return false} + if lhs.restrictFormat != rhs.restrictFormat {return false} + if lhs.useCamera != rhs.useCamera {return false} + if lhs._android != rhs._android {return false} + if lhs.autoEnableFlash != rhs.autoEnableFlash {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -406,11 +391,14 @@ extension ScanResult: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try decoder.decodeSingularEnumField(value: &self.type) - case 2: try decoder.decodeSingularStringField(value: &self.rawContent) - case 3: try decoder.decodeSingularEnumField(value: &self.format) - case 4: try decoder.decodeSingularStringField(value: &self.formatNote) + case 1: try { try decoder.decodeSingularEnumField(value: &self.type) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.rawContent) }() + case 3: try { try decoder.decodeSingularEnumField(value: &self.format) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.formatNote) }() default: break } } diff --git a/lib/gen/protos/protos.pb.dart b/lib/gen/protos/protos.pb.dart index ad69181b..f1c44fda 100644 --- a/lib/gen/protos/protos.pb.dart +++ b/lib/gen/protos/protos.pb.dart @@ -17,6 +17,9 @@ class AndroidConfiguration extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo('AndroidConfiguration', createEmptyInstance: create) ..a<$core.double>(1, 'aspectTolerance', $pb.PbFieldType.OD, protoName: 'aspectTolerance') ..aOB(2, 'useAutoFocus', protoName: 'useAutoFocus') + ..aOS(3, 'title') + ..aOS(4, 'statusbarColor', protoName: 'statusbarColor') + ..aOS(5, 'actionBarColor', protoName: 'actionBarColor') ..hasRequiredFields = false ; @@ -52,6 +55,33 @@ class AndroidConfiguration extends $pb.GeneratedMessage { $core.bool hasUseAutoFocus() => $_has(1); @$pb.TagNumber(2) void clearUseAutoFocus() => clearField(2); + + @$pb.TagNumber(3) + $core.String get title => $_getSZ(2); + @$pb.TagNumber(3) + set title($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasTitle() => $_has(2); + @$pb.TagNumber(3) + void clearTitle() => clearField(3); + + @$pb.TagNumber(4) + $core.String get statusbarColor => $_getSZ(3); + @$pb.TagNumber(4) + set statusbarColor($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasStatusbarColor() => $_has(3); + @$pb.TagNumber(4) + void clearStatusbarColor() => clearField(4); + + @$pb.TagNumber(5) + $core.String get actionBarColor => $_getSZ(4); + @$pb.TagNumber(5) + set actionBarColor($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasActionBarColor() => $_has(4); + @$pb.TagNumber(5) + void clearActionBarColor() => clearField(5); } class Configuration extends $pb.GeneratedMessage { diff --git a/lib/gen/protos/protos.pbjson.dart b/lib/gen/protos/protos.pbjson.dart index 958b3c14..ae2c7e79 100644 --- a/lib/gen/protos/protos.pbjson.dart +++ b/lib/gen/protos/protos.pbjson.dart @@ -37,6 +37,9 @@ const AndroidConfiguration$json = const { '2': const [ const {'1': 'aspectTolerance', '3': 1, '4': 1, '5': 1, '10': 'aspectTolerance'}, const {'1': 'useAutoFocus', '3': 2, '4': 1, '5': 8, '10': 'useAutoFocus'}, + const {'1': 'title', '3': 3, '4': 1, '5': 9, '10': 'title'}, + const {'1': 'statusbarColor', '3': 4, '4': 1, '5': 9, '10': 'statusbarColor'}, + const {'1': 'actionBarColor', '3': 5, '4': 1, '5': 9, '10': 'actionBarColor'}, ], }; diff --git a/lib/model/android_options.dart b/lib/model/android_options.dart index 1733fd9b..750b1d15 100644 --- a/lib/model/android_options.dart +++ b/lib/model/android_options.dart @@ -9,10 +9,28 @@ class AndroidOptions { /// This parameter is only supported on Android devices. final bool useAutoFocus; + /// Change the title of activities + /// This parameter is only supported on Android devices. + final String title; + + /// Set statusbar color + /// This parameter is only supported on Android devices. + final String statusbarColor; + + /// Set actionBar color + /// This parameter is only supported on Android devices. + final String actionBarColor; + /// Create Android specific scan options const AndroidOptions({ this.aspectTolerance = 0.5, this.useAutoFocus = true, + this.title = "", + this.statusbarColor = "#000000", + this.actionBarColor = "#000000", }) : assert(aspectTolerance != null), - assert(useAutoFocus != null); + assert(useAutoFocus != null), + assert(title != null), + assert(statusbarColor != null), + assert(actionBarColor != null); } diff --git a/lib/platform_wrapper.dart b/lib/platform_wrapper.dart index 96643e2c..70f3713c 100644 --- a/lib/platform_wrapper.dart +++ b/lib/platform_wrapper.dart @@ -72,6 +72,9 @@ class BarcodeScanner { ..android = (proto.AndroidConfiguration() ..useAutoFocus = options.android.useAutoFocus ..aspectTolerance = options.android.aspectTolerance + ..title = options.android.title + ..statusbarColor = options.android.statusbarColor + ..actionBarColor = options.android.actionBarColor /**/) /**/; var buffer = await _channel.invokeMethod('scan', config?.writeToBuffer()); diff --git a/protos/android_configuration.proto b/protos/android_configuration.proto index 286e5aeb..7797638b 100644 --- a/protos/android_configuration.proto +++ b/protos/android_configuration.proto @@ -12,4 +12,16 @@ message AndroidConfiguration { // Set to true to enable auto focus // This parameter is only supported on Android devices. bool useAutoFocus = 2; + + /// Change the title of activities + /// This parameter is only supported on Android devices. + string title = 3; + + /// Set statusbar color + /// This parameter is only supported on Android devices. + string statusbarColor = 4; + + /// Set actionBar color + /// This parameter is only supported on Android devices. + string actionBarColor = 5; } \ No newline at end of file diff --git a/protos/protos.proto b/protos/protos.proto index cf508b67..0813cc36 100644 --- a/protos/protos.proto +++ b/protos/protos.proto @@ -15,6 +15,15 @@ message AndroidConfiguration { // Set to true to enable auto focus // This parameter is only supported on Android devices. bool useAutoFocus = 2; + /// Change the title of activities + /// This parameter is only supported on Android devices. + string title = 3; + /// Set statusbar color + /// This parameter is only supported on Android devices. + string statusbarColor = 4; + /// Set actionBar color + /// This parameter is only supported on Android devices. + string actionBarColor = 5; } // protos/barcode_format.proto