Есть ли способ сканирования штрих-кодов в Flutter?
По сути, я делаю приложение, которое сканирует QR-код для подключения к серверу. Затем приложение отсканирует штрих-код продуктов, сделает снимки товара и отправит их на сервер. Мой вопрос заключается в следующем:
Существует ли плагин Flutter для сканирования QR-кодов и штрих-кодов, который не вступает в конфликт с image_picker
?
Вот что я нашел до сих пор.
Я ценю любую помощь, которую вы можете оказать. Спасибо!
Обновить
Проблема с barcode_scan
была решена. Я закончил тем, что использовал этот, так как он быстрее, чем принятый ответ, и его проблемы решаются довольно быстро Имейте в виду, что его поведение на iOS изменено Apple, поэтому вы можете получить другие результаты с номерами контрольных сумм или чем-то еще.
Ответы
Ответ 1
У меня раньше была похожая проблема, и после поиска, как и вы, я не нашел много. Я решил, что лучшим подходом было бы написать сам плагин... так что постыдный плагин для моего плагина здесь = D, не то чтобы я извлек выгоду из того, что кто-то еще его вообще использует.
Вы можете увидеть это здесь. Однако у меня не было времени документировать это, тщательно тестировать или публиковать в пабе должным образом. Так что ваш пробег может отличаться. Тем не менее, он должен работать на Android 4. 4+ (и, возможно, ниже), а также на устройствах iOS, которые поддерживаются. Я также не тестировал его в сочетании с плагином Camera, но не понимаю, почему с ним могут возникнуть проблемы.
Он использует другой подход, чем большинство других плагинов кода qr; вместо того, чтобы создавать окно Android или iOS, выполнять сканирование, а затем возвращаться к флаттеру, он использует возможности рендеринга текстур флаттера, чтобы камера рендерилась прямо в флаттер.
Еще несколько вещей, которые следует учитывать, это то, что он использует Google Mobile Vision SDK с соответствующими лицензиями и возможностями, которые прилагаются к нему (и требует последней версии Play Services на Android); и что в настоящее время он поддерживает только самое основное извлечение информации из сканирования штрих-кода - мне нужен был только необработанный текст, чтобы все, что я сделал.
Чтобы использовать это, добавьте это в ваш pubspec.yaml:
dependencies:
qr_mobile_vision: '^0.0.7'
И реализовать следующим образом:
import 'package:qr_mobile_vision/QrCamera.dart';
...
new Container(
constraints: new BoxConstraints.loose(
new Size(cameraSize, cameraSize)),
child: new QrCamera(
qrCodeCallback: (code) {
print(code);
}
),
)
Я планирую закончить документацию/тестирование/и т.д. в конце концов, но вы можете попробовать это в то же время. Если вы решите использовать его и нуждаетесь в функции, которую он не поддерживает, я могу помочь в ее реализации... но PR приветствуются и поощряются!
ОБНОВЛЕНИЕ: теперь это включает поддержку штрих-кода. Вы можете указать, какие типы QR-кодов/штрих-кодов вы хотите поддерживать при создании экземпляра QrCamera. По умолчанию используется значение all, которое требует больше обработки, поэтому, если вам нужен определенный тип, рекомендуется передать его.
Ответ 2
Я работаю над тем, что в настоящее время является компаньоном моего плагина генерации QR (https://github.com/lukef/qr.flutter), но у меня нет конкретные сроки, к сожалению.
Мой план состоит в том, чтобы использовать объект Texture
и подключить камеру (или использовать fork/использовать плагин камеры), а затем использовать API Google Vision (https://developers.google.com/vision/android/barcodes-overview).
Это должно быть прилично тривиально, мне просто нужно найти время. В любом случае, это был план, если вы хотите это сделать:)
Ответ 3
В проекте Flutter можно использовать SDK с открытым исходным кодом (например, ZXing) или коммерческий SDK (например, SDK ). Реализация функции сканирования штрих-кода проста.
Я написал статью - Программирование флаттера с файлом Android AAR, в котором говорится, как сканировать QR-код в проекте флаттера. исходный код также доступен на GitHub.
Java-код
private String onGetBarcode(String json) {
String filename;
try {
JSONObject message = new JSONObject(json);
filename = message.getString("filename");
} catch (JSONException e) {
Log.e(TAG, "JSON exception", e);
return null;
}
String locationProvider;
String barcodeResult = "No barcode detected";
File file = new File(filename);
if (!file.exists()) {
barcodeResult = "No file exists: " + file.toString();
Toast.makeText(BarcodeReaderActivity.this, barcodeResult, Toast.LENGTH_LONG).show();
return null;
}
else {
Bitmap bitmap = BitmapFactory.decodeFile(file.toString());
BarcodeReader reader = new BarcodeReader("license");
ReadResult result = reader.readSingle(bitmap, Barcode.QR_CODE);
Barcode[] all = result.barcodes;
if (all != null && all.length == 1) {
barcodeResult = all[0].displayValue;
}
else {
barcodeResult = "no barcode found: " + file.toString();
}
bitmap.recycle();
}
JSONObject reply = new JSONObject();
try {
if (barcodeResult != null) {
reply.put("result", barcodeResult);
} else {
reply.put("result", "No barcode detected");
}
} catch (JSONException e) {
Log.e(TAG, "JSON exception", e);
return null;
}
return reply.toString();
}
Код дротика
@override
Widget build(BuildContext context) {
if (_isExisted) {
return new Material(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Text('Barcode Reader'),
new Input(
labelText: 'Please input the image path',
value: new InputValue(text: _filename),
onChanged: onTextChanged,
autofocus: true,
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new RaisedButton(
child: new Text('Read'),
onPressed: _getBarcode
),
new RaisedButton(
child: new Text('Reset'),
onPressed: _resetResult
),
]
),
new Image.file(new File(_filename)),
new Text('$_result'),
]
)
)
);
}
else {
return new Material(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Text('Barcode Reader'),
new Input(
labelText: 'Please input the image path',
onChanged: onTextChanged,
autofocus: true,
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new RaisedButton(
child: new Text('Read'),
onPressed: _getBarcode
),
new RaisedButton(
child: new Text('Reset'),
onPressed: _resetResult
),
]
),
new Text('$_result'),
]
)
)
);
}
}
Future<Null> _readBarcode() async {
final Map<String, String> message = <String, String>{'filename':_filename};
final Map<String, dynamic> reply = await HostMessages.sendJSON('getBarcode', message);
// If the widget was removed from the tree while the message was in flight,
// we want to discard the reply rather than calling setState to update our
// non-existent appearance.
if (!mounted)
return;
setState(() {
_result = reply['result'].toString();
});
}
Скриншот
![введите описание изображения здесь]()
Поймите немного времени и сделайте это сами:)