365 lines
12 KiB
Dart
365 lines
12 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:EasyDartModule/EasyDartModule.dart';
|
|
import 'package:ef/ef.dart';
|
|
import 'package:geocoding/geocoding.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:json_annotation/json_annotation.dart';
|
|
import 'package:vbvs_app/common/util/CommonVariables.dart';
|
|
import 'package:vbvs_app/controller/setting/language/language_controller.dart';
|
|
import 'package:weather/weather.dart';
|
|
|
|
part 'weather_controller.g.dart';
|
|
|
|
@JsonSerializable()
|
|
class WeatherModel {
|
|
double? longitude; // 经度
|
|
double? latitude; // 纬度
|
|
String? weather_info = ''; // 天气
|
|
int? current_temperature; // 温度
|
|
int? min_temperature; // 最低温度
|
|
int? max_temperature; // 最高温度
|
|
String? wind_direction; // 风向
|
|
int? wind_speed; // 风速等级
|
|
String? cityName; // 城市名
|
|
String? weatherIcon; // 天气图标
|
|
String? weatherIconurl; // 天气图标url
|
|
|
|
WeatherModel();
|
|
|
|
static WeatherModel fromJson(Map<String, dynamic> json) =>
|
|
_$WeatherModelFromJson(json);
|
|
|
|
Map<String, dynamic> toJson() => _$WeatherModelToJson(this);
|
|
}
|
|
|
|
class WeatherModelController extends GetControllerEx<WeatherModel> {
|
|
LanguageController languageController = Get.find();
|
|
WeatherModelController() {
|
|
attr = GetModel(WeatherModel()).obs;
|
|
weatherFactory = WeatherFactory(CommonVariables.weather_apiKey,
|
|
language: Language.CHINESE_SIMPLIFIED);
|
|
}
|
|
|
|
Timer? _weatherTimer;
|
|
Timer? _locationTimer;
|
|
|
|
late WeatherFactory weatherFactory;
|
|
|
|
@override
|
|
Future<void> onInit() async {
|
|
super.onInit();
|
|
|
|
try {
|
|
await _getCurrentLocation();
|
|
_weatherTimer = Timer.periodic(Duration(seconds: 5), (timer) {
|
|
_getCurrentWeather(); // 每 5 秒更新一次天气
|
|
});
|
|
|
|
_locationTimer = Timer.periodic(Duration(minutes: 10), (timer) {
|
|
_getCurrentLocation(); // 每 10 分钟更新一次位置
|
|
});
|
|
} catch (e) {
|
|
ef.log("[天气和定位请求失败]");
|
|
}
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
_weatherTimer?.cancel(); // 取消天气更新定时器
|
|
_locationTimer?.cancel(); // 取消位置更新定时器
|
|
super.onClose();
|
|
}
|
|
|
|
// 获取当前位置并存储到 model
|
|
Future<void> _getCurrentLocation() async {
|
|
try {
|
|
Position position = await determinePosition();
|
|
if (position == null) {
|
|
throw Exception("获取位置失败");
|
|
}
|
|
|
|
String? language = "zh_CN";
|
|
if (languageController.selectLanguage != null) {
|
|
language = languageController.selectLanguage.value!.language_code;
|
|
}
|
|
List<Placemark> placemarks = [];
|
|
// placemarks = await placemarkFromCoordinates(position.latitude, position.longitude,
|
|
// localeIdentifier: language);
|
|
placemarks = await placemarkFromCoordinates(
|
|
position.latitude,
|
|
position.longitude,
|
|
);
|
|
|
|
if (placemarks.isNotEmpty) {
|
|
model.cityName = placemarks[0].locality ?? "未知数据".tr;
|
|
model.latitude = position.latitude;
|
|
model.longitude = position.longitude;
|
|
}
|
|
|
|
// 调用获取天气方法
|
|
_getCurrentWeather();
|
|
} catch (e) {
|
|
|
|
|
|
print(e);
|
|
EasyDartModule.logger.error("获取位置失败: $e");
|
|
}
|
|
}
|
|
|
|
// 获取当前位置
|
|
Future<Position> determinePosition() async {
|
|
bool serviceEnabled;
|
|
LocationPermission permission;
|
|
|
|
serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
|
if (!serviceEnabled) {
|
|
return Future.error('位置服务未启用');
|
|
}
|
|
|
|
permission = await Geolocator.checkPermission();
|
|
if (permission == LocationPermission.denied) {
|
|
permission = await Geolocator.requestPermission();
|
|
if (permission == LocationPermission.denied) {
|
|
return Future.error('位置权限被拒绝');
|
|
}
|
|
}
|
|
|
|
if (permission == LocationPermission.deniedForever) {
|
|
return Future.error('位置权限被永久拒绝');
|
|
}
|
|
|
|
return await Geolocator.getCurrentPosition(
|
|
locationSettings: const LocationSettings(
|
|
accuracy: LocationAccuracy.low, // 使用高精度定位,但不依赖 Google Play
|
|
distanceFilter: 1000, // 设置最小距离过滤
|
|
timeLimit: Duration(seconds: 10), // 设置获取位置的最大等待时间
|
|
),
|
|
);
|
|
}
|
|
|
|
// 获取天气信息
|
|
Future<void> _getCurrentWeather() async {
|
|
if (model.latitude == null || model.longitude == null) {
|
|
EasyDartModule.logger.error("获取天气失败:位置数据获取失败");
|
|
return; // 如果位置数据没有获取到,则不更新天气
|
|
}
|
|
String? language = "zh_CN";
|
|
if (languageController.selectLanguage != null) {
|
|
language = languageController.selectLanguage.value!.language_code;
|
|
}
|
|
List<Placemark> placemarks = [];
|
|
// placemarks = await placemarkFromCoordinates(model.latitude!, model.longitude!,
|
|
// localeIdentifier: language);
|
|
|
|
if (placemarks.isNotEmpty) {
|
|
model.cityName = placemarks[0].locality ?? "未知数据".tr;
|
|
}
|
|
|
|
try {
|
|
weatherFactory.language = Language.CHINESE_SIMPLIFIED;
|
|
String? language = "zh_CN";
|
|
if (languageController.selectLanguage != null) {
|
|
language = languageController.selectLanguage.value!.language_code;
|
|
}
|
|
if (language == "zh_CN") {
|
|
weatherFactory.language = Language.CHINESE_SIMPLIFIED;
|
|
} else {
|
|
weatherFactory.language = Language.ENGLISH;
|
|
}
|
|
Weather weather = await weatherFactory.currentWeatherByLocation(
|
|
model.latitude!, model.longitude!);
|
|
|
|
model.weather_info = weather.weatherDescription;
|
|
model.min_temperature = weather.tempMin?.celsius?.toInt();
|
|
model.max_temperature = weather.tempMax?.celsius?.toInt();
|
|
model.current_temperature = weather.temperature?.celsius?.toInt();
|
|
model.wind_speed = weather.windSpeed?.toInt();
|
|
model.weatherIcon = weather.weatherIcon;
|
|
if (model.weatherIcon != null) {
|
|
model.weatherIconurl =
|
|
"https://openweathermap.org/img/w/${model.weatherIcon}.png";
|
|
}
|
|
updateAll(); // 更新 UI
|
|
} catch (e) {
|
|
EasyDartModule.logger.error("获取天气失败: $e");
|
|
print('获取天气失败: $e');
|
|
}
|
|
}
|
|
|
|
// 获取 5 天天气预报
|
|
Future<List<Weather>> getWeatherForecast(
|
|
double latitude, double longitude) async {
|
|
try {
|
|
return await weatherFactory.fiveDayForecastByLocation(
|
|
latitude, longitude);
|
|
} catch (e) {
|
|
print('获取天气预报失败: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
}
|
|
|
|
// import 'dart:async';
|
|
// import 'package:EasyDartModule/EasyDartModule.dart';
|
|
// import 'package:ef/ef.dart';
|
|
// import 'package:amap_flutter_location/amap_flutter_location.dart'; // 导入 amap_flutter_location 插件
|
|
// import 'package:geocoding/geocoding.dart';
|
|
// import 'package:json_annotation/json_annotation.dart';
|
|
// import 'package:vbvs_app/common/util/CommonVariables.dart';
|
|
// import 'package:vbvs_app/controller/setting/language/language_controller.dart';
|
|
// import 'package:weather/weather.dart';
|
|
|
|
// part 'weather_controller.g.dart';
|
|
|
|
// @JsonSerializable()
|
|
// class WeatherModel {
|
|
// double? longitude; // 经度
|
|
// double? latitude; // 纬度
|
|
// String? weather_info = ''; // 天气
|
|
// int? current_temperature; // 温度
|
|
// int? min_temperature; // 最低温度
|
|
// int? max_temperature; // 最高温度
|
|
// String? wind_direction; // 风向
|
|
// int? wind_speed; // 风速等级
|
|
// String? cityName; // 城市名
|
|
// String? weatherIcon; // 天气图标
|
|
// String? weatherIconurl; // 天气图标url
|
|
|
|
// WeatherModel();
|
|
|
|
// static WeatherModel fromJson(Map<String, dynamic> json) =>
|
|
// _$WeatherModelFromJson(json);
|
|
|
|
// Map<String, dynamic> toJson() => _$WeatherModelToJson(this);
|
|
// }
|
|
|
|
// class WeatherModelController extends GetControllerEx<WeatherModel> {
|
|
// LanguageController languageController = Get.find();
|
|
// WeatherModelController() {
|
|
// attr = GetModel(WeatherModel()).obs;
|
|
// weatherFactory = WeatherFactory(CommonVariables.weather_apiKey,
|
|
// language: Language.CHINESE_SIMPLIFIED);
|
|
// }
|
|
|
|
// Timer? _weatherTimer;
|
|
// Timer? _locationTimer;
|
|
|
|
// late WeatherFactory weatherFactory;
|
|
// late AMapFlutterLocation location; // 声明 AMapFlutterLocation 实例
|
|
|
|
// @override
|
|
// Future<void> onInit() async {
|
|
// super.onInit();
|
|
|
|
// location = AMapFlutterLocation(); // 初始化 AMapFlutterLocation
|
|
|
|
// try {
|
|
// await _getCurrentLocation();
|
|
// _weatherTimer = Timer.periodic(Duration(seconds: 5), (timer) {
|
|
// _getCurrentWeather(); // 每 5 秒更新一次天气
|
|
// });
|
|
|
|
// _locationTimer = Timer.periodic(Duration(minutes: 10), (timer) {
|
|
// _getCurrentLocation(); // 每 10 分钟更新一次位置
|
|
// });
|
|
// } catch (e) {
|
|
// ef.log("[天气和定位请求失败]");
|
|
// }
|
|
// }
|
|
|
|
// @override
|
|
// void onClose() {
|
|
// _weatherTimer?.cancel(); // 取消天气更新定时器
|
|
// _locationTimer?.cancel(); // 取消位置更新定时器
|
|
// location.stopLocation(); // 停止高德定位
|
|
// super.onClose();
|
|
// }
|
|
|
|
// // 获取当前位置并存储到 model
|
|
// Future<void> _getCurrentLocation() async {
|
|
// try {
|
|
// // 开始定位
|
|
// location.startLocation();
|
|
|
|
// // 监听定位回调
|
|
|
|
// location.onLocationChanged().listen((Map<String, Object> result) {
|
|
// ///result即为定位结果
|
|
// ef.log("[位置]:${result}");
|
|
// });
|
|
|
|
// // location.onLocationChanged.listen((locationData) {
|
|
// // if (locationData.latitude != null && locationData.longitude != null) {
|
|
// // model.latitude = locationData.latitude;
|
|
// // model.longitude = locationData.longitude;
|
|
|
|
// // // 获取位置对应的城市名
|
|
// // _getCityName(locationData.latitude!, locationData.longitude!);
|
|
// // }
|
|
// // });
|
|
// } catch (e) {
|
|
// print(e);
|
|
// EasyDartModule.logger.error("获取位置失败: $e");
|
|
// }
|
|
// }
|
|
|
|
// // 获取城市名
|
|
// Future<void> _getCityName(double latitude, double longitude) async {
|
|
// try {
|
|
// List<Placemark> placemarks =
|
|
// await placemarkFromCoordinates(latitude, longitude);
|
|
|
|
// if (placemarks.isNotEmpty) {
|
|
// model.cityName = placemarks[0].locality ?? "未知数据".tr;
|
|
// }
|
|
// // 获取天气
|
|
// _getCurrentWeather();
|
|
// } catch (e) {
|
|
// print(e);
|
|
// EasyDartModule.logger.error("获取城市名失败: $e");
|
|
// }
|
|
// }
|
|
|
|
// // 获取天气信息
|
|
// Future<void> _getCurrentWeather() async {
|
|
// if (model.latitude == null || model.longitude == null) {
|
|
// EasyDartModule.logger.error("获取天气失败:位置数据获取失败");
|
|
// return; // 如果位置数据没有获取到,则不更新天气
|
|
// }
|
|
|
|
// try {
|
|
// weatherFactory.language = Language.CHINESE_SIMPLIFIED;
|
|
// Weather weather = await weatherFactory.currentWeatherByLocation(
|
|
// model.latitude!, model.longitude!);
|
|
|
|
// model.weather_info = weather.weatherDescription;
|
|
// model.min_temperature = weather.tempMin?.celsius?.toInt();
|
|
// model.max_temperature = weather.tempMax?.celsius?.toInt();
|
|
// model.current_temperature = weather.temperature?.celsius?.toInt();
|
|
// model.wind_speed = weather.windSpeed?.toInt();
|
|
// model.weatherIcon = weather.weatherIcon;
|
|
// if (model.weatherIcon != null) {
|
|
// model.weatherIconurl =
|
|
// "https://openweathermap.org/img/w/${model.weatherIcon}.png";
|
|
// }
|
|
// updateAll(); // 更新 UI
|
|
// } catch (e) {
|
|
// EasyDartModule.logger.error("获取天气失败: $e");
|
|
// print('获取天气失败: $e');
|
|
// }
|
|
// }
|
|
|
|
// // 获取 5 天天气预报
|
|
// Future<List<Weather>> getWeatherForecast(
|
|
// double latitude, double longitude) async {
|
|
// try {
|
|
// return await weatherFactory.fiveDayForecastByLocation(
|
|
// latitude, longitude);
|
|
// } catch (e) {
|
|
// print('获取天气预报失败: $e');
|
|
// rethrow;
|
|
// }
|
|
// }
|
|
// }
|