moyoung_glasses_ble_plugin 1.1.9
moyoung_glasses_ble_plugin: ^1.1.9 copied to clipboard
A comprehensive Flutter plugin for MoYoung smart glasses with 50+ features including Bluetooth communication, camera control, audio recording, file management, OTA upgrades, and AI integration.
MoYoung Glasses Flutter SDK / 魔样智能眼镜 Flutter SDK #
English #
A comprehensive Flutter plugin for communicating with MoYoung smart glasses via Bluetooth. This plugin provides a unified API for both Android and iOS platforms, wrapping the native SDKs to enable Flutter applications to seamlessly interact with MoYoung smart glasses.
Chinese #
一个全面的 Flutter 插件,用于通过蓝牙与魔样智能眼镜通信。该插件为 Android 和 iOS 平台提供了统一的 API,封装了原生 SDK,使 Flutter 应用程序能够无缝地与魔样智能眼镜交互。
Features / 功能特性 #
- 🔍 Device Scanning / 设备扫描 - Scan and discover nearby MoYoung smart glasses / 扫描并发现附近的 MoYoung 智能眼镜
- 🔗 Device Connection / 设备连接 - Connect, disconnect and reconnect to devices / 连接、断开和重连设备
- 📱 Device Control / 设备控制 - Restart, reset, shutdown devices / 重启、重置、关机
- 🔋 Battery Monitoring / 电池监控 - Real-time battery level and charging status / 实时电池电量和充电状态
- 🎥 Camera Control / 相机控制 - Photo capture with multiple modes / 拍照功能,支持多种模式
- 🎙️ Audio Recording / 音频录制 - Voice recording, PCM data streaming / 语音录制、PCM数据流
- 🖼️ AI Recognition / AI识别 - Real-time image recognition and display / 实时图像识别与显示
- 🌐 Simultaneous Interpretation / 同声传译 - Real-time translation services / 实时翻译服务
- 📊 Health Monitoring / 健康监测 - Step counting, heart rate, sleep tracking / 计步、心率、睡眠跟踪
- 👓 Wear Detection / 佩戴检测 - Detect if glasses are being worn (iOS only) / 检测眼镜是否被佩戴(仅iOS)
- 📁 File Management / 文件管理 - Upload, download, delete files with Wi-Fi connectivity / 文件上传、下载、删除,支持Wi-Fi连接
- 🔄 OTA Updates / OTA升级 - Firmware and system updates / 固件和系统升级
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
moyoung_glasses_ble_plugin: ^1.1.9
Then run:
flutter pub get
Platform Setup #
Android #
Add the following permissions to your android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
iOS #
Add the following to your ios/Runner/Info.plist:
<!-- Bluetooth permissions -->
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth access to connect with smart glasses</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs Bluetooth access to connect with smart glasses</string>
<!-- Location permission (required for Bluetooth scanning) -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs location access to scan for Bluetooth devices</string>
<!-- Wi-Fi hotspot configuration permission (required for file sync feature) -->
<key>NSHotspotConfigurationUsageDescription</key>
<string>This app needs to configure Wi-Fi hotspot to connect to your device</string>
<key>NEHotspotConfiguration</key>
<true/>
<!-- Storage permissions (required for file download feature) -->
<key>NSDocumentsFolderUsageDescription</key>
<string>This app needs access to documents folder to save downloaded files</string>
<key>NSDownloadsFolderUsageDescription</key>
<string>This app needs access to downloads folder to save media files</string>
<!-- Background modes -->
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
<string>nearby-interaction</string>
</array>
<!-- App Transport Security (allows HTTP connections for local Wi-Fi) -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Quick Start #
import 'package:moyoung_glasses_ble_plugin/moyoung_glasses_ble.dart';
class _MyAppState extends State<MyApp> {
final MoYoungGlassesBle _glasses = MoYoungGlassesBle();
@override
void initState() {
super.initState();
_initGlasses();
}
Future<void> _initGlasses() async {
// Explicit initialize (recommended on Android before BLE operations)
await _glasses.initialize();
// Check if Bluetooth is enabled
bool isEnabled = await _glasses.checkBluetoothEnable;
if (!isEnabled) {
print('Please enable Bluetooth');
return;
}
// Start scanning for devices
_glasses.startScan(10);
// Listen for scan results
_glasses.bleScanEveStm.listen((device) {
print('Found device: ${device.name} (${device.address})');
});
// Listen for connection state
_glasses.connStateEveStm.listen((state) {
print('Connection state: ${state.connectState}');
});
// Listen for battery updates
_glasses.batteryEveStm.listen((battery) {
print('Battery: ${battery['battery']}% - Charging: ${battery['charging']}');
});
}
Future<void> _connectDevice(String address) async {
bool success = await _glasses.connect('{"address":"$address"}');
if (success) {
print('Connected successfully');
}
}
}
API Reference #
Main Classes #
MoYoungGlassesBle- Main entry point for all operationsBleScanBean- Represents a scanned deviceConnectStateBean- Represents connection state
Key Methods #
Bluetooth & Scanning
// Explicit initialize (recommended on Android)
await glasses.initialize();
// Check Bluetooth status
bool isEnabled = await glasses.checkBluetoothEnable;
// Start scanning
await glasses.startScan(10); // 10 seconds
// Stop scanning
await glasses.stopScan();
Connection Management
// Connect to device
await glasses.connect('{"address":"XX:XX:XX:XX:XX:XX"}');
// Disconnect
await glasses.disconnect();
// Get connected device
String device = await glasses.connectedDevice;
Device Information
// Get battery info
Map<String, dynamic> battery = await glasses.queryBattery();
// Get device version
String version = await glasses.queryDeviceVersion();
// Sync time
await glasses.syncTime();
Photo Capture with Modes
// Take photo with different modes
await glasses.takePhoto(
photoMode: 0, // 0-Normal, 1-AI Recognition, 2-Continuous
savePath: '/path/to/save',
);
// Get TP version
String tpVersion = await glasses.getTPVersion();
Simultaneous Interpretation
// Control simultaneous interpretation
await glasses.setAudioControl(actionType: 2); // Start
await glasses.setAudioControl(actionType: 3); // Pause
await glasses.setAudioControl(actionType: 4); // Stop
await glasses.setAudioControl(actionType: 5); // Resume
// Listen to interpretation status
_glassesPlugin.audioTalkStateEveStm.listen((state) {
// 0-Stopped, 1-Started, 2-Recording,
// 3-Interpreting, 4-Paused, 5-Resumed
print('Interpretation state: $state');
});
AI Conversation Monitoring
// Listen to AI conversation events
_glassesPlugin.aiDialogueEveStm.listen((event) {
// Handle AI dialogue events
});
// Listen to PCM audio data
glasses.pcmAudioEveStm.listen((pcmData) {
// Process PCM audio bytes
});
// Listen to AI recognition images
glasses.aiImageDataEveStm.listen((imageData) {
// Display AI recognition images
// imageData contains base64 encoded image
});
Wear Detection
// Get wear detection status
Map<String, dynamic> wearState = await glasses.getWearCheckState();
bool isEnabled = wearState['enable'];
// Set wear detection state
await glasses.setWearCheckState(enable: true); // Enable
await glasses.setWearCheckState(enable: false); // Disable
Camera Control
// Take a photo
await glasses.takePhoto(photoMode: 0); // 0-Normal, 1-AI recognition, 2-Continuous
Wi-Fi Configuration
// Enable Wi-Fi with custom credentials
await glasses.enableWifi(
wifiType: 1, // 1-File sync, 2-OTA
ssid: "MyGlass", // Custom SSID (1-32 chars)
password: "password123", // Custom password (8-63 chars)
);
// Listen to Wi-Fi action results
glasses.actionResultEveStm.listen((Map<String, dynamic> result) {
int code = result['code'];
String message = result['msg'];
String? action = result['action'];
if (action == 'wifi_connection') {
if (code == 0) {
print('Wi-Fi connected successfully');
} else {
print('Wi-Fi connection failed: $message');
}
}
});
// Listen for file base URL events
glasses.fileBaseUrlEveStm.listen((String baseUrl) {
print('File base URL: $baseUrl');
});
// Disable Wi-Fi file sync mode
await glasses.disableWifi();
// Trigger file count query (count data comes from event stream)
await glasses.getFileCount();
// Listen file count updates
glasses.mediaFileCountEveStm.listen((Map<String, dynamic> count) {
print('File count => total:${count['total']} picture:${count['picture']} video:${count['video']} audio:${count['audio']}');
});
// Connect to device Wi-Fi (iOS uses NEHotspotConfiguration)
await glasses.connectToDeviceWifi();
// Download media files to specified directory
final result = await glasses.downloadMediaFilesToDir(
targetDir: '/path/to/your/download/directory',
);
print('Download result: $result');
// Listen to download progress
glasses.mediaDownloadProgress.listen((Map<String, dynamic> progress) {
int progress = progress['progress'];
String fileName = progress['fileName'];
print('Download progress: $progress% - $fileName');
});
Event Streams
// Listen to scan results
glasses.bleScanEveStm.listen((BleScanBean device) {
// Handle scanned device
});
// Listen to connection state
glasses.connStateEveStm.listen((ConnectStateBean state) {
// Handle connection changes
});
// Listen to battery updates
glasses.batteryEveStm.listen((Map<String, dynamic> battery) {
// Handle battery changes
});
For a complete list of all APIs, please visit: https://github.com/liangqian609/moyoung_glasses_ble_plugin/blob/master/moyoung_glasses_ble_plugin_example/API_LIST.md
Example App #
This repository contains a complete Flutter app demonstrating all features of the plugin. Clone the repository and run flutter run to try it out.
GitHub Repository: https://github.com/liangqian609/moyoung_glasses_ble_plugin
Requirements #
- Flutter SDK >= 3.0.0
- Android SDK >= 21 (Android 5.0)
- iOS >= 12.0
- Bluetooth LE support
iOS Configuration #
📖 详细的iOS接入指南:iOS_INTEGRATION_GUIDE.md
For detailed iOS integration guide, please visit: iOS_INTEGRATION_GUIDE.md
iOS Duplicate Class Loading Fix (Required when integrating with moyoung_ble_plugin) #
When integrating this plugin together with moyoung_ble_plugin, iOS may report runtime warnings like:
Class XXX is implemented in both .../Runner and .../CRPSmartBand.framework
To avoid duplicate class loading, add the following snippet into your app's ios/Podfile:
pre_install do |installer|
installer.pod_targets.each do |pod|
if pod.name == 'moyoung_ble_plugin'
def pod.build_type
Pod::BuildType.dynamic_framework
end
end
end
end
Then run:
pod install
Verify on a real iOS device (Release/Profile):
- no
Class XXX is implemented in both ...warnings at app startup - both glasses and watch features can connect and work normally
Support #
- GitHub Repository: https://github.com/liangqian609/moyoung_glasses_ble_plugin
- Example App: https://github.com/liangqian609/moyoung_glasses_ble_plugin (The entire repository is the example app)
- Technical Support: jack@moyoung.com
- Homepage: https://www.moyoung.com/en/
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog #
See CHANGELOG.md for a list of changes in each version.