Add MIUI device detection and warning for accessibility service

Co-authored-by: jonasbark <1151304+jonasbark@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-10-31 18:31:30 +00:00
parent 807d868b74
commit b7b6b9803f
2 changed files with 127 additions and 0 deletions

View File

@@ -1,11 +1,14 @@
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:swift_control/main.dart';
import 'package:swift_control/utils/requirements/platform.dart';
import 'package:swift_control/widgets/accessibility_disclosure_dialog.dart';
import 'package:swift_control/widgets/warning.dart';
import 'package:url_launcher/url_launcher.dart';
class AccessibilityRequirement extends PlatformRequirement {
AccessibilityRequirement()
@@ -169,3 +172,124 @@ void notificationTapBackground(NotificationResponse notificationResponse) {
});
}
}
class MiuiWarningRequirement extends PlatformRequirement {
static bool? _isMiui;
MiuiWarningRequirement()
: super(
'MIUI Battery Optimization Warning',
description: 'MIUI devices may kill the accessibility service. Please disable battery optimization.',
);
static Future<bool> isMiuiDevice() async {
if (_isMiui != null) return _isMiui!;
try {
final deviceInfo = await DeviceInfoPlugin().androidInfo;
// Check if manufacturer is Xiaomi or if it's running MIUI
_isMiui = deviceInfo.manufacturer.toLowerCase() == 'xiaomi' ||
deviceInfo.brand.toLowerCase() == 'xiaomi' ||
deviceInfo.brand.toLowerCase() == 'redmi' ||
deviceInfo.brand.toLowerCase() == 'poco';
return _isMiui!;
} catch (e) {
_isMiui = false;
return false;
}
}
@override
Future<void> call(BuildContext context, VoidCallback onUpdate) async {
// This is an informational requirement, no action needed
}
@override
Future<void> getStatus() async {
// This is always "complete" - it's just a warning
status = true;
}
@override
Widget? build(BuildContext context, VoidCallback onUpdate) {
return Warning(
children: [
Row(
children: [
Icon(Icons.warning_amber, color: Theme.of(context).colorScheme.error),
SizedBox(width: 8),
Expanded(
child: Text(
'MIUI Device Detected',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.error,
),
),
),
],
),
SizedBox(height: 8),
Text(
'Your device is running MIUI, which is known to aggressively kill background services and accessibility services.',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 8),
Text(
'To ensure SwiftControl works properly:',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
),
Text(
'• Disable battery optimization for SwiftControl',
style: TextStyle(fontSize: 14),
),
Text(
'• Enable autostart for SwiftControl',
style: TextStyle(fontSize: 14),
),
Text(
'• Lock the app in recent apps',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 12),
ElevatedButton.icon(
onPressed: () async {
final url = Uri.parse('https://dontkillmyapp.com/xiaomi');
if (await canLaunchUrl(url)) {
await launchUrl(url, mode: LaunchMode.externalApplication);
}
},
icon: Icon(Icons.open_in_new),
label: Text('View Detailed Instructions'),
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.errorContainer,
foregroundColor: Theme.of(context).colorScheme.onErrorContainer,
),
),
SizedBox(height: 8),
ElevatedButton(
onPressed: () {
onUpdate();
},
child: Text('I understand, continue'),
),
],
);
}
@override
Widget? buildDescription() {
return Row(
children: [
Icon(Icons.info_outline, size: 16, color: Colors.orange),
SizedBox(width: 4),
Expanded(
child: Text(
'Please review the battery optimization settings',
style: TextStyle(color: Colors.orange),
),
),
],
);
}
}

View File

@@ -71,6 +71,7 @@ Future<List<PlatformRequirement>> getRequirements(ConnectionType connectionType)
} else if (Platform.isAndroid) {
final deviceInfoPlugin = DeviceInfoPlugin();
final deviceInfo = await deviceInfoPlugin.androidInfo;
final isMiui = await MiuiWarningRequirement.isMiuiDevice();
list = [
TargetRequirement(),
BluetoothTurnedOn(),
@@ -81,6 +82,8 @@ Future<List<PlatformRequirement>> getRequirements(ConnectionType connectionType)
BluetoothScanRequirement(),
BluetoothConnectRequirement(),
],
if (isMiui && connectionType == ConnectionType.local)
MiuiWarningRequirement(),
switch (connectionType) {
ConnectionType.local => AccessibilityRequirement(),
ConnectionType.remote => RemoteRequirement(),