Recording Control
Programmatically control UXCam session recording in Flutter apps
Recording Control
Take full control of when and how UXCam records user sessions in your Flutter application. This guide covers starting, stopping, pausing, and customizing recording behavior.
Core Recording Methods
Start Recording
import 'package:flutter_uxcam/flutter_uxcam.dart';
// Basic start with configuration
FlutterUxConfig config = FlutterUxConfig(
userAppKey: "YOUR_APP_KEY",
enableAutomaticScreenNameTagging: true,
);
await FlutterUxcam.startWithConfiguration(config);Stop Recording
// Stop current session and upload data
await FlutterUxcam.stopSessionAndUploadData();
// Check if currently recording
bool isRecording = await FlutterUxcam.isRecording();
print('Recording status: $isRecording');Pause/Resume Recording
// Pause recording (session continues, but no data captured)
await FlutterUxcam.pauseScreenRecording();
// Resume recording
await FlutterUxcam.resumeScreenRecording();Advanced Recording Patterns
Conditional Recording
class RecordingController {
static bool _shouldRecord = true;
static Future<void> startConditionalRecording({
required String appKey,
required bool userConsented,
required bool isProduction,
}) async {
// Only record if user consented and in production
if (!userConsented || !isProduction) {
_shouldRecord = false;
return;
}
FlutterUxConfig config = FlutterUxConfig(
userAppKey: appKey,
enableAutomaticScreenNameTagging: true,
);
await FlutterUxcam.startWithConfiguration(config);
_shouldRecord = true;
}
static Future<void> stopIfRecording() async {
if (_shouldRecord && await FlutterUxcam.isRecording()) {
await FlutterUxcam.stopSessionAndUploadData();
}
}
}Session Rotation
class SessionRotationManager {
static const int MAX_SESSION_DURATION = 30 * 60 * 1000; // 30 minutes
static Timer? _rotationTimer;
static Future<void> startWithRotation(String appKey) async {
await _startNewSession(appKey);
_scheduleRotation(appKey);
}
static Future<void> _startNewSession(String appKey) async {
FlutterUxConfig config = FlutterUxConfig(
userAppKey: appKey,
enableAutomaticScreenNameTagging: true,
);
await FlutterUxcam.startWithConfiguration(config);
print('New UXCam session started');
}
static void _scheduleRotation(String appKey) {
_rotationTimer?.cancel();
_rotationTimer = Timer(
Duration(milliseconds: MAX_SESSION_DURATION),
() async {
await FlutterUxcam.stopSessionAndUploadData();
await _startNewSession(appKey);
_scheduleRotation(appKey); // Schedule next rotation
},
);
}
static void stopRotation() {
_rotationTimer?.cancel();
FlutterUxcam.stopSessionAndUploadData();
}
}Screen-Specific Recording
class ScreenRecordingManager {
static final Set<String> _sensitiveScreens = {
'LoginScreen',
'PaymentScreen',
'PersonalInfoScreen',
};
static Future<void> handleScreenTransition(String screenName) async {
if (_sensitiveScreens.contains(screenName)) {
// Pause recording on sensitive screens
await FlutterUxcam.pauseScreenRecording();
print('Recording paused for sensitive screen: $screenName');
} else {
// Resume recording on normal screens
await FlutterUxcam.resumeScreenRecording();
print('Recording resumed for screen: $screenName');
}
// Tag the screen
FlutterUxcam.tagScreenName(screenName);
}
}
// Usage in your screens
class PaymentScreen extends StatefulWidget {
@override
_PaymentScreenState createState() => _PaymentScreenState();
}
class _PaymentScreenState extends State<PaymentScreen> {
@override
void initState() {
super.initState();
ScreenRecordingManager.handleScreenTransition('PaymentScreen');
}
@override
void dispose() {
// Resume recording when leaving sensitive screen
FlutterUxcam.resumeScreenRecording();
super.dispose();
}
}App Lifecycle Integration
Comprehensive Lifecycle Management
class UXCamLifecycleManager extends WidgetsBindingObserver {
final String appKey;
bool _isRecording = false;
UXCamLifecycleManager(this.appKey);
Future<void> initialize() async {
WidgetsBinding.instance.addObserver(this);
await startRecording();
}
Future<void> startRecording() async {
if (!_isRecording) {
FlutterUxConfig config = FlutterUxConfig(
userAppKey: appKey,
enableAutomaticScreenNameTagging: true,
);
await FlutterUxcam.startWithConfiguration(config);
_isRecording = true;
print('UXCam recording started');
}
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.paused:
_handleAppPaused();
break;
case AppLifecycleState.resumed:
_handleAppResumed();
break;
case AppLifecycleState.detached:
_handleAppDetached();
break;
}
}
void _handleAppPaused() async {
print('App paused - ensuring session upload');
if (_isRecording) {
// Optional: Stop recording when app goes to background
// await FlutterUxcam.stopSessionAndUploadData();
// _isRecording = false;
}
}
void _handleAppResumed() async {
print('App resumed');
if (!_isRecording) {
await startRecording();
}
}
void _handleAppDetached() async {
print('App detached - final session upload');
if (_isRecording) {
await FlutterUxcam.stopSessionAndUploadData();
_isRecording = false;
}
}
void dispose() {
WidgetsBinding.instance.removeObserver(this);
if (_isRecording) {
FlutterUxcam.stopSessionAndUploadData();
}
}
}
// Usage in main app
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late UXCamLifecycleManager _uxcamManager;
@override
void initState() {
super.initState();
_uxcamManager = UXCamLifecycleManager("YOUR_APP_KEY");
_uxcamManager.initialize();
}
@override
void dispose() {
_uxcamManager.dispose();
super.dispose();
}
}Performance Optimization
Smart Recording Configuration
class PerformanceOptimizedRecording {
static Future<void> startOptimizedRecording({
required String appKey,
bool isLowEndDevice = false,
bool isOnMeteredConnection = false,
}) async {
FlutterUxConfig config = FlutterUxConfig(
userAppKey: appKey,
enableAutomaticScreenNameTagging: !isLowEndDevice, // Disable for performance
enableImprovedScreenCapture: !isLowEndDevice, // Use basic capture on low-end devices
);
await FlutterUxcam.startWithConfiguration(config);
// Implement session rotation for low-end devices
if (isLowEndDevice) {
SessionRotationManager.startWithRotation(appKey);
}
}
static Future<bool> _isLowEndDevice() async {
// Implement device capability detection
// This is a simplified example
final deviceInfo = await DeviceInfoPlugin().androidInfo;
return deviceInfo.version.sdkInt < 26; // Android 8.0+
}
static Future<bool> _isOnMeteredConnection() async {
final connectivityResult = await Connectivity().checkConnectivity();
return connectivityResult == ConnectivityResult.mobile;
}
}Memory-Conscious Recording
class MemoryAwareRecording {
static const int MEMORY_THRESHOLD_MB = 100;
static Timer? _memoryCheckTimer;
static Future<void> startWithMemoryMonitoring(String appKey) async {
FlutterUxConfig config = FlutterUxConfig(
userAppKey: appKey,
enableAutomaticScreenNameTagging: true,
);
await FlutterUxcam.startWithConfiguration(config);
_startMemoryMonitoring();
}
static void _startMemoryMonitoring() {
_memoryCheckTimer = Timer.periodic(
Duration(minutes: 5),
(timer) async {
final memoryUsage = await _getMemoryUsage();
if (memoryUsage > MEMORY_THRESHOLD_MB) {
print('High memory usage detected: ${memoryUsage}MB');
// Rotate session to free memory
await FlutterUxcam.stopSessionAndUploadData();
// Wait a bit before starting new session
await Future.delayed(Duration(seconds: 2));
FlutterUxConfig config = FlutterUxConfig(
userAppKey: "YOUR_APP_KEY",
enableImprovedScreenCapture: false, // Reduce quality
);
await FlutterUxcam.startWithConfiguration(config);
}
},
);
}
static Future<double> _getMemoryUsage() async {
// Platform-specific memory usage implementation
// This is a simplified placeholder
return 50.0; // MB
}
static void stopMemoryMonitoring() {
_memoryCheckTimer?.cancel();
}
}Error Handling
Robust Recording Control
class RobustRecordingController {
static bool _isInitialized = false;
static String? _appKey;
static Future<bool> startRecording(String appKey) async {
try {
_appKey = appKey;
FlutterUxConfig config = FlutterUxConfig(
userAppKey: appKey,
enableAutomaticScreenNameTagging: true,
);
await FlutterUxcam.startWithConfiguration(config);
_isInitialized = true;
print('UXCam recording started successfully');
return true;
} catch (error) {
print('Failed to start UXCam recording: $error');
return false;
}
}
static Future<bool> stopRecording() async {
try {
if (_isInitialized && await FlutterUxcam.isRecording()) {
await FlutterUxcam.stopSessionAndUploadData();
_isInitialized = false;
print('UXCam recording stopped successfully');
return true;
}
return false;
} catch (error) {
print('Failed to stop UXCam recording: $error');
return false;
}
}
static Future<void> ensureRecording() async {
try {
if (!_isInitialized && _appKey != null) {
await startRecording(_appKey!);
}
} catch (error) {
print('Failed to ensure UXCam recording: $error');
}
}
}Testing Recording Control
Development Testing
class UXCamTestController {
static bool _testMode = false;
static void enableTestMode() {
_testMode = true;
}
static Future<void> startRecording(String appKey) async {
if (_testMode) {
print('TEST MODE: Would start UXCam recording with key: $appKey');
return;
}
FlutterUxConfig config = FlutterUxConfig(
userAppKey: appKey,
enableAutomaticScreenNameTagging: true,
);
await FlutterUxcam.startWithConfiguration(config);
}
static Future<void> stopRecording() async {
if (_testMode) {
print('TEST MODE: Would stop UXCam recording');
return;
}
await FlutterUxcam.stopSessionAndUploadData();
}
}Best Practices
Do's
- ✅ Always check recording status before stopping
- ✅ Handle app lifecycle events properly
- ✅ Implement error handling for all recording operations
- ✅ Use session rotation for long-running apps
- ✅ Pause recording on sensitive screens
- ✅ Monitor memory usage and optimize accordingly
Don'ts
- ❌ Don't start multiple sessions simultaneously
- ❌ Don't ignore app lifecycle events
- ❌ Don't record sensitive user data
- ❌ Don't forget to stop recording on app termination
- ❌ Don't skip error handling in production
Next Steps
- Crash Handling - Learn advanced error tracking
- User Consent - Implement privacy controls
- Integration Logging - Debug your setup
Master recording control to optimize performance and ensure data quality in your Flutter app.
Updated 8 months ago
