|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
|
import 'package:hmg_qline/services/logger_service.dart';
|
|
|
|
|
import 'package:hmg_qline/utilities/enums.dart';
|
|
|
|
|
|
|
|
|
|
abstract class NativeMethodChannelService {
|
|
|
|
|
void reopenApp();
|
|
|
|
|
|
|
|
|
|
Future<void> restartApp();
|
|
|
|
|
|
|
|
|
|
Future<void> restartDevice();
|
|
|
|
|
|
|
|
|
|
Future<void> clearAllResources();
|
|
|
|
|
|
|
|
|
|
Future<void> smartRestart({bool forceRestart = false, bool cleanupFirst = true});
|
|
|
|
|
|
|
|
|
|
/// Schedule daily restart alarm at specified time.
|
|
|
|
|
/// Works on Android 14+ and older versions.
|
|
|
|
|
Future<void> scheduleRestartAlarm({int hour = 0, int minute = 15});
|
|
|
|
|
|
|
|
|
|
/// Cancel the scheduled restart alarm.
|
|
|
|
|
Future<void> cancelRestartAlarm();
|
|
|
|
|
|
|
|
|
|
/// Check if the app can schedule exact alarms (Android 12+).
|
|
|
|
|
Future<bool> canScheduleExactAlarms();
|
|
|
|
|
|
|
|
|
|
/// Request permission to schedule exact alarms (Android 12+).
|
|
|
|
|
Future<void> requestExactAlarmPermission();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class NativeMethodChannelServiceImp implements NativeMethodChannelService {
|
|
|
|
|
static const MethodChannel _platform = MethodChannel('com.example.hmg_qline/foreground');
|
|
|
|
|
LoggerService loggerService;
|
|
|
|
|
|
|
|
|
|
NativeMethodChannelServiceImp({required this.loggerService});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void reopenApp() async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Attempting to reopen app");
|
|
|
|
|
await _platform.invokeMethod('reopenApp');
|
|
|
|
|
loggerService.logInfo("App reopened successfully");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error launching app: $e");
|
|
|
|
|
loggerService.logToFile(message: "Error launching app: $e", source: "reopenApp -> native_method_handler.dart", type: LogTypeEnum.error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> restartApp() async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Initiating app restart");
|
|
|
|
|
await _platform.invokeMethod('restartApp');
|
|
|
|
|
loggerService.logInfo("App restart command sent successfully");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error restarting app: $e");
|
|
|
|
|
loggerService.logToFile(message: "Error restarting app: $e", source: "restartApp -> native_method_handler.dart", type: LogTypeEnum.error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> restartDevice() async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Attempting device restart (requires root)");
|
|
|
|
|
|
|
|
|
|
final result = await _platform.invokeMethod('restartDevice');
|
|
|
|
|
loggerService.logInfo("Device restart initiated: $result");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Device restart failed: $e");
|
|
|
|
|
loggerService.logToFile(message: "Device restart failed: $e", source: "restartDevice -> native_method_handler.dart", type: LogTypeEnum.error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> clearAllResources() async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Clearing all native resources");
|
|
|
|
|
|
|
|
|
|
final result = await _platform.invokeMethod('clearAllResources');
|
|
|
|
|
loggerService.logInfo("All resources cleared: $result");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error clearing resources: $e");
|
|
|
|
|
loggerService.logToFile(message: "Error clearing resources: $e", source: "clearAllResources -> native_method_handler.dart", type: LogTypeEnum.error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Enhanced restart method with multiple fallback options
|
|
|
|
|
@override
|
|
|
|
|
Future<void> smartRestart({bool forceRestart = false, bool cleanupFirst = true}) async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Starting smart restart - forceRestart: $forceRestart, cleanupFirst: $cleanupFirst");
|
|
|
|
|
|
|
|
|
|
if (cleanupFirst) {
|
|
|
|
|
await clearAllResources();
|
|
|
|
|
await Future.delayed(const Duration(seconds: 1));
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Initiating app restart");
|
|
|
|
|
await _platform.invokeMethod('restartApp');
|
|
|
|
|
loggerService.logInfo("App restart command sent successfully");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error restarting app: $e");
|
|
|
|
|
loggerService.logToFile(message: "Error restarting app: $e", source: "restartApp -> native_method_handler.dart", type: LogTypeEnum.error);
|
|
|
|
|
}
|
|
|
|
|
} catch (primaryError) {
|
|
|
|
|
loggerService.logError("Primary restart failed, trying fallback methods: $primaryError");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// === NEW: Alarm Scheduling Methods for Android 14+ compatibility ===
|
|
|
|
|
|
|
|
|
|
/// Schedule daily restart alarm at specified time.
|
|
|
|
|
/// Default is 00:15 (12:15 AM).
|
|
|
|
|
/// Works on Android 14+ and older versions.
|
|
|
|
|
@override
|
|
|
|
|
Future<void> scheduleRestartAlarm({int hour = 0, int minute = 15}) async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Scheduling restart alarm for $hour:$minute");
|
|
|
|
|
|
|
|
|
|
// First check if we can schedule exact alarms
|
|
|
|
|
final canSchedule = await canScheduleExactAlarms();
|
|
|
|
|
if (!canSchedule) {
|
|
|
|
|
loggerService.logInfo("Exact alarm permission not granted. Requesting permission...");
|
|
|
|
|
await requestExactAlarmPermission();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await _platform.invokeMethod('scheduleRestartAlarm', {
|
|
|
|
|
'hour': hour,
|
|
|
|
|
'minute': minute,
|
|
|
|
|
});
|
|
|
|
|
loggerService.logInfo("Restart alarm scheduled successfully for $hour:$minute");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error scheduling restart alarm: $e");
|
|
|
|
|
loggerService.logToFile(
|
|
|
|
|
message: "Error scheduling restart alarm: $e",
|
|
|
|
|
source: "scheduleRestartAlarm -> native_method_handler.dart",
|
|
|
|
|
type: LogTypeEnum.error,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Cancel the scheduled restart alarm.
|
|
|
|
|
@override
|
|
|
|
|
Future<void> cancelRestartAlarm() async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Cancelling restart alarm");
|
|
|
|
|
await _platform.invokeMethod('cancelRestartAlarm');
|
|
|
|
|
loggerService.logInfo("Restart alarm cancelled successfully");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error cancelling restart alarm: $e");
|
|
|
|
|
loggerService.logToFile(
|
|
|
|
|
message: "Error cancelling restart alarm: $e",
|
|
|
|
|
source: "cancelRestartAlarm -> native_method_handler.dart",
|
|
|
|
|
type: LogTypeEnum.error,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Check if the app can schedule exact alarms.
|
|
|
|
|
/// Returns true on Android < 12 (always allowed) or if permission is granted on Android 12+.
|
|
|
|
|
@override
|
|
|
|
|
Future<bool> canScheduleExactAlarms() async {
|
|
|
|
|
try {
|
|
|
|
|
final result = await _platform.invokeMethod('canScheduleExactAlarms');
|
|
|
|
|
loggerService.logInfo("Can schedule exact alarms: $result");
|
|
|
|
|
return result ?? false;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error checking exact alarm permission: $e");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Request permission to schedule exact alarms (Android 12+).
|
|
|
|
|
/// Opens system settings for the user to grant permission.
|
|
|
|
|
@override
|
|
|
|
|
Future<void> requestExactAlarmPermission() async {
|
|
|
|
|
try {
|
|
|
|
|
loggerService.logInfo("Requesting exact alarm permission");
|
|
|
|
|
await _platform.invokeMethod('requestExactAlarmPermission');
|
|
|
|
|
loggerService.logInfo("Exact alarm permission request initiated");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
loggerService.logError("Error requesting exact alarm permission: $e");
|
|
|
|
|
loggerService.logToFile(
|
|
|
|
|
message: "Error requesting exact alarm permission: $e",
|
|
|
|
|
source: "requestExactAlarmPermission -> native_method_handler.dart",
|
|
|
|
|
type: LogTypeEnum.error,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|