Adjust android process

This commit is contained in:
chen08209
2026-08-05 10:54:54 +08:00
parent 7c831855ef
commit 51e24ef9de
80 changed files with 1930 additions and 2381 deletions
+29 -3
View File
@@ -5,19 +5,45 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wifi_ssid/wifi_ssid_manager.dart';
enum LocationPermissionFollowUp { none, showDeniedMessage, openSettings }
LocationPermissionFollowUp getLocationPermissionFollowUp(
WifiSsidPermission permission,
) {
return switch (permission) {
WifiSsidPermission.granted => LocationPermissionFollowUp.none,
WifiSsidPermission.denied => LocationPermissionFollowUp.showDeniedMessage,
WifiSsidPermission.permanentlyDenied =>
LocationPermissionFollowUp.openSettings,
};
}
class Permissions {
static Permissions? _instance;
Permissions._internal();
Permissions._internal({bool Function()? supportsLocationPermissions})
: _supportsLocationPermissions =
supportsLocationPermissions ??
(() => system.isAndroid || system.isMacOS);
factory Permissions() {
_instance ??= Permissions._internal();
return _instance!;
}
@visibleForTesting
factory Permissions.test({required bool supportsLocationPermissions}) {
return Permissions._internal(
supportsLocationPermissions: () => supportsLocationPermissions,
);
}
final bool Function() _supportsLocationPermissions;
bool _isRequestingLocation = false;
bool needWaitingBatteryOptimizationSettings = false;
@@ -53,7 +79,7 @@ class Permissions {
}
Future<void> checkLocationPermissions() async {
if (!(system.isAndroid || system.isMacOS)) {
if (!_supportsLocationPermissions()) {
return;
}
final res = await WifiSsidManager.instance.checkPermission();
@@ -74,7 +100,7 @@ class Permissions {
final res = await WifiSsidManager.instance.requestPermission();
globalState.container.read(locationPermissionsProvider.notifier).value =
res;
if (res != WifiSsidPermission.granted) {
if (res == WifiSsidPermission.granted) {
final ssid = await WifiSsidManager.instance.getSsid();
globalState.container.read(currentSSIDProvider.notifier).value = ssid;
}
-8
View File
@@ -53,14 +53,6 @@ class _AndroidContainerState extends ConsumerState<AndroidManager>
super.onServiceEvent(event);
}
@override
void onServiceCrash(String message) {
coreEventManager.sendEvent(
CoreEvent(type: CoreEventType.crash, data: message),
);
super.onServiceCrash(message);
}
@override
Widget build(BuildContext context) {
return widget.child;
+4 -4
View File
@@ -1,5 +1,5 @@
import 'package:fl_clash/common/app_localizations.dart';
import 'package:fl_clash/core/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/plugins/tile.dart';
import 'package:fl_clash/providers/providers.dart';
@@ -25,10 +25,10 @@ class _TileContainerState extends ConsumerState<TileManager> with TileListener {
@override
Future<void> onStart() async {
if (isStart && coreController.isCompleted) {
if (isStart && ref.read(coreStatusProvider) == CoreStatus.connected) {
return;
}
ref.read(setupActionProvider.notifier).updateStatus(true);
ref.read(setupActionProvider.notifier).setRunning(true);
app?.tip(currentAppLocalizations.startVpn);
super.onStart();
}
@@ -38,7 +38,7 @@ class _TileContainerState extends ConsumerState<TileManager> with TileListener {
if (!isStart) {
return;
}
ref.read(setupActionProvider.notifier).updateStatus(false);
ref.read(setupActionProvider.notifier).setRunning(false);
app?.tip(currentAppLocalizations.stopVpn);
super.onStop();
}
+2 -2
View File
@@ -40,8 +40,8 @@ class _VpnContainerState extends ConsumerState<VpnManager> {
actionText: currentAppLocalizations.restart,
action: () async {
final setupAction = ref.read(setupActionProvider.notifier);
await setupAction.handleStop();
await setupAction.updateStatus(true);
await setupAction.setRunning(false);
await setupAction.setRunning(true);
},
),
);
+11
View File
@@ -102,6 +102,17 @@ class App {
if (!Platform.isAndroid) return false;
return methodChannel.invokeMethod<bool>('openAppSettings');
}
Future<bool> didCrashOnPreviousExecution() async {
try {
return await methodChannel.invokeMethod<bool>(
'didCrashOnPreviousExecution',
) ??
false;
} catch (_) {
return false;
}
}
}
final app = system.isAndroid ? App() : null;
+22 -15
View File
@@ -3,14 +3,15 @@ import 'dart:convert';
import 'dart:isolate';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/core/event.dart';
import 'package:fl_clash/core/method.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
abstract mixin class ServiceListener {
void onServiceEvent(CoreEvent event) {}
void onServiceCrash(String message) {}
}
class Service {
@@ -32,15 +33,21 @@ class Service {
switch (call.method) {
case 'event':
final data = call.arguments as String? ?? '';
final result = ActionResult.fromJson(json.decode(data));
for (final listener in _listeners) {
listener.onServiceEvent(CoreEvent.fromJson(result.data));
}
break;
case 'crash':
final message = call.arguments as String? ?? '';
for (final listener in _listeners) {
listener.onServiceCrash(message);
final methodCall = CoreMethodCall.fromJson(
Map<String, Object?>.from(json.decode(data) as Map),
);
for (final event in coreEventsFromData(methodCall.arguments)) {
for (final listener in _listeners) {
try {
listener.onServiceEvent(event);
} catch (error) {
commonPrint.log(
'Unable to dispatch Android Core event '
'${event.type.name}: $error',
logLevel: LogLevel.error,
);
}
}
}
break;
default:
@@ -49,16 +56,16 @@ class Service {
});
}
Future<ActionResult?> invokeAction(Action action) async {
Future<CoreMethodResponse?> invokeMethod(CoreMethodCall call) async {
final data = await methodChannel.invokeMethod<String>(
'invokeAction',
json.encode(action),
'invokeMethod',
json.encode(call),
);
if (data == null) {
return null;
}
final dataJson = await data.commonToJSON<dynamic>();
return ActionResult.fromJson(dataJson);
return CoreMethodResponse.fromJson(dataJson);
}
Future<bool> start() async {