Appearance
Overview
- File:
lib/main.dart
The main.dart file serves as the entry point for the HVC XR application, handling initialization, configuration, and setup of core components. This document provides a detailed explanation of the file's structure and functionality.
Global Variables
dart
bool isProd = true;
late String deviceId;
late String deviceType;
late String deviceAgent;
late bool isDeviceHmt, isNavigator500, isCimo, isDigiLens;
late PackageInfo appInfo;
RxBool isInCall = false.obs;
DbManager? dbManager;
HippoDBManager? hippoDBManager;
Logger log = Logger('HVC_XR_LOGGER');Variable Descriptions
isProd: Production environment flagdeviceId: Unique identifier for the devicedeviceType: Type of device (e.g., HMT-1, Navigator 500)deviceAgent: User agent string for API requestsisDeviceHmt,isNavigator500,isCimo,isDigiLens: Device type flagsappInfo: Package information for the applicationisInCall: Reactive boolean for call statedbManager: Database manager instancehippoDBManager: Hippo database manager instancelog: Logger instance for application logging
Main Function
The main() function handles the application's initialization process:
dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
try {
// Initialization steps...
} catch (e) {
logInfo(e);
}
}Initialization Steps
Logging Setup
dartLogger.root.activateLogcat(); Logger.root.level = Level.ALL;Storage Initialization
dartawait GetStorage.init();Device Detection
dartisDeviceHmt = await isHmt; isNavigator500 = await isNav500; isCimo = await isCimoOrXps; isDigiLens = await isDigiLensDevice;Permission Requests
dartMap<Permission, PermissionStatus> statuses = await [ Permission.camera, Permission.microphone, Permission.storage, Permission.mediaLibrary, Permission.manageExternalStorage, Permission.notification, ].request();Database Initialization
dartdbManager = dbManager ?? await DbManager.create(); hippoDBManager = hippoDBManager ?? await HippoDBManager.initiate();Background Service Setup
dartWorkmanager().initialize( workToDoInBackgroundService, isInDebugMode: false, ); Workmanager().registerPeriodicTask( "hvc_xr", "fileUpload", backoffPolicy: BackoffPolicy.linear, );Device Information Setup
dartdeviceId = isDigiLens ? 'DigiLens' : await getDeviceId(); appInfo = await PackageInfo.fromPlatform(); deviceType = await getDeviceType(); deviceAgent = 'HvcHeadset->$deviceType->$deviceId';Orientation Configuration
dartawait SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]);Push Notification Setup
dartOneSignal.Debug.setLogLevel(OSLogLevel.verbose); OneSignal.initialize('5bc6d3bd-8862-48c9-b172-435f8b3c75b4'); OneSignal.Notifications.requestPermission(true);
MyApp Widget
The MyApp widget is the root widget of the application:
dart
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}Controller Initialization
The following controllers are initialized in _MyAppState:
dart
final digilensController = Get.put(DigilensController());
final authController = Get.put(AuthController());
final contactsController = Get.put(ContactsController());
final schedulesController = Get.put(EventsController());
final meetingsController = Get.put(MeetingsController());
final realTimeController = Get.put(RealTimeController());
final messagesController = Get.put(MessagesController());
final mediaController = Get.put(MediaController());Application Lifecycle Management
The application handles lifecycle events in _MyAppState:
dart
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.inactive:
print('appLifeCycleState inactive');
break;
case AppLifecycleState.resumed:
if (isLoggedIn()) {
realTimeController.onInit().whenComplete(() async =>
await realTimeController.callHi('AppLifecycleState.resumed'));
}
print('appLifeCycleState resumed');
break;
case AppLifecycleState.paused:
authController.saveClosingTime();
print('appLifeCycleState paused');
break;
case AppLifecycleState.detached:
break;
}
}Error Handling
The application implements error handling at multiple levels:
Main Function Error Handling
darttry { // Initialization code } catch (e) { logInfo(e); }Laser Permission Error Handling
dartFuture<void> requestLaserPermission() async { try { await laserChannel.invokeMethod('requestLaserPermission'); } catch (e) { logInfo(e); } }
Best Practices
- Always check device type before implementing device-specific features
- Handle permissions appropriately for each device type
- Implement proper error handling for all async operations
- Clean up resources in the dispose method
- Use reactive state management with GetX
- Follow the established controller initialization pattern
Common Issues and Solutions
Permission Denials
- Ensure all required permissions are requested
- Handle permission denials gracefully
- Provide clear user feedback
Device Detection Issues
- Verify device detection methods
- Implement fallback options
- Log device detection results
Background Service Problems
- Check Workmanager initialization
- Verify task registration
- Monitor task execution
Testing
- Test initialization on different devices
- Verify permission handling
- Check background service functionality
- Test application lifecycle management
- Verify controller initialization
Dependencies
The main file relies on several key dependencies:
get: State managementget_storage: Local storagelogging_to_logcat: Loggingonesignal_flutter: Push notificationspermission_handler: Permission managementworkmanager: Background tasksflutter_screenutil: Screen utilities
This documentation provides a comprehensive guide for understanding and working with the main.dart file. For specific implementation details, refer to the inline documentation in the source code.