Flutter轮胎胎纹识别插件anyline_tire_tread_plugin的使用
Flutter轮胎胎纹识别插件anyline_tire_tread_plugin的使用
本Flutter插件提供了对Anyline轮胎胎纹SDK的接口,允许你在Flutter应用中集成轮胎胎纹扫描功能。
要求
Android
- Android 8.0(Oreo)或更高版本(API级别26+)
- 良好的摄像头功能(推荐:≥ 720p且具备良好的自动对焦)
- 具备闪光灯功能
- 稳定的互联网连接
iOS
- iOS版本 >= 16.4
- 稳定的互联网连接
- 具备闪光灯功能
Anyline轮胎胎纹Flutter插件指南
在本指南中,我们将向你展示如何充分利用Anyline轮胎胎纹插件。如果你觉得本指南不完整或某些部分需要进一步解释,请随时联系我们。
获取Anyline许可证
为了能够使用该Flutter插件,你需要按照我们的文档中的步骤获取一个许可证密钥。
安装Anyline轮胎胎纹插件
在pubspec.yaml
文件中添加以下依赖:
dependencies:
anyline_tire_tread_plugin: ^x.y.z
将Anyline轮胎胎纹SDK作为依赖项添加
要将Anyline轮胎胎纹SDK集成到你的Android项目中,请按以下步骤操作:
- 在Android Studio中打开你的项目。
- 找到项目的
build.gradle
文件。该文件通常位于项目的根目录下。 - 向你的
repositories
块中添加Anyline Maven仓库,以使项目能够访问指定Maven仓库中的Anyline轮胎胎纹SDK。更新你的repositories
块以包含Anyline Maven仓库URL:
repositories {
// ... 你的其他仓库 ...
mavenCentral()
// Anyline Maven仓库
maven { url "https://europe-maven.pkg.dev/anyline-ttr-sdk/maven" }
}
通过pub.dev安装
从命令行安装包依赖项:
flutter pub get
或者,你可以使用IDE支持的flutter pub get
命令。查阅其文档了解更多信息。
导入Anyline到你的Flutter项目
现在,在你的Dart代码中导入Anyline:
import 'package:anyline_tire_tread_plugin/anyline_tire_tread_plugin.dart';
通过此导入,你可以使用TireTreadPlugin
类来调用SDK方法并执行扫描功能。接下来,创建该类的一个实例:
var tireTreadPlugin = TireTreadPlugin();
初始化SDK
在应用程序启动时,在调用任何其他插件方法之前,通过调用插件对象的initialize
方法并提供你的许可证密钥来初始化Anyline轮胎胎纹SDK:
try {
await tireTreadPlugin.initialize(licenseKey);
} catch (error) {
print("初始化Anyline轮胎胎纹SDK时出错: $error");
}
开始扫描
通过TireTreadPlugin
实例调用scan
方法,并传入配置选项:
scanWithAnyline() async {
tireTreadPlugin.scan(options: ScanOptions());
}
音频反馈
轮胎胎纹插件可以提供音频反馈来指导用户完成扫描过程。
要在你的应用中使用这些音频反馈,需要在以下文件夹内提供音频文件:
- 对于iOS:
path_to_plugin_root_folder/example/ios/Resources
- 对于Android:
path_to_plugin_root_folder/example/android/app/src/main/assets
在iOS/Android上播放的音频反馈(及其对应的文件名)包括:
- 聚焦点找到时
tiretread_focuspoint_found.wav
- 扫描开始时
tiretread_sound_start.wav
- 扫描停止时
tiretread_sound_stop.wav
- 手机距离轮胎太近时
tiretread_sound_beep_too_close.wav
- 手机距离轮胎太远时
tiretread_sound_beep_too_far.wav
SDK仅支持这些文件名和.wav扩展名。
配置扫描行为
你可以通过传递一个ScanOptions
对象来自定义扫描行为:
tireTreadPlugin.scan(options: ScanOptions());
一个未设置参数的ScanOptions
对象包含一些默认值,可以帮助你快速开始使用。
如果你想自定义扫描速度(快或慢)和测量系统(公制或英制单位),可以这样做:
var scanOptions = ScanOptions(measurementSystem: MeasurementSystem.Imperial, scanSpeed: ScanSpeed.Fast);
tireTreadPlugin.scan(options: scanOptions);
或者,你可以提供一个包含SDK轮胎胎纹扫描视图配置JSON的字符串给ScanOptions
对象,例如:
const configJSON = '{
"scanSpeed": "Fast",
"measurementSystem": "Metric",
...
}';
tireTreadPlugin.scan(options: ScanOptions(configFileContent: configJSON));
更多关于JSON配置的信息可以在这里找到:https://documentation.anyline.com/tiretreadsdk-component/latest/scanconfiguration.html
处理SDK的事件
通过TireTreadPlugin
实例调用onScanningEvent
来处理SDK的事件:
tireTreadPlugin.onScanningEvent.listen((event) {
switch (event) {
case ScanAborted():
debugPrint('测量UUID : ${event.measurementUUID}');
case UploadAborted():
debugPrint('测量UUID : ${event.measurementUUID}');
case UploadCompleted():
debugPrint('测量UUID : ${event.measurementUUID}');
setState(() => _uuid = event.measurementUUID ?? '');
case UploadFailed():
debugPrint('测量UUID : ${event.error}');
}
});
结果
获取测量结果
在上传扫描帧完成后(即UploadCompletedEvent
),你的测量结果可能需要几秒钟才能可用。要获取结果,调用getResult
函数:
String result = await tireTreadPlugin.getResult(measurementUUID: measurementUUID);
分析
热力图
在上传扫描帧完成后(即UploadCompletedEvent
),你的热力图结果可能需要几秒钟才能可用。要获取热力图,调用getHeatMap
函数:
String heatmap = await tireTreadPlugin.getHeatMap(measurementUUID: measurementUUID);
示例代码
以下是示例代码,展示了如何在Flutter应用中使用Anyline轮胎胎纹插件:
import 'dart:convert';
import 'package:anyline_tire_tread_plugin/anyline_tire_tread_plugin.dart';
import 'package:anyline_tire_tread_plugin_example/app_colors.dart';
import 'package:anyline_tire_tread_plugin_example/device_details_widget.dart';
import 'package:anyline_tire_tread_plugin_example/env_info.dart';
import 'package:anyline_tire_tread_plugin_example/initalize_dialog.dart';
import 'package:anyline_tire_tread_plugin_example/widgets.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
enum InitializationStatus { start, pending, done, fail }
void main() {
EnvInfo.initialize();
runApp(const AnylineTireTreadPluginExample());
}
class AnylineTireTreadPluginExample extends StatefulWidget {
const AnylineTireTreadPluginExample({super.key});
[@override](/user/override)
State<AnylineTireTreadPluginExample> createState() => _AnylineTireTreadPluginExampleState();
}
class _AnylineTireTreadPluginExampleState extends State<AnylineTireTreadPluginExample> {
bool showLoader = false;
static GlobalKey<ScaffoldMessengerState> snackBarKey = GlobalKey<ScaffoldMessengerState>();
String _uuid = '';
String _result = '';
String _heatmap = '';
ValueNotifier<InitializationStatus> initializationStatus = ValueNotifier(InitializationStatus.pending);
final TireTreadPlugin _tireTreadPlugin = TireTreadPlugin();
final GlobalKey heatMapViewKey = GlobalKey();
final GlobalKey resultViewKey = GlobalKey();
final ScrollController scrollController = ScrollController();
[@override](/user/override)
void initState() {
_tireTreadPlugin.onScanningEvent.listen((event) {
switch (event) {
case ScanAborted():
debugPrint('UUID : ${event.measurementUUID}');
case UploadAborted():
debugPrint('UUID : ${event.measurementUUID}');
case UploadCompleted():
debugPrint('UUID : ${event.measurementUUID}');
setState(() => _uuid = event.measurementUUID ?? '');
case UploadFailed():
debugPrint('UUID : ${event.error}');
}
});
super.initState();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
scaffoldMessengerKey: snackBarKey,
home: Scaffold(
backgroundColor: const Color(0xFF000000),
appBar: AppBar(
backgroundColor: const Color(0xFF000000),
title: const Text(
'Anyline轮胎胎纹插件示例',
style: TextStyle(color: AppColors.primary),
),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Center(
child: Column(
children: [
ValueListenableBuilder(
valueListenable: initializationStatus,
builder: (context, status, _) {
return Expanded(
child: SingleChildScrollView(
controller: scrollController,
child: Column(
children: [
AppButton(
onPressed: (status != InitializationStatus.start)
? () async {
EnvInfo.runTimeLicenseKey = EnvInfo.licenseKey ?? '';
showDialog<void>(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return Dialog(
backgroundColor: Colors.white,
child: InitializeDialog(
onCancel: () {
Navigator.pop(context);
}, onDone: (licenseKey) async {
EnvInfo.runTimeLicenseKey = licenseKey;
Navigator.of(context).pop();
setState(() {
_uuid = '';
_result = '';
});
await startInitialization();
}),
);
},
);
}
: null,
title: '初始化'),
sizedBox,
AppButton(
onPressed: (status == InitializationStatus.done)
? () {
try {
setState(() {
_uuid = '';
_result = '';
_heatmap = '';
});
_tireTreadPlugin.scan(options: ScanOptions());
} on PlatformException catch (error) {
if (kDebugMode) {
print(error);
}
}
}
: null,
title: '扫描'),
sizedBox,
AppButton(
onPressed: (status == InitializationStatus.done && _uuid.isNotEmpty)
? () async {
try {
setState(() {
showLoader = true;
});
Scrollable.ensureVisible(resultViewKey.currentContext!, duration: const Duration(milliseconds: 300));
_result = (await _tireTreadPlugin.getResult(measurementUUID: _uuid))!;
} on PlatformException catch (error) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(error.details as String)));
}
} finally {
setState(() {
showLoader = false;
});
}
}
: null,
title: '获取结果'),
sizedBox,
AppButton(
onPressed: (status == InitializationStatus.done && _uuid.isNotEmpty)
? () async {
try {
setState(() {
showLoader = true;
});
Scrollable.ensureVisible(heatMapViewKey.currentContext!, duration: const Duration(milliseconds: 300));
_heatmap = (await _tireTreadPlugin.getHeatMap(measurementUUID: _uuid))!;
} on PlatformException catch (error) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(error.details as String)));
}
} finally {
setState(() {
showLoader = false;
});
}
}
: null,
title: '获取热力图'),
sizedBox,
initializationStatusView(status),
sizedBox,
if (_uuid.isNotEmpty)
Text(
'UUID: $_uuid',
style: const TextStyle(fontSize: 16, color: AppColors.primary),
),
sizedBox,
if (showLoader)
const SizedBox(
height: 40,
width: 40,
child: CircularProgressIndicator(color: AppColors.primary)),
sizedBox,
Image.network(
_heatmap,
key: heatMapViewKey,
errorBuilder: (
context,
_,
__,
) {
return const SizedBox();
},
),
sizedBox,
Text(
(_result.isNotEmpty)
? '结果: ${const JsonEncoder.withIndent(' ').convert(jsonDecode(_result))}'
: '',
key: resultViewKey,
style: const TextStyle(fontSize: 16, color: AppColors.primary),
),
],
),
),
);
}),
pluginDetailsWidget(),
const DeviceDetailsWidget()
],
),
),
),
),
),
);
}
Future<void> startInitialization() async {
try {
setState(() {
_uuid = '';
showLoader = true;
});
initializationStatus.value = InitializationStatus.start;
await _tireTreadPlugin.initialize(EnvInfo.licenseKey ?? '');
initializationStatus.value = InitializationStatus.done;
} on PlatformException catch (error) {
initializationStatus.value = InitializationStatus.fail;
snackBarKey.currentState?.showSnackBar(SnackBar(content: Text(error.details as String)));
} finally {
setState(() {
showLoader = false;
});
}
}
Column pluginDetailsWidget() {
return Column(
children: [
FutureBuilder(
future: _tireTreadPlugin.sdkVersion,
builder: (context, snap) {
if (snap.hasData) {
return Text('SDK版本: ${snap.data}', style: const TextStyle(fontSize: 14, color: AppColors.primary));
}
return const SizedBox.shrink();
}),
FutureBuilder(
future: _tireTreadPlugin.pluginVersion,
builder: (context, snap) {
if (snap.hasData) {
return Text('插件版本: ${snap.data}', style: const TextStyle(fontSize: 14, color: AppColors.primary));
}
return const SizedBox.shrink();
}),
],
);
}
Widget initializationStatusView(InitializationStatus status) {
String message = '';
if (status == InitializationStatus.pending) {
message = '待定';
} else if (status == InitializationStatus.start) {
message = '开始';
} else if (status == InitializationStatus.fail) {
message = '失败';
} else {
message = '成功';
}
return Text(
'初始化结果: $message',
style: const TextStyle(fontSize: 16, color: AppColors.primary),
);
}
}
更多关于Flutter轮胎胎纹识别插件anyline_tire_tread_plugin的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter轮胎胎纹识别插件anyline_tire_tread_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用anyline_tire_tread_plugin
插件的一个基本示例。请注意,这个插件是假设存在的,用于轮胎胎纹识别的自定义插件。在实际使用中,你可能需要替换为真实的插件名称或者进行必要的调整。
首先,确保你的Flutter项目已经创建。如果还没有创建,可以使用以下命令创建一个新的Flutter项目:
flutter create tire_tread_recognition_app
cd tire_tread_recognition_app
接下来,假设anyline_tire_tread_plugin
已经在pub.dev
上发布(实际上你需要使用真实的插件名称或者从私有源安装),在pubspec.yaml
文件中添加依赖:
dependencies:
flutter:
sdk: flutter
anyline_tire_tread_plugin: ^1.0.0 # 假设的版本号,实际使用时请替换为最新版本
然后运行flutter pub get
来安装依赖。
安装完成后,你可以开始在你的Flutter应用中使用这个插件。以下是一个简单的示例代码,展示了如何使用anyline_tire_tread_plugin
进行轮胎胎纹识别:
import 'package:flutter/material.dart';
import 'package:anyline_tire_tread_plugin/anyline_tire_tread_plugin.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tire Tread Recognition App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String result = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tire Tread Recognition'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Scan a tire tread image to recognize its pattern',
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
// 打开图像选择器或相机以获取图像
var imageFile = await ImagePicker().pickImage(source: ImageSource.camera);
if (imageFile != null) {
// 使用插件进行轮胎胎纹识别
var recognitionResult = await AnylineTireTreadPlugin.recognizeTireTread(imageFile.path);
setState(() {
result = recognitionResult?.toJson()?.toString() ?? 'Recognition failed';
});
}
},
child: Text('Scan Tire Tread'),
),
SizedBox(height: 20),
Text(
result,
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
],
),
),
);
}
}
在这个示例中,我们使用了ImagePicker
插件来选择图像(可以从相机或图库中选择)。然后,我们使用假设的AnylineTireTreadPlugin.recognizeTireTread
方法来处理图像并获取识别结果。请注意,AnylineTireTreadPlugin
和它的recognizeTireTread
方法是假设存在的,你需要根据实际的插件API进行调整。
此外,由于ImagePicker
插件不是Flutter SDK的一部分,你还需要在pubspec.yaml
文件中添加它的依赖:
dependencies:
flutter:
sdk: flutter
image_picker: ^0.8.4+4 # 假设的版本号,实际使用时请替换为最新版本
anyline_tire_tread_plugin: ^1.0.0 # 假设的版本号,实际使用时请替换为最新版本
然后再次运行flutter pub get
来安装依赖。
请注意,上述代码是一个简化的示例,用于说明如何使用一个假设的轮胎胎纹识别插件。在实际应用中,你可能需要处理更多的错误情况、优化用户体验,并根据实际的插件API文档进行调整。