jjsos_autosos_flutter/lib/pages/me/optimization_page.dart

186 lines
5.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'package:autosos_flutter/service/background_service.dart';
import 'package:autosos_flutter/service/location_service.dart';
import 'package:autosos_flutter/service/push_service.dart';
import 'package:autosos_flutter/util/toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
/// 性能优化页(对应 Android OptimizationActivity
/// 检查并展示:定位 / 推送 / 后台 / 心跳 / 网络 各模块状态
class OptimizationPage extends ConsumerStatefulWidget {
const OptimizationPage({super.key});
@override
ConsumerState<OptimizationPage> createState() => _OptimizationPageState();
}
class _OptimizationPageState extends ConsumerState<OptimizationPage> {
bool _locating = false;
String? _lastLoc;
String? _cid;
bool _bgRunning = false;
bool _heartbeat = false;
int _online = 0;
bool _testing = false;
String? _netResult;
@override
void initState() {
super.initState();
_refresh();
}
Future<void> _refresh() async {
final loc = LocationService.instance.last;
final bg = await BackgroundService.instance.isRunning();
setState(() {
_cid = PushService.instance.clientId;
_bgRunning = bg;
_lastLoc = loc == null
? null
: '(${(loc['latitude'] as num? ?? 0).toDouble().toStringAsFixed(4)}, ${(loc['longitude'] as num? ?? 0).toDouble().toStringAsFixed(4)})';
});
}
Future<void> _fetchOnce() async {
setState(() => _locating = true);
try {
final loc = await LocationService.instance.fetchOnce();
if (loc == null) {
Toast.error('定位失败');
} else {
setState(() {
_lastLoc =
'(${(loc['latitude'] as num? ?? 0).toDouble().toStringAsFixed(4)}, ${(loc['longitude'] as num? ?? 0).toDouble().toStringAsFixed(4)})';
});
}
} catch (e) {
Toast.error('定位异常:$e');
} finally {
if (mounted) setState(() => _locating = false);
}
}
Future<void> _testNet() async {
setState(() {
_testing = true;
_netResult = null;
});
final sw = Stopwatch()..start();
try {
final r = await LocationService.instance.fetchOnce();
sw.stop();
if (r != null) {
setState(() {
_netResult = '定位耗时 ${sw.elapsedMilliseconds} ms';
});
Toast.success('网络正常');
} else {
setState(() {
_netResult = '定位失败';
});
}
} catch (e) {
sw.stop();
setState(() {
_netResult = '异常:$e';
});
} finally {
if (mounted) setState(() => _testing = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('性能优化')),
body: ListView(
children: [
_section('定位服务'),
ListTile(
leading: const Icon(Icons.location_on, color: Colors.red),
title: const Text('当前位置'),
subtitle: Text(_lastLoc ?? '尚未获取'),
trailing: _locating
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.refresh),
onTap: _fetchOnce,
),
_section('推送服务'),
ListTile(
leading: const Icon(Icons.notifications, color: Colors.red),
title: const Text('个推 CID'),
subtitle: Text(_cid ?? '未初始化'),
),
_section('后台保活'),
ListTile(
leading: Icon(
Icons.alarm_on,
color: _bgRunning ? Colors.green : Colors.grey,
),
title: const Text('Background Service'),
subtitle: Text(_bgRunning ? '运行中' : '未运行'),
trailing: TextButton(
onPressed: () async {
if (_bgRunning) {
await BackgroundService.instance.stop();
} else {
await BackgroundService.instance.start();
}
_refresh();
},
child: Text(_bgRunning ? '停止' : '启动'),
),
),
_section('心跳 / 网络'),
ListTile(
leading: const Icon(Icons.favorite, color: Colors.red),
title: const Text('心跳'),
subtitle: Text(_heartbeat ? '正常' : ''),
trailing: Text('${_online}s'),
),
ListTile(
leading: const Icon(Icons.network_check, color: Colors.red),
title: const Text('网络测试'),
subtitle: Text(_netResult ?? '点击测试'),
trailing: _testing
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.play_arrow),
onTap: _testing ? null : _testNet,
),
_section('开发者'),
ListTile(
title: const Text('强制重连推送'),
onTap: () async {
PushService.instance.init();
_refresh();
Toast.success('已重连');
},
),
],
),
);
}
Widget _section(String title) => Container(
color: Colors.grey.shade100,
padding: const EdgeInsets.fromLTRB(16, 12, 16, 4),
width: double.infinity,
child: Text(
title,
style: const TextStyle(
fontSize: 12,
color: Colors.grey,
),
),
);
}