├── .gitignore ├── .metadata ├── CHANGELOG-ZH.md ├── CHANGELOG.md ├── CODEOWNERS ├── LICENSE ├── README.md ├── android ├── .gitignore ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── libs │ └── QWeather_Public_Android_V4.11.jar ├── proguard-rules.pro ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── kotlin │ └── com │ └── fluttercandies │ └── flutter_qweather │ ├── ApiAir.java │ ├── ApiAstronomy.java │ ├── ApiGeo.java │ ├── ApiHistory.java │ ├── ApiIndices.java │ ├── ApiOcean.java │ ├── ApiTropical.java │ ├── ApiWarning.java │ ├── ApiWeather.java │ ├── DebugPrint.java │ ├── FlutterQweatherPlugin.kt │ └── MethodConstants.java ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── fluttercandies │ │ │ │ │ └── flutter_qweather_example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ └── main.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── flutter_qweather.iml ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── Api │ │ ├── ApiAir.h │ │ ├── ApiAir.m │ │ ├── ApiAstronomy.h │ │ ├── ApiAstronomy.m │ │ ├── ApiGeo.h │ │ ├── ApiGeo.m │ │ ├── ApiHistorical.h │ │ ├── ApiHistorical.m │ │ ├── ApiIndices.h │ │ ├── ApiIndices.m │ │ ├── ApiOcean.h │ │ ├── ApiOcean.m │ │ ├── ApiTropical.h │ │ ├── ApiTropical.m │ │ ├── ApiWarning.h │ │ ├── ApiWarning.m │ │ ├── ApiWeather.h │ │ └── ApiWeather.m │ ├── DebugPrint │ │ ├── DebugPrint.h │ │ └── DebugPrint.m │ ├── FlutterQweatherPlugin.h │ ├── FlutterQweatherPlugin.m │ └── MethodConstants.h └── flutter_qweather.podspec ├── lib ├── apis │ ├── air_api.dart │ ├── astronomy_api.dart │ ├── geo_api.dart │ ├── historical_api.dart │ ├── indices_api.dart │ ├── ocean_api.dart │ ├── tropical_api.dart │ ├── warning_api.dart │ └── weather_api.dart ├── constants.dart ├── flutter_qweather.dart └── models │ ├── air.dart │ ├── astronomy.dart │ ├── basic.dart │ ├── geo.dart │ ├── historical.dart │ ├── indices.dart │ ├── ocean.dart │ ├── refer.dart │ ├── tropical.dart │ ├── warning.dart │ └── weather.dart ├── pubspec.lock ├── pubspec.yaml └── test └── flutter_qweather_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | .idea/ 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: adc687823a831bbebe28bdccfac1a628ca621513 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG-ZH.md: -------------------------------------------------------------------------------- 1 | ## 0.0.11 2 | 3 | - 升级 iOS SDK 4.10, 支持模拟器 4 | - 5 | ## 0.0.10 6 | 7 | - 升级 Android SDK 4.11 8 | 9 | ## 0.0.9 10 | 11 | - ios 平台 台风预报增加moveDir 12 | 13 | ## 0.0.8 14 | 15 | - 实现 历史天气和空气质量、太阳和月亮、潮汐和潮流、热带气旋(台风) 16 | 17 | ## 0.0.7 18 | 19 | - 实现 灾害预警、空气质量、 20 | 21 | ## 0.0.6 22 | 23 | - 升级 SDK 4.8 24 | - 重要改变: 图标代码有所增加 25 | 26 | ## 0.0.5 27 | 28 | - 升级 SDK 29 | 30 | ## 0.0.4 31 | 32 | - 升级 SDK 33 | - 实现 生活指数查询 34 | 35 | ## 0.0.3 36 | 37 | - 实现 Geo 搜索 38 | 39 | ## 0.0.2 40 | 41 | - 实现 逐天天气查询 42 | - 实现 逐时天气查询 43 | - 实现 中国地区未来2小时内每5分钟降水查询 44 | 45 | ## 0.0.1 46 | 47 | - 实现 实时天气查询。 48 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | [中文](CHANGELOG-ZH.md) 2 | ## 0.0.11 3 | 4 | - update iOS sdk 4.10, support simulator 5 | 6 | ## 0.0.10 7 | 8 | - update android sdk 4.11 9 | 10 | ## 0.0.9 11 | 12 | - add movedir to IOS platform tropical forecast 13 | 14 | ## 0.0.8 15 | 16 | - realized: disaster historical、astronomy、ocean、tropical 17 | 18 | ## 0.0.7 19 | 20 | - realized: disaster warning、air quality 21 | 22 | ## 0.0.6 23 | 24 | - update SDK 4.8. 25 | - BreakingChanges: Icon codes have been added 26 | 27 | ## 0.0.5 28 | 29 | - update SDK. 30 | 31 | ## 0.0.4 32 | 33 | - update sdk. 34 | - realized life indices query 35 | 36 | ## 0.0.3 37 | 38 | - realized geo search 39 | 40 | ## 0.0.2 41 | 42 | - realized daily weather query 43 | - realized hourly weather query 44 | - realized Precipitation query every 5 minutes in the next 2 hours in China 45 | 46 | ## 0.0.1 47 | 48 | - realized now weather query 49 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @CyJaySong 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter 和风天气插件 2 | 3 | [![pub package](https://img.shields.io/pub/v/flutter_qweather?logo=dart&label=stable&style=flat-square)](https://pub.dev/packages/flutter_qweather) 4 | [![pub package](https://img.shields.io/pub/v/flutter_qweather?color=42a012&include_prereleases&label=dev&logo=dart&style=flat-square)](https://pub.dev/packages/flutter_qweather) 5 | [![CodeFactor](https://img.shields.io/codefactor/grade/github/fluttercandies/flutter_qweather?logo=codefactor&logoColor=%23ffffff&style=flat-square)](https://www.codefactor.io/repository/github/fluttercandies/flutter_qweather) 6 | [![GitHub license](https://img.shields.io/github/license/fluttercandies/flutter_qweather?style=flat-square)](https://github.com/fluttercandies/flutter_qweather/blob/master/LICENSE) 7 | [![GitHub stars](https://img.shields.io/github/stars/fluttercandies/flutter_qweather?logo=github&style=flat-square)](https://github.com/fluttercandies/flutter_qweather/stargazers) 8 | [![GitHub forks](https://img.shields.io/github/forks/fluttercandies/flutter_qweather?logo=github&style=flat-square)](https://github.com/fluttercandies/flutter_qweather/network) 9 | FlutterCandies 10 | 11 | ## qweather_icons 12 | 13 | 若需要图标支持,请查看 [qweather_icons](https://pub.dev/packages/qweather_icons) 包。 14 | 15 | ## 已有功能 16 | - [x] 城市信息查询 17 | - [x] 热门城市查询 18 | - [x] POI信息搜索 19 | - [x] POI范围搜索 20 | - [x] 实时天气查询 21 | - [x] 逐天天气查询 22 | - [x] 逐时天气查询 23 | - [x] 中国地区未来2小时内每5分钟降水查询 24 | - [x] 当天生活指数查询 25 | - [x] 三天生活指数查询 26 | - [x] 天气灾害预警 27 | - [x] 灾害预警列表 28 | - [x] 空气质量实况 29 | - [x] 空气质量5天预报 30 | - [x] 历史天气 31 | - [x] 历史空气质量 32 | - [x] 日出日落 33 | - [x] 月升月落月相 34 | - [x] 太阳高度角 35 | - [x] 潮汐 36 | - [x] 潮流 37 | - [x] 台风列表 38 | - [x] 台风实况和路径 39 | - [x] 台风预报 40 | - [ ] 其他功能(好像没有了) 41 | 42 | ## 运行 43 | ### 注册账号 并 get 秘钥 44 | 首先你得有个和风天气的账号,[去吧骚年](https://id.qweather.com)。账号注册成功后在应用管理创建应用。注意包名别写错了哦。 45 | 46 | #### 本项目 example 的包名 47 | 48 | Android:com.fluttercandies.flutter_qweather_example 49 | ios: com.fluttercandies.flutterQweatherExample 50 | ### 初始化插件 51 | ```dart 52 | QweatherConfig config = QweatherConfig( 53 | publicIdForAndroid: 'HE210xxxxxxxxxxxxx', 54 | keyForAndroid: '8453863xxxxxxxxxxxxxxxxxxxxxxxxxx', 55 | publicIdForIos: 'HE210xxxxxxxxxxxxx', 56 | keyForIos: 'aead742xxxxxxxxxxxxxxxxxxxxxxxxx', 57 | biz: false, 58 | debug: true); 59 | await FlutterQweather.instance.init(config); 60 | ``` 61 | location 为 LocationID 或者 经纬度; 62 | LocationID 可通过geo 接口查询 或 查看[https://github.com/qwd/LocationList](https://github.com/qwd/LocationList) 63 | 64 | ### 实时天气查询 65 | ```dart 66 | String location = '116.41,39.92'; 67 | WeatherNow? _resp = await FlutterQweather.instance.getWeatherNow(location); 68 | ``` 69 | 70 | ### 逐天天气查询 71 | 72 | ```dart 73 | String location = '116.41,39.92'; 74 | WeatherDailyResp? _resp = await FlutterQweather.instance.getWeatherDaily(location, WeatherDailyForecast.WeatherForecast3Day); 75 | ``` 76 | 77 | ### 逐时天气查询 78 | ```dart 79 | String location = '116.41,39.92'; 80 | WeatherHourlyResp? _resp = await FlutterQweather.instance.getWeatherHourly(location, WeatherHourlyForecast.WeatherForecast24Hour); 81 | ``` 82 | 83 | ### 中国地区未来2小时内每5分钟降水查询 84 | ```dart 85 | String location = '116.41,39.92'; 86 | WeatherMinutelyResp? _resp = await FlutterQweather.instance.getWeatherMinuteLy(location); 87 | ``` 88 | ### 其他接口....相信你能看懂怎么用 89 | 90 | ## 贡献代码 91 | 第一次写跟原生交互的插件,望各位大大多多指点,有写得不好的地方,请直接用 PR 来怼我。 92 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.fluttercandies.flutter_qweather' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.6.10' 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:4.1.0' 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | rootProject.allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | apply plugin: 'com.android.library' 25 | apply plugin: 'kotlin-android' 26 | 27 | android { 28 | compileSdkVersion 31 29 | 30 | sourceSets { 31 | main.java.srcDirs += 'src/main/kotlin' 32 | } 33 | defaultConfig { 34 | minSdkVersion 19 35 | } 36 | packagingOptions { 37 | merge 'AndroidManifest.xml' 38 | } 39 | buildTypes { 40 | release { 41 | consumerProguardFiles "proguard-rules.pro" 42 | } 43 | } 44 | } 45 | 46 | dependencies { 47 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 48 | implementation fileTree(dir: 'libs', include: ['*.jar']) 49 | implementation 'com.squareup.okhttp3:okhttp:3.12.12+' 50 | implementation 'com.google.code.gson:gson:2.6.2+' 51 | } 52 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 6 | -------------------------------------------------------------------------------- /android/libs/QWeather_Public_Android_V4.11.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/android/libs/QWeather_Public_Android_V4.11.jar -------------------------------------------------------------------------------- /android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # 排除okhttp 2 | -dontwarn com.squareup.** 3 | -dontwarn okio.** 4 | -keep public class org.codehaus.* { *; } 5 | -keep public class java.nio.* { *; } 6 | 7 | # 排除QWeather 8 | -dontwarn com.qweather.sdk.** 9 | -keep class com.qweather.sdk.** { *;} 10 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_qweather' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiAir.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.air.AirDailyBean; 7 | import com.qweather.sdk.bean.air.AirNowBean; 8 | import com.qweather.sdk.bean.base.Lang; 9 | import com.qweather.sdk.view.QWeather; 10 | 11 | import java.util.Map; 12 | 13 | import io.flutter.plugin.common.MethodChannel; 14 | 15 | public class ApiAir { 16 | /// 获取实时空气质量 17 | protected static void getAirNow(Context context, Object arguments, final MethodChannel.Result result) { 18 | String location = (String) arguments; 19 | QWeather.OnResultAirNowListener onResultAirNowListener = new QWeather.OnResultAirNowListener() { 20 | @Override 21 | public void onError(Throwable throwable) { 22 | DebugPrint.print("getAirNow onError: " + throwable.getLocalizedMessage()); 23 | result.success(null); 24 | } 25 | 26 | @Override 27 | public void onSuccess(AirNowBean airNowBean) { 28 | Gson gson = new Gson(); 29 | String jsonStr = gson.toJson(airNowBean); 30 | DebugPrint.print("getAirNow onSuccess: " + jsonStr); 31 | result.success(gson.fromJson(jsonStr, Map.class)); 32 | } 33 | }; 34 | QWeather.getAirNow(context, location, Lang.ZH_HANS, onResultAirNowListener); 35 | } 36 | 37 | /// 获取5天空气质量预报 38 | protected static void getAir5Day(Context context, Object arguments, final MethodChannel.Result result) { 39 | String location = (String) arguments; 40 | QWeather.OnResultAirDailyListener onResultAirDailyListener = new QWeather.OnResultAirDailyListener() { 41 | @Override 42 | public void onError(Throwable throwable) { 43 | DebugPrint.print("getAir5Day onError: " + throwable.getLocalizedMessage()); 44 | result.success(null); 45 | } 46 | 47 | @Override 48 | public void onSuccess(AirDailyBean airDailyBean) { 49 | Gson gson = new Gson(); 50 | String jsonStr = gson.toJson(airDailyBean); 51 | DebugPrint.print("getAir5Day onSuccess: " + jsonStr); 52 | result.success(gson.fromJson(jsonStr, Map.class)); 53 | } 54 | }; 55 | QWeather.getAir5D(context, location, Lang.ZH_HANS, onResultAirDailyListener); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiAstronomy.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.sunmoon.MoonBean; 7 | import com.qweather.sdk.bean.sunmoon.SolarElevationAngleBean; 8 | import com.qweather.sdk.bean.sunmoon.SunBean; 9 | import com.qweather.sdk.view.QWeather; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | import io.flutter.plugin.common.MethodChannel; 15 | 16 | public class ApiAstronomy { 17 | /// 获取日出日落 18 | protected static void getSun(Context context, Object arguments, final MethodChannel.Result result) { 19 | @SuppressWarnings("unchecked") 20 | HashMap param = (HashMap) arguments; 21 | String location = (String) param.get("location"); 22 | String date = (String) param.get("date"); 23 | QWeather.OnResultSunListener onResultSunListener = new QWeather.OnResultSunListener() { 24 | @Override 25 | public void onError(Throwable throwable) { 26 | DebugPrint.print("getSun onError: " + throwable.getLocalizedMessage()); 27 | result.success(null); 28 | } 29 | 30 | @Override 31 | public void onSuccess(SunBean sunBean) { 32 | Gson gson = new Gson(); 33 | String jsonStr = gson.toJson(sunBean); 34 | DebugPrint.print("getSun onSuccess: " + jsonStr); 35 | result.success(gson.fromJson(jsonStr, Map.class)); 36 | } 37 | }; 38 | QWeather.getSun(context, location, date, onResultSunListener); 39 | } 40 | 41 | /// 获取月升月落月相 42 | protected static void getMoon(Context context, Object arguments, final MethodChannel.Result result) { 43 | @SuppressWarnings("unchecked") 44 | HashMap param = (HashMap) arguments; 45 | String location = (String) param.get("location"); 46 | String date = (String) param.get("date"); 47 | QWeather.OnResultMoonListener onResultMoonListener = new QWeather.OnResultMoonListener() { 48 | @Override 49 | public void onError(Throwable throwable) { 50 | DebugPrint.print("getMoon onError: " + throwable.getLocalizedMessage()); 51 | result.success(null); 52 | } 53 | 54 | @Override 55 | public void onSuccess(MoonBean moonBean) { 56 | Gson gson = new Gson(); 57 | String jsonStr = gson.toJson(moonBean); 58 | DebugPrint.print("getMoon onSuccess: " + jsonStr); 59 | result.success(gson.fromJson(jsonStr, Map.class)); 60 | } 61 | }; 62 | QWeather.getMoon(context, location, date, onResultMoonListener); 63 | } 64 | 65 | /// 获取太阳高度角 66 | protected static void getSolarElevationAngle(Context context, Object arguments, final MethodChannel.Result result) { 67 | @SuppressWarnings("unchecked") 68 | HashMap param = (HashMap) arguments; 69 | String location = (String) param.get("location"); 70 | String date = (String) param.get("date"); 71 | String time = (String) param.get("time"); 72 | String tz = (String) param.get("tz"); 73 | String alt = (String) param.get("alt"); 74 | QWeather.OnResultSolarElevationAngleListener onResultMoonListener = new QWeather.OnResultSolarElevationAngleListener() { 75 | @Override 76 | public void onError(Throwable throwable) { 77 | DebugPrint.print("getSolarElevationAngle onError: " + throwable.getLocalizedMessage()); 78 | result.success(null); 79 | } 80 | 81 | @Override 82 | public void onSuccess(SolarElevationAngleBean solarElevationAngleBean) { 83 | Gson gson = new Gson(); 84 | String jsonStr = gson.toJson(solarElevationAngleBean); 85 | DebugPrint.print("getSolarElevationAngle onSuccess: " + jsonStr); 86 | result.success(gson.fromJson(jsonStr, Map.class)); 87 | } 88 | }; 89 | QWeather.getSolarElevationAngle(context, location, date, time, tz, alt, onResultMoonListener); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiGeo.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.base.Lang; 7 | import com.qweather.sdk.bean.base.Range; 8 | import com.qweather.sdk.bean.base.Type; 9 | import com.qweather.sdk.bean.geo.GeoBean; 10 | import com.qweather.sdk.bean.geo.GeoPoiBean; 11 | import com.qweather.sdk.view.QWeather; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | import io.flutter.plugin.common.MethodChannel; 17 | 18 | public class ApiGeo { 19 | /// 城市信息查询 20 | protected static void geoCityLookup(Context context, Object arguments, final MethodChannel.Result result) { 21 | @SuppressWarnings("unchecked") 22 | HashMap param = (HashMap) arguments; 23 | String location = (String) param.get("location"); 24 | String range = (String) param.get("range"); 25 | Integer number = (Integer) param.get("number"); 26 | assert range != null && number != null; 27 | QWeather.OnResultGeoListener onResultGeoListener = new QWeather.OnResultGeoListener() { 28 | @Override 29 | public void onError(Throwable throwable) { 30 | DebugPrint.print("geoCityLookup onError: " + throwable.getLocalizedMessage()); 31 | result.success(null); 32 | } 33 | 34 | @Override 35 | public void onSuccess(GeoBean geoBean) { 36 | Gson gson = new Gson(); 37 | String jsonStr = gson.toJson(geoBean); 38 | jsonStr = jsonStr.replace("locationBean", "locations"); 39 | DebugPrint.print("geoCityLookup onSuccess: " + jsonStr); 40 | result.success(gson.fromJson(jsonStr, Map.class)); 41 | } 42 | }; 43 | QWeather.getGeoCityLookup(context, location, Range.valueOf(range.toUpperCase()), number, Lang.ZH_HANS, onResultGeoListener); 44 | } 45 | 46 | /// 热门城市查询 47 | protected static void getGeoTopCity(Context context, Object arguments, final MethodChannel.Result result) { 48 | @SuppressWarnings("unchecked") 49 | HashMap param = (HashMap) arguments; 50 | String range = (String) param.get("range"); 51 | Integer number = (Integer) param.get("number"); 52 | assert range != null && number != null; 53 | QWeather.OnResultGeoListener onResultGeoListener = new QWeather.OnResultGeoListener() { 54 | @Override 55 | public void onError(Throwable throwable) { 56 | DebugPrint.print("getGeoTopCity onError: " + throwable.getLocalizedMessage()); 57 | result.success(null); 58 | } 59 | 60 | @Override 61 | public void onSuccess(GeoBean geoBean) { 62 | Gson gson = new Gson(); 63 | String jsonStr = gson.toJson(geoBean); 64 | jsonStr = jsonStr.replace("locationBean", "locations"); 65 | DebugPrint.print("getGeoTopCity onSuccess: " + jsonStr); 66 | result.success(gson.fromJson(jsonStr, Map.class)); 67 | } 68 | }; 69 | QWeather.getGeoTopCity(context, number, Range.valueOf(range.toUpperCase()), Lang.ZH_HANS, onResultGeoListener); 70 | } 71 | 72 | /// POI信息搜索 73 | protected static void geoPoiLookup(Context context, Object arguments, final MethodChannel.Result result) { 74 | @SuppressWarnings("unchecked") 75 | HashMap param = (HashMap) arguments; 76 | String location = (String) param.get("location"); 77 | String city = (String) param.get("city"); 78 | String type = (String) param.get("type"); 79 | Integer number = (Integer) param.get("number"); 80 | assert type != null && number != null; 81 | QWeather.OnResultGeoPoiListener onResultGeoPoiListener = new QWeather.OnResultGeoPoiListener() { 82 | @Override 83 | public void onError(Throwable throwable) { 84 | DebugPrint.print("geoPoiLookup onError: " + throwable.getLocalizedMessage()); 85 | result.success(null); 86 | } 87 | 88 | @Override 89 | public void onSuccess(GeoPoiBean geoPoiBean) { 90 | Gson gson = new Gson(); 91 | String jsonStr = gson.toJson(geoPoiBean); 92 | jsonStr = jsonStr.replace("poiList", "locations"); 93 | DebugPrint.print("geoPoiLookup onSuccess: " + jsonStr); 94 | result.success(gson.fromJson(jsonStr, Map.class)); 95 | } 96 | }; 97 | QWeather.getGeoPoiLookup(context, location, city, number, Type.valueOf(type.toUpperCase()), Lang.ZH_HANS, onResultGeoPoiListener); 98 | } 99 | 100 | /// POI范围搜索 101 | protected static void geoPoiRangeLookup(Context context, Object arguments, final MethodChannel.Result result) { 102 | @SuppressWarnings("unchecked") 103 | HashMap param = (HashMap) arguments; 104 | String location = (String) param.get("location"); 105 | String type = (String) param.get("type"); 106 | Integer radius = (Integer) param.get("radius"); 107 | Integer number = (Integer) param.get("number"); 108 | assert type != null && number != null && radius != null; 109 | QWeather.OnResultGeoPoiListener onResultGeoPoiListener = new QWeather.OnResultGeoPoiListener() { 110 | @Override 111 | public void onError(Throwable throwable) { 112 | DebugPrint.print("geoPoiRangeLookup onError: " + throwable.getLocalizedMessage()); 113 | result.success(null); 114 | } 115 | 116 | @Override 117 | public void onSuccess(GeoPoiBean geoPoiBean) { 118 | Gson gson = new Gson(); 119 | String jsonStr = gson.toJson(geoPoiBean); 120 | jsonStr = jsonStr.replace("poiList", "locations"); 121 | DebugPrint.print("geoPoiRangeLookup onSuccess: " + jsonStr); 122 | result.success(gson.fromJson(jsonStr, Map.class)); 123 | } 124 | }; 125 | QWeather.getGeoPoiRange(context, location, radius, number, Type.valueOf(type.toUpperCase()), Lang.ZH_HANS, onResultGeoPoiListener); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiHistory.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.history.HistoricalAirBean; 7 | import com.qweather.sdk.bean.history.HistoryWeatherBean; 8 | import com.qweather.sdk.view.QWeather; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | import io.flutter.plugin.common.MethodChannel; 14 | 15 | public class ApiHistory { 16 | /// 获取历史天气 17 | protected static void getHistoricalWeather(Context context, Object arguments, final MethodChannel.Result result) { 18 | @SuppressWarnings("unchecked") 19 | HashMap param = (HashMap) arguments; 20 | String location = (String) param.get("location"); 21 | String date = (String) param.get("date"); 22 | QWeather.OnResultWeatherHistoricalBeanListener onResultWeatherHistoricalBeanListener = new QWeather.OnResultWeatherHistoricalBeanListener() { 23 | @Override 24 | public void onError(Throwable throwable) { 25 | DebugPrint.print("getHistoricalWeather onError: " + throwable.getLocalizedMessage()); 26 | result.success(null); 27 | } 28 | 29 | @Override 30 | public void onSuccess(HistoryWeatherBean historyWeatherBean) { 31 | Gson gson = new Gson(); 32 | String jsonStr = gson.toJson(historyWeatherBean); 33 | DebugPrint.print("getHistoricalWeather onSuccess: " + jsonStr); 34 | result.success(gson.fromJson(jsonStr, Map.class)); 35 | } 36 | }; 37 | QWeather.getHistoricalWeather(context, location, date, onResultWeatherHistoricalBeanListener); 38 | } 39 | 40 | /// 获取空气质量 41 | protected static void getHistoricalAir(Context context, Object arguments, final MethodChannel.Result result) { 42 | @SuppressWarnings("unchecked") 43 | HashMap param = (HashMap) arguments; 44 | String location = (String) param.get("location"); 45 | String date = (String) param.get("date"); 46 | QWeather.OnResultAirHistoricalBeanListener onResultAirHistoricalBeanListener = new QWeather.OnResultAirHistoricalBeanListener() { 47 | @Override 48 | public void onError(Throwable throwable) { 49 | DebugPrint.print("getHistoricalAir onError: " + throwable.getLocalizedMessage()); 50 | result.success(null); 51 | } 52 | 53 | @Override 54 | public void onSuccess(HistoricalAirBean historicalAirBean) { 55 | Gson gson = new Gson(); 56 | String jsonStr = gson.toJson(historicalAirBean); 57 | DebugPrint.print("getHistoricalAir onSuccess: " + jsonStr); 58 | result.success(gson.fromJson(jsonStr, Map.class)); 59 | } 60 | }; 61 | QWeather.getHistoricalAir(context, location, date, onResultAirHistoricalBeanListener); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiIndices.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.IndicesBean; 7 | import com.qweather.sdk.bean.base.IndicesType; 8 | import com.qweather.sdk.bean.base.Lang; 9 | import com.qweather.sdk.view.QWeather; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Collections; 13 | import java.util.HashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | import io.flutter.plugin.common.MethodChannel; 18 | 19 | public class ApiIndices { 20 | /// 获取1天生活指数 21 | protected static void getIndices1Day(Context context, Object arguments, final MethodChannel.Result result) { 22 | getIndices("getIndices1Day", context, arguments, result); 23 | } 24 | 25 | /// 获取3天生活指数 26 | protected static void getIndices3Day(Context context, Object arguments, final MethodChannel.Result result) { 27 | getIndices("getIndices3Day", context, arguments, result); 28 | } 29 | 30 | private static void getIndices(final String name, Context context, Object arguments, final MethodChannel.Result result) { 31 | @SuppressWarnings("unchecked") 32 | HashMap param = (HashMap) arguments; 33 | String location = (String) param.get("location"); 34 | @SuppressWarnings("unchecked") 35 | List indicesTypes = (List) param.get("indicesTypes"); 36 | List indicesTypesTmp = new ArrayList<>(); 37 | assert indicesTypes != null; 38 | for (String type : indicesTypes) { 39 | switch (type) { 40 | case "SPT": 41 | indicesTypesTmp.add(IndicesType.SPT); 42 | break; 43 | case "CW": 44 | indicesTypesTmp.add(IndicesType.CW); 45 | break; 46 | case "DRSG": 47 | indicesTypesTmp.add(IndicesType.DRSG); 48 | break; 49 | case "FIS": 50 | indicesTypesTmp.add(IndicesType.FIS); 51 | break; 52 | case "UV": 53 | indicesTypesTmp.add(IndicesType.UV); 54 | break; 55 | case "TRAV": 56 | indicesTypesTmp.add(IndicesType.TRAV); 57 | break; 58 | case "AG": 59 | indicesTypesTmp.add(IndicesType.AG); 60 | break; 61 | case "COMF": 62 | indicesTypesTmp.add(IndicesType.COMF); 63 | break; 64 | case "FLU": 65 | indicesTypesTmp.add(IndicesType.FLU); 66 | break; 67 | case "AP": 68 | indicesTypesTmp.add(IndicesType.AP); 69 | break; 70 | case "AC": 71 | indicesTypesTmp.add(IndicesType.AC); 72 | break; 73 | case "GL": 74 | indicesTypesTmp.add(IndicesType.GL); 75 | break; 76 | case "MU": 77 | indicesTypesTmp.add(IndicesType.MU); 78 | break; 79 | case "DC": 80 | indicesTypesTmp.add(IndicesType.DC); 81 | break; 82 | case "PTFC": 83 | indicesTypesTmp.add(IndicesType.PTFC); 84 | break; 85 | case "SPI": 86 | indicesTypesTmp.add(IndicesType.SPI); 87 | break; 88 | case "SKI": 89 | indicesTypesTmp.add(IndicesType.SK); 90 | break; 91 | default: 92 | indicesTypesTmp = Collections.singletonList(IndicesType.ALL); 93 | break; 94 | } 95 | if (indicesTypesTmp.contains(IndicesType.ALL)) break; 96 | } 97 | QWeather.OnResultIndicesListener onResultIndicesListener = new QWeather.OnResultIndicesListener() { 98 | @Override 99 | public void onError(Throwable throwable) { 100 | DebugPrint.print(name + " onError: " + throwable.getLocalizedMessage()); 101 | result.success(null); 102 | } 103 | 104 | @Override 105 | public void onSuccess(IndicesBean indicesBean) { 106 | Gson gson = new Gson(); 107 | String jsonStr = gson.toJson(indicesBean); 108 | DebugPrint.print(name + " onSuccess: " + jsonStr); 109 | result.success(gson.fromJson(jsonStr, Map.class)); 110 | } 111 | }; 112 | if (name.equals("getIndices1Day")) { 113 | QWeather.getIndices1D(context, location, Lang.ZH_HANS, indicesTypesTmp, onResultIndicesListener); 114 | } else { 115 | QWeather.getIndices3D(context, location, Lang.ZH_HANS, indicesTypesTmp, onResultIndicesListener); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiOcean.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.ocean.CurrentsBean; 7 | import com.qweather.sdk.bean.ocean.TideBean; 8 | import com.qweather.sdk.view.QWeather; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | import io.flutter.plugin.common.MethodChannel; 14 | 15 | public class ApiOcean { 16 | /// 获取潮汐 17 | protected static void getOceanTide(Context context, Object arguments, final MethodChannel.Result result) { 18 | @SuppressWarnings("unchecked") 19 | HashMap param = (HashMap) arguments; 20 | String location = (String) param.get("location"); 21 | String date = (String) param.get("date"); 22 | QWeather.OnResultOceanTideListener onResultOceanTideListener = new QWeather.OnResultOceanTideListener() { 23 | @Override 24 | public void onError(Throwable throwable) { 25 | DebugPrint.print("getOceanTide onError: " + throwable.getLocalizedMessage()); 26 | result.success(null); 27 | } 28 | 29 | @Override 30 | public void onSuccess(TideBean tideBean) { 31 | Gson gson = new Gson(); 32 | String jsonStr = gson.toJson(tideBean); 33 | DebugPrint.print("getOceanTide onSuccess: " + jsonStr); 34 | result.success(gson.fromJson(jsonStr, Map.class)); 35 | } 36 | }; 37 | QWeather.getOceanTide(context, location, date, onResultOceanTideListener); 38 | } 39 | 40 | /// 获取潮流 41 | protected static void getOceanCurrents(Context context, Object arguments, final MethodChannel.Result result) { 42 | @SuppressWarnings("unchecked") 43 | HashMap param = (HashMap) arguments; 44 | String location = (String) param.get("location"); 45 | String date = (String) param.get("date"); 46 | QWeather.OnResultOceanCurrentsListener onResultOceanCurrentsListener = new QWeather.OnResultOceanCurrentsListener() { 47 | @Override 48 | public void onError(Throwable throwable) { 49 | DebugPrint.print("getOceanCurrents onError: " + throwable.getLocalizedMessage()); 50 | result.success(null); 51 | } 52 | 53 | @Override 54 | public void onSuccess(CurrentsBean currentsBean) { 55 | Gson gson = new Gson(); 56 | String jsonStr = gson.toJson(currentsBean); 57 | DebugPrint.print("getOceanCurrents onSuccess: " + jsonStr); 58 | result.success(gson.fromJson(jsonStr, Map.class)); 59 | } 60 | }; 61 | QWeather.getOceanCurrents(context, location, date, onResultOceanCurrentsListener); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiTropical.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.base.Basin; 7 | import com.qweather.sdk.bean.tropical.StormForecastBean; 8 | import com.qweather.sdk.bean.tropical.StormListBean; 9 | import com.qweather.sdk.bean.tropical.StormTrackBean; 10 | import com.qweather.sdk.view.QWeather; 11 | 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | import io.flutter.plugin.common.MethodChannel; 16 | 17 | public class ApiTropical { 18 | /// 台风列表 19 | protected static void getStormList(Context context, Object arguments, final MethodChannel.Result result) { 20 | @SuppressWarnings("unchecked") 21 | HashMap param = (HashMap) arguments; 22 | String year = (String) param.get("year"); 23 | String basin = (String) param.get("basin"); 24 | QWeather.OnResultTropicalStormListListener onResultTropicalStormListListener = new QWeather.OnResultTropicalStormListListener() { 25 | @Override 26 | public void onError(Throwable throwable) { 27 | DebugPrint.print("getStormList onError: " + throwable.getLocalizedMessage()); 28 | result.success(null); 29 | } 30 | 31 | @Override 32 | public void onSuccess(StormListBean stormListBean) { 33 | Gson gson = new Gson(); 34 | String jsonStr = gson.toJson(stormListBean); 35 | DebugPrint.print("getStormList onSuccess: " + jsonStr); 36 | result.success(gson.fromJson(jsonStr, Map.class)); 37 | } 38 | }; 39 | QWeather.getStormList(context, year, Basin.valueOf(basin), onResultTropicalStormListListener); 40 | } 41 | 42 | /// 台风实况和路径 43 | protected static void getStormTrack(Context context, Object arguments, final MethodChannel.Result result) { 44 | String stormId = (String) arguments; 45 | QWeather.OnResultTropicalStormTrackListener onResultTropicalStormTrackListener = new QWeather.OnResultTropicalStormTrackListener() { 46 | @Override 47 | public void onError(Throwable throwable) { 48 | DebugPrint.print("getStormTrack onError: " + throwable.getLocalizedMessage()); 49 | result.success(null); 50 | } 51 | 52 | @Override 53 | public void onSuccess(StormTrackBean stormTrackBean) { 54 | Gson gson = new Gson(); 55 | String jsonStr = gson.toJson(stormTrackBean); 56 | DebugPrint.print("getStormTrack onSuccess: " + jsonStr); 57 | result.success(gson.fromJson(jsonStr, Map.class)); 58 | } 59 | }; 60 | QWeather.getStormTrack(context, stormId, onResultTropicalStormTrackListener); 61 | } 62 | 63 | /// 台风预报 64 | protected static void getStormForecast(Context context, Object arguments, final MethodChannel.Result result) { 65 | String stormId = (String) arguments; 66 | QWeather.OnResultTropicalStormForecastListener onResultTropicalStormForecastListener = new QWeather.OnResultTropicalStormForecastListener() { 67 | @Override 68 | public void onError(Throwable throwable) { 69 | DebugPrint.print("getStormTrack onError: " + throwable.getLocalizedMessage()); 70 | result.success(null); 71 | } 72 | 73 | @Override 74 | public void onSuccess(StormForecastBean stormForecastBean) { 75 | Gson gson = new Gson(); 76 | String jsonStr = gson.toJson(stormForecastBean); 77 | DebugPrint.print("getStormForecast onSuccess: " + jsonStr); 78 | result.success(gson.fromJson(jsonStr, Map.class)); 79 | } 80 | }; 81 | QWeather.getStormForecast(context, stormId, onResultTropicalStormForecastListener); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiWarning.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.WarningBean; 7 | import com.qweather.sdk.bean.WarningListBean; 8 | import com.qweather.sdk.bean.base.Lang; 9 | import com.qweather.sdk.bean.base.Range; 10 | import com.qweather.sdk.view.QWeather; 11 | 12 | import java.util.Map; 13 | 14 | import io.flutter.plugin.common.MethodChannel; 15 | 16 | public class ApiWarning { 17 | /// 获取灾害预警 18 | protected static void getWarning(Context context, Object arguments, final MethodChannel.Result result) { 19 | String location = (String) arguments; 20 | QWeather.OnResultWarningListener onResultWarningListener = new QWeather.OnResultWarningListener() { 21 | @Override 22 | public void onError(Throwable throwable) { 23 | DebugPrint.print("getWarning onError: " + throwable.getLocalizedMessage()); 24 | result.success(null); 25 | } 26 | 27 | @Override 28 | public void onSuccess(WarningBean warningBean) { 29 | Gson gson = new Gson(); 30 | String jsonStr = gson.toJson(warningBean); 31 | DebugPrint.print("getWarning onSuccess: " + jsonStr); 32 | result.success(gson.fromJson(jsonStr, Map.class)); 33 | } 34 | }; 35 | QWeather.getWarning(context, location, onResultWarningListener); 36 | } 37 | 38 | /// 获取灾害预警列表 39 | protected static void getWarningList(Context context, Object arguments, final MethodChannel.Result result) { 40 | String range = (String) arguments; 41 | QWeather.OnResultWarningListListener onResultWarningListListener = new QWeather.OnResultWarningListListener() { 42 | @Override 43 | public void onError(Throwable throwable) { 44 | DebugPrint.print("getWarningList onError: " + throwable.getLocalizedMessage()); 45 | result.success(null); 46 | } 47 | 48 | @Override 49 | public void onSuccess(WarningListBean warningListBean) { 50 | Gson gson = new Gson(); 51 | String jsonStr = gson.toJson(warningListBean); 52 | DebugPrint.print("getWarningList onSuccess: " + jsonStr); 53 | result.success(gson.fromJson(jsonStr, Map.class)); 54 | } 55 | }; 56 | QWeather.getWarningList(context, Range.valueOf(range.toUpperCase()), onResultWarningListListener); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/ApiWeather.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | import com.qweather.sdk.bean.MinutelyBean; 7 | import com.qweather.sdk.bean.weather.WeatherDailyBean; 8 | import com.qweather.sdk.bean.weather.WeatherHourlyBean; 9 | import com.qweather.sdk.bean.weather.WeatherNowBean; 10 | import com.qweather.sdk.view.QWeather; 11 | 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | import io.flutter.plugin.common.MethodChannel; 15 | 16 | public class ApiWeather { 17 | /// 获取实时天气 18 | protected static void getWeatherNow(Context context, Object arguments, final MethodChannel.Result result) { 19 | String location = (String) arguments; 20 | QWeather.OnResultWeatherNowListener onResultWeatherNowListener = new QWeather.OnResultWeatherNowListener() { 21 | @Override 22 | public void onError(Throwable throwable) { 23 | DebugPrint.print("getWeatherNow onError: " + throwable.getLocalizedMessage()); 24 | result.success(null); 25 | } 26 | 27 | @Override 28 | public void onSuccess(WeatherNowBean weatherNowBean) { 29 | Gson gson = new Gson(); 30 | String jsonStr = gson.toJson(weatherNowBean); 31 | DebugPrint.print("getWeatherNow onSuccess: " + jsonStr); 32 | result.success(gson.fromJson(jsonStr, Map.class)); 33 | } 34 | }; 35 | QWeather.getWeatherNow(context, location, onResultWeatherNowListener); 36 | } 37 | 38 | /// 获取逐天预报 39 | protected static void getWeatherDaily(Context context, Object arguments, final MethodChannel.Result result) { 40 | @SuppressWarnings("unchecked") 41 | HashMap param = (HashMap) arguments; 42 | String location = (String) param.get("location"); 43 | Integer dailyForecast = (Integer) param.get("daily"); 44 | assert dailyForecast != null; 45 | QWeather.OnResultWeatherDailyListener onResultWeatherDailyListener = new QWeather.OnResultWeatherDailyListener() { 46 | @Override 47 | public void onError(Throwable throwable) { 48 | DebugPrint.print("getWeatherDaily onError: " + throwable.getLocalizedMessage()); 49 | result.success(null); 50 | } 51 | 52 | @Override 53 | public void onSuccess(WeatherDailyBean weatherDailyBean) { 54 | Gson gson = new Gson(); 55 | String jsonStr = gson.toJson(weatherDailyBean); 56 | DebugPrint.print("getWeatherDaily onSuccess: " + jsonStr); 57 | result.success(gson.fromJson(jsonStr, Map.class)); 58 | } 59 | }; 60 | if (dailyForecast == 3) { 61 | QWeather.getWeather3D(context, location, onResultWeatherDailyListener); 62 | } else if (dailyForecast == 7) { 63 | QWeather.getWeather7D(context, location, onResultWeatherDailyListener); 64 | } else if (dailyForecast == 10) { 65 | QWeather.getWeather10D(context, location, onResultWeatherDailyListener); 66 | } else if (dailyForecast == 15) { 67 | QWeather.getWeather15D(context, location, onResultWeatherDailyListener); 68 | } 69 | } 70 | 71 | /// 获取逐时预报 72 | protected static void getWeatherHourly(Context context, Object arguments, final MethodChannel.Result result) { 73 | @SuppressWarnings("unchecked") 74 | HashMap param = (HashMap) arguments; 75 | String location = (String) param.get("location"); 76 | Integer hourlyForecast = (Integer) param.get("hourly"); 77 | assert hourlyForecast != null; 78 | QWeather.OnResultWeatherHourlyListener onResultWeatherHourlyListener = new QWeather.OnResultWeatherHourlyListener() { 79 | @Override 80 | public void onError(Throwable throwable) { 81 | DebugPrint.print("getWeatherHourly onError: " + throwable.getLocalizedMessage()); 82 | result.success(null); 83 | } 84 | 85 | @Override 86 | public void onSuccess(WeatherHourlyBean weatherHourlyBean) { 87 | Gson gson = new Gson(); 88 | String jsonStr = gson.toJson(weatherHourlyBean); 89 | DebugPrint.print("getWeatherHourly onSuccess: " + jsonStr); 90 | result.success(gson.fromJson(jsonStr, Map.class)); 91 | } 92 | }; 93 | if (hourlyForecast == 24) { 94 | QWeather.getWeather24Hourly(context, location, onResultWeatherHourlyListener); 95 | } else if (hourlyForecast == 72) { 96 | QWeather.getWeather72Hourly(context, location, onResultWeatherHourlyListener); 97 | } else if (hourlyForecast == 168) { 98 | QWeather.getWeather168Hourly(context, location, onResultWeatherHourlyListener); 99 | } 100 | } 101 | 102 | /// 获取中国地区未来2小时内每5分钟降水 103 | protected static void getWeatherMinuteLy(Context context, Object arguments, final MethodChannel.Result result) { 104 | String location = (String) arguments; 105 | QWeather.OnResultMinutelyListener onResultMinutelyListener = new QWeather.OnResultMinutelyListener() { 106 | @Override 107 | public void onError(Throwable throwable) { 108 | DebugPrint.print("getWeatherMinuteLy onError: " + throwable.getLocalizedMessage()); 109 | result.success(null); 110 | } 111 | 112 | @Override 113 | public void onSuccess(MinutelyBean minutelyBean) { 114 | Gson gson = new Gson(); 115 | String jsonStr = gson.toJson(minutelyBean); 116 | DebugPrint.print("getWeatherMinuteLy onSuccess: " + jsonStr); 117 | result.success(gson.fromJson(jsonStr, Map.class)); 118 | } 119 | }; 120 | QWeather.getMinuteLy(context, location, onResultMinutelyListener); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/DebugPrint.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | /// 调试打印 4 | public class DebugPrint { 5 | private static boolean _debug = false; 6 | 7 | 8 | public static void setDebug(boolean debug) { 9 | if (_debug != debug){ 10 | System.out.println("com.fluttercandies.qweather: 设置调试模式:" + debug); 11 | _debug = debug; 12 | } 13 | } 14 | 15 | public static void print(String value) { 16 | if (_debug) System.out.println("com.fluttercandies.qweather: " + value); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/FlutterQweatherPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather 2 | 3 | import android.content.Context 4 | import androidx.annotation.NonNull 5 | import com.qweather.sdk.view.HeConfig 6 | import io.flutter.embedding.engine.plugins.FlutterPlugin 7 | import io.flutter.plugin.common.MethodCall 8 | import io.flutter.plugin.common.MethodChannel 9 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler 10 | import io.flutter.plugin.common.MethodChannel.Result 11 | 12 | /** FlutterQweatherPlugin */ 13 | class FlutterQweatherPlugin : FlutterPlugin, MethodCallHandler { 14 | private lateinit var channel: MethodChannel 15 | private lateinit var context: Context 16 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { 17 | channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.fluttercandies.qweather") 18 | channel.setMethodCallHandler(this) 19 | context = flutterPluginBinding.applicationContext 20 | } 21 | 22 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { 23 | when (call.method) { 24 | MethodConstants.GetPlatformVersion -> result.success("Android ${android.os.Build.VERSION.RELEASE}") 25 | MethodConstants.SetDebug -> setDebug(call.arguments, result) 26 | MethodConstants.Init -> init(call.arguments, result) 27 | MethodConstants.GeoCityLookup -> ApiGeo.geoCityLookup(context, call.arguments, result) 28 | MethodConstants.GetGeoTopCity -> ApiGeo.getGeoTopCity(context, call.arguments, result) 29 | MethodConstants.GeoPoiLookup -> ApiGeo.geoPoiLookup(context, call.arguments, result) 30 | MethodConstants.GeoPoiRangeLookup -> ApiGeo.geoPoiRangeLookup(context, call.arguments, result) 31 | MethodConstants.GetWeatherNow -> ApiWeather.getWeatherNow(context, call.arguments, result) 32 | MethodConstants.GetWeatherDaily -> ApiWeather.getWeatherDaily(context, call.arguments, result) 33 | MethodConstants.GetWeatherHourly -> ApiWeather.getWeatherHourly(context, call.arguments, result) 34 | MethodConstants.GetWeatherMinuteLy -> ApiWeather.getWeatherMinuteLy(context, call.arguments, result) 35 | MethodConstants.GetIndices1Day -> ApiIndices.getIndices1Day(context, call.arguments, result) 36 | MethodConstants.GetIndices3Day -> ApiIndices.getIndices3Day(context, call.arguments, result) 37 | MethodConstants.GetWarning -> ApiWarning.getWarning(context, call.arguments, result) 38 | MethodConstants.GetWarningList -> ApiWarning.getWarningList(context, call.arguments, result) 39 | MethodConstants.GetAirNow -> ApiAir.getAirNow(context, call.arguments, result) 40 | MethodConstants.GetAir5Day -> ApiAir.getAir5Day(context, call.arguments, result) 41 | MethodConstants.GetHistoricalWeather -> ApiHistory.getHistoricalWeather(context, call.arguments, result) 42 | MethodConstants.GetHistoricalAir -> ApiHistory.getHistoricalAir(context, call.arguments, result) 43 | MethodConstants.GetSun -> ApiAstronomy.getSun(context, call.arguments, result) 44 | MethodConstants.GetMoon -> ApiAstronomy.getMoon(context, call.arguments, result) 45 | MethodConstants.GetSolarElevationAngle -> ApiAstronomy.getSolarElevationAngle(context, call.arguments, result) 46 | MethodConstants.GetOceanTide -> ApiOcean.getOceanTide(context, call.arguments, result) 47 | MethodConstants.GetOceanCurrents -> ApiOcean.getOceanCurrents(context, call.arguments, result) 48 | MethodConstants.GetStormList -> ApiTropical.getStormList(context, call.arguments, result) 49 | MethodConstants.GetStormTrack -> ApiTropical.getStormTrack(context, call.arguments, result) 50 | MethodConstants.GetStormForecast -> ApiTropical.getStormForecast(context, call.arguments, result) 51 | else -> result.notImplemented() 52 | } 53 | } 54 | 55 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { 56 | channel.setMethodCallHandler(null) 57 | } 58 | 59 | 60 | private fun setDebug(arguments: Any, result: Result) { 61 | DebugPrint.setDebug(arguments as Boolean) 62 | result.success(true) 63 | } 64 | 65 | private fun init(arguments: Any?, result: Result) { 66 | val argumentsMap = arguments as HashMap<*, *> 67 | val publicId = argumentsMap["publicId"] as String 68 | val key = argumentsMap["key"] as String 69 | val debug = argumentsMap["debug"] as Boolean 70 | val biz = argumentsMap["biz"] as Boolean 71 | DebugPrint.setDebug(debug) 72 | HeConfig.init(publicId, key) 73 | if (biz) HeConfig.switchToBizService() else HeConfig.switchToDevService() 74 | result.success(true) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/fluttercandies/flutter_qweather/MethodConstants.java: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather; 2 | 3 | /// 方法常量 4 | public class MethodConstants { 5 | /// 获取平台版本 6 | public static final String GetPlatformVersion = "GetPlatformVersion"; 7 | /// 设置 Debug 8 | public static final String SetDebug = "SetDebug"; 9 | /// 初始化 10 | public static final String Init = "Init"; 11 | 12 | // 城市信息查询 13 | public static final String GeoCityLookup = "GeoCityLookup"; 14 | 15 | // 热门城市查询 16 | public static final String GetGeoTopCity = "GetGeoTopCity"; 17 | 18 | // POI信息搜索 19 | public static final String GeoPoiLookup = "GeoPoiLookup"; 20 | 21 | // POI范围搜索 22 | public static final String GeoPoiRangeLookup = "GeoPoiRangeLookup"; 23 | 24 | /// 获取实况天气数据 25 | public static final String GetWeatherNow = "GetWeatherNow"; 26 | 27 | // 获取逐天预报 28 | public static final String GetWeatherDaily = "GetWeatherDaily"; 29 | 30 | // 获取逐时预报 31 | public static final String GetWeatherHourly = "GetWeatherHourly"; 32 | 33 | // 获取中国地区未来2小时内每5分钟降水 34 | public static final String GetWeatherMinuteLy = "GetWeatherMinuteLy"; 35 | 36 | // 获取1天生活指数 37 | public static final String GetIndices1Day = "GetIndices1Day"; 38 | 39 | // 获取3天生活指数 40 | public static final String GetIndices3Day = "GetIndices3Day"; 41 | 42 | // 获取灾害预警 43 | public static final String GetWarning = "GetWarning"; 44 | 45 | // 获取灾害预警列表 46 | public static final String GetWarningList = "GetWarningList"; 47 | 48 | // 获取实时空气质量 49 | public static final String GetAirNow = "GetAirNow"; 50 | 51 | // 获取5天空气质量预报 52 | public static final String GetAir5Day = "GetAir5Day"; 53 | 54 | /// 获取历史天气 55 | public static final String GetHistoricalWeather = "GetHistoricalWeather"; 56 | 57 | /// 获取历史空气质量 58 | public static final String GetHistoricalAir = "GetHistoricalAir"; 59 | 60 | /// 获取日出日落 61 | public static final String GetSun = "GetSun"; 62 | 63 | /// 获取月升月落月相 64 | public static final String GetMoon = "GetMoon"; 65 | 66 | /// 获取太阳高度角 67 | public static final String GetSolarElevationAngle = "GetSolarElevationAngle"; 68 | 69 | /// 获取潮汐 70 | public static final String GetOceanTide = "GetOceanTide"; 71 | 72 | /// 获取潮流 73 | public static final String GetOceanCurrents = "GetOceanCurrents"; 74 | 75 | /// 台风列表 76 | public static final String GetStormList = "GetStormList"; 77 | 78 | /// 台风实况和路径 79 | public static final String GetStormTrack = "GetStormTrack"; 80 | 81 | /// 台风预报 82 | public static final String GetStormForecast = "GetStormForecast"; 83 | } 84 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: adc687823a831bbebe28bdccfac1a628ca621513 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_qweather_example 2 | 3 | Demonstrates how to use the flutter_qweather plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 31 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.fluttercandies.flutter_qweather_example" 38 | minSdkVersion 19 39 | targetSdkVersion 30 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 59 | } 60 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 14 | 18 | 22 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/fluttercandies/flutter_qweather_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.fluttercandies.flutter_qweather_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (4.0.1): 3 | - AFNetworking/NSURLSession (= 4.0.1) 4 | - AFNetworking/Reachability (= 4.0.1) 5 | - AFNetworking/Security (= 4.0.1) 6 | - AFNetworking/Serialization (= 4.0.1) 7 | - AFNetworking/UIKit (= 4.0.1) 8 | - AFNetworking/NSURLSession (4.0.1): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (4.0.1) 13 | - AFNetworking/Security (4.0.1) 14 | - AFNetworking/Serialization (4.0.1) 15 | - AFNetworking/UIKit (4.0.1): 16 | - AFNetworking/NSURLSession 17 | - Flutter (1.0.0) 18 | - flutter_qweather (0.0.1): 19 | - AFNetworking (~> 4.0.0) 20 | - Flutter 21 | - QWeather-SDK 22 | - QWeather-SDK (4.10): 23 | - AFNetworking (~> 4.0.1) 24 | 25 | DEPENDENCIES: 26 | - Flutter (from `Flutter`) 27 | - flutter_qweather (from `.symlinks/plugins/flutter_qweather/ios`) 28 | 29 | SPEC REPOS: 30 | trunk: 31 | - AFNetworking 32 | - QWeather-SDK 33 | 34 | EXTERNAL SOURCES: 35 | Flutter: 36 | :path: Flutter 37 | flutter_qweather: 38 | :path: ".symlinks/plugins/flutter_qweather/ios" 39 | 40 | SPEC CHECKSUMS: 41 | AFNetworking: 7864c38297c79aaca1500c33288e429c3451fdce 42 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 43 | flutter_qweather: ca1274d27d146b749e5a617193d7acec763a4bb0 44 | QWeather-SDK: 20ef99647726903bb1583ceedee1d418176cedd4 45 | 46 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 47 | 48 | COCOAPODS: 1.11.3 49 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_qweather_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_qweather/constants.dart'; 6 | import 'package:flutter_qweather/flutter_qweather.dart'; 7 | 8 | void main() => runApp(MyApp()); 9 | 10 | class MyApp extends StatefulWidget { 11 | @override 12 | _MyAppState createState() => _MyAppState(); 13 | } 14 | 15 | class _MyAppState extends State { 16 | String _platformVersion = 'Unknown'; 17 | 18 | /// _location 19 | /// LocationID 或者 经纬度; 20 | /// LocationID 可通过geo 接口查询 或 查看https://github.com/qwd/LocationList 21 | String _location = "106.227305,29.592024"; 22 | TextEditingController _controller = TextEditingController(); 23 | WeatherNowResp? _weatherNowResp; 24 | 25 | @override 26 | void initState() { 27 | _controller.text = _location; 28 | super.initState(); 29 | initPlatformState(); 30 | initQweather(); 31 | } 32 | 33 | // 初始化 Qweather 34 | Future initQweather() async { 35 | QweatherConfig config = QweatherConfig( 36 | publicIdForAndroid: 'HE2104211812191773', 37 | keyForAndroid: '83716e1718b64b22b5b9615300ac366e', 38 | publicIdForIos: 'HE2104211812581604', 39 | keyForIos: 'e5d46c6726d34584ae16eb2e4520e610', 40 | biz: false, 41 | debug: true); 42 | await FlutterQweather.instance.init(config); 43 | // await FlutterQweather.instance.setDebug(); 44 | await queryWeatherNow(); 45 | FlutterQweather.instance.getAirNow(_location); 46 | // FlutterQweather.instance.geoPoiRangeLookup('116.40000,39.88999', PoiType.scenic); 47 | // FlutterQweather.instance.getWeatherMinuteLy(_location); 48 | // FlutterQweather.instance.geoPoiRangeLookup('116.40000,39.88999', PoiType.scenic); 49 | // FlutterQweather.instance.getIndices1Day('116.40000,39.88999',indicesTypes: {IndicesType.TRAV}); 50 | // FlutterQweather.instance.getWarning('116.40000,39.88999'); 51 | // FlutterQweather.instance.getWarningList(range: 'cn'); 52 | // FlutterQweather.instance.getSun('116.40000,39.88999', '20220419'); 53 | // FlutterQweather.instance.getMoon('116.40000,39.88999', '20220419'); 54 | // FlutterQweather.instance.getSolarElevationAngle( 55 | // location: '116.40000,39.88999', date: '20220419', 56 | // time: "1230", tz: "0800", alt: "430"); 57 | // FlutterQweather.instance.getHistoricalWeather('116.40000,39.88999', '20220419'); 58 | // FlutterQweather.instance.getHistoricalAir('116.40000,39.88999', '20220419'); 59 | } 60 | 61 | // 查询实时天气 62 | Future queryWeatherNow() async { 63 | setState(() => _weatherNowResp = null); 64 | // await Qweather.instance.getWeatherNow("101010100"); 65 | _weatherNowResp = await FlutterQweather.instance.getWeatherNow(_location); 66 | setState(() {}); 67 | } 68 | 69 | Future initPlatformState() async { 70 | String platformVersion; 71 | try { 72 | platformVersion = await FlutterQweather.instance.platformVersion; 73 | } on PlatformException { 74 | platformVersion = 'Failed to get platform version.'; 75 | } 76 | if (!mounted) return; 77 | setState(() => _platformVersion = platformVersion); 78 | } 79 | 80 | @override 81 | Widget build(BuildContext context) { 82 | return MaterialApp( 83 | home: Scaffold( 84 | appBar: AppBar(title: const Text('QWeather example app')), 85 | body: Column( 86 | children: [ 87 | Padding( 88 | padding: EdgeInsets.all(20), 89 | child: IntrinsicHeight( 90 | child: Row( 91 | children: [ 92 | Expanded( 93 | child: TextField( 94 | controller: _controller, 95 | onChanged: (v) => _location = v, 96 | decoration: InputDecoration( 97 | hintText: "请输入LocationID 或者 经纬度", 98 | ), 99 | ), 100 | ), 101 | ElevatedButton( 102 | child: Text("查询天气"), 103 | onPressed: 104 | _weatherNowResp == null || _location.trim().isEmpty 105 | ? null 106 | : queryWeatherNow, 107 | ) 108 | ], 109 | ), 110 | ), 111 | ), 112 | Expanded( 113 | child: _weatherNowResp == null 114 | ? Center(child: Text("loading...")) 115 | : _weatherNowWidget, 116 | ), 117 | Container( 118 | padding: EdgeInsets.all(64), 119 | child: Text('Running on: $_platformVersion\n'), 120 | ) 121 | ], 122 | ), 123 | ), 124 | ); 125 | } 126 | 127 | Widget get _weatherNowWidget { 128 | return Container( 129 | padding: EdgeInsets.symmetric(horizontal: 20, vertical: 20), 130 | alignment: Alignment.center, 131 | child: ListView( 132 | children: [ 133 | Text( 134 | "原始数据来源: ${_weatherNowResp?.refer.sources.join(",")}"), 135 | Text( 136 | "使用许可: ${_weatherNowResp?.refer.license.join(",")}"), 137 | Divider(), 138 | Text("接口更新时间: ${_weatherNowResp?.basic.updateTime}"), 139 | Text("所查询城市的天气预报网页: ${_weatherNowResp?.basic.fxLink}"), 140 | Divider(), 141 | Text("实况观测时间: ${_weatherNowResp?.now.obsTime}"), 142 | Text("体感温度,默认单位:摄氏度: ${_weatherNowResp?.now.feelsLike}"), 143 | Text("温度,默认单位:摄氏度: ${_weatherNowResp?.now.temp}"), 144 | Text("实况天气状况代码: ${_weatherNowResp?.now.icon}"), 145 | Text("实况天气状况: ${_weatherNowResp?.now.text}"), 146 | Text("风向360角度: ${_weatherNowResp?.now.wind360}"), 147 | Text("风向: ${_weatherNowResp?.now.windDir}"), 148 | Text("风力: ${_weatherNowResp?.now.windScale}"), 149 | Text("风速,公里/小时: ${_weatherNowResp?.now.windSpeed}"), 150 | Text("相对湿度: ${_weatherNowResp?.now.humidity}"), 151 | Text("降水量: ${_weatherNowResp?.now.precip}"), 152 | Text("大气压强: ${_weatherNowResp?.now.pressure}"), 153 | Text("能见度,默认单位:公里: ${_weatherNowResp?.now.vis}"), 154 | Text("云量: ${_weatherNowResp?.now.cloud}"), 155 | Text("实况云量: ${_weatherNowResp?.now.dew}"), 156 | ], 157 | ), 158 | ); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.10.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.2.1" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.17.0" 44 | cupertino_icons: 45 | dependency: "direct main" 46 | description: 47 | name: cupertino_icons 48 | sha256: caac504f942f41dfadcf45229ce8c47065b93919a12739f20d6173a883c5ec73 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.0.2" 52 | fake_async: 53 | dependency: transitive 54 | description: 55 | name: fake_async 56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "1.3.1" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_qweather: 66 | dependency: "direct main" 67 | description: 68 | path: ".." 69 | relative: true 70 | source: path 71 | version: "0.0.11" 72 | flutter_test: 73 | dependency: "direct dev" 74 | description: flutter 75 | source: sdk 76 | version: "0.0.0" 77 | js: 78 | dependency: transitive 79 | description: 80 | name: js 81 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" 82 | url: "https://pub.flutter-io.cn" 83 | source: hosted 84 | version: "0.6.5" 85 | matcher: 86 | dependency: transitive 87 | description: 88 | name: matcher 89 | sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" 90 | url: "https://pub.flutter-io.cn" 91 | source: hosted 92 | version: "0.12.13" 93 | material_color_utilities: 94 | dependency: transitive 95 | description: 96 | name: material_color_utilities 97 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 98 | url: "https://pub.flutter-io.cn" 99 | source: hosted 100 | version: "0.2.0" 101 | meta: 102 | dependency: transitive 103 | description: 104 | name: meta 105 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" 106 | url: "https://pub.flutter-io.cn" 107 | source: hosted 108 | version: "1.8.0" 109 | path: 110 | dependency: transitive 111 | description: 112 | name: path 113 | sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b 114 | url: "https://pub.flutter-io.cn" 115 | source: hosted 116 | version: "1.8.2" 117 | sky_engine: 118 | dependency: transitive 119 | description: flutter 120 | source: sdk 121 | version: "0.0.99" 122 | source_span: 123 | dependency: transitive 124 | description: 125 | name: source_span 126 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 127 | url: "https://pub.flutter-io.cn" 128 | source: hosted 129 | version: "1.9.1" 130 | stack_trace: 131 | dependency: transitive 132 | description: 133 | name: stack_trace 134 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 135 | url: "https://pub.flutter-io.cn" 136 | source: hosted 137 | version: "1.11.0" 138 | stream_channel: 139 | dependency: transitive 140 | description: 141 | name: stream_channel 142 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 143 | url: "https://pub.flutter-io.cn" 144 | source: hosted 145 | version: "2.1.1" 146 | string_scanner: 147 | dependency: transitive 148 | description: 149 | name: string_scanner 150 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 151 | url: "https://pub.flutter-io.cn" 152 | source: hosted 153 | version: "1.2.0" 154 | term_glyph: 155 | dependency: transitive 156 | description: 157 | name: term_glyph 158 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 159 | url: "https://pub.flutter-io.cn" 160 | source: hosted 161 | version: "1.2.1" 162 | test_api: 163 | dependency: transitive 164 | description: 165 | name: test_api 166 | sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 167 | url: "https://pub.flutter-io.cn" 168 | source: hosted 169 | version: "0.4.16" 170 | vector_math: 171 | dependency: transitive 172 | description: 173 | name: vector_math 174 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 175 | url: "https://pub.flutter-io.cn" 176 | source: hosted 177 | version: "2.1.4" 178 | sdks: 179 | dart: ">=2.18.0 <4.0.0" 180 | flutter: ">=1.20.0" 181 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_qweather_example 2 | description: Demonstrates how to use the flutter_qweather plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | environment: 9 | sdk: ">=2.12.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | flutter_qweather: 16 | # When depending on this package from a real application you should use: 17 | # flutter_qweather: ^x.y.z 18 | # See https://dart.dev/tools/pub/dependencies#version-constraints 19 | # The example app is bundled with the plugin so we use a path dependency on 20 | # the parent directory to use the current plugin's version. 21 | path: ../ 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^1.0.2 26 | 27 | dev_dependencies: 28 | flutter_test: 29 | sdk: flutter 30 | 31 | # For information on the generic Dart part of this file, see the 32 | # following page: https://dart.dev/tools/pub/pubspec 33 | 34 | # The following section is specific to Flutter. 35 | flutter: 36 | 37 | # The following line ensures that the Material Icons font is 38 | # included with your application, so that you can use the icons in 39 | # the material Icons class. 40 | uses-material-design: true 41 | 42 | # To add assets to your application, add an assets section, like this: 43 | # assets: 44 | # - images/a_dot_burr.jpeg 45 | # - images/a_dot_ham.jpeg 46 | 47 | # An image asset can refer to one or more resolution-specific "variants", see 48 | # https://flutter.dev/assets-and-images/#resolution-aware. 49 | 50 | # For details regarding adding assets from package dependencies, see 51 | # https://flutter.dev/assets-and-images/#from-packages 52 | 53 | # To add custom fonts to your application, add a fonts section here, 54 | # in this "flutter" section. Each entry in this list should have a 55 | # "family" key with the font family name, and a "fonts" key with a 56 | # list giving the asset and other descriptors for the font. For 57 | # example: 58 | # fonts: 59 | # - family: Schyler 60 | # fonts: 61 | # - asset: fonts/Schyler-Regular.ttf 62 | # - asset: fonts/Schyler-Italic.ttf 63 | # style: italic 64 | # - family: Trajan Pro 65 | # fonts: 66 | # - asset: fonts/TrajanPro.ttf 67 | # - asset: fonts/TrajanPro_Bold.ttf 68 | # weight: 700 69 | # 70 | # For details regarding fonts from package dependencies, 71 | # see https://flutter.dev/custom-fonts/#from-packages 72 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | //// This is a basic Flutter widget test. 2 | //// 3 | //// To perform an interaction with a widget in your test, use the WidgetTester 4 | //// utility that Flutter provides. For example, you can send tap and scroll 5 | //// gestures. You can also use WidgetTester to find child widgets in the widget 6 | //// tree, read text, and verify that the values of widget properties are correct. 7 | // 8 | //import 'package:flutter/material.dart'; 9 | //import 'package:flutter_test/flutter_test.dart'; 10 | // 11 | //import 'package:flutter_qweather_example/main.dart'; 12 | // 13 | //void main() { 14 | // testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // // Build our app and trigger a frame. 16 | // await tester.pumpWidget(MyApp()); 17 | // 18 | // // Verify that platform version is retrieved. 19 | // expect( 20 | // find.byWidgetPredicate( 21 | // (Widget widget) => widget is Text && 22 | // widget.data.startsWith('Running on:'), 23 | // ), 24 | // findsOneWidget, 25 | // ); 26 | // }); 27 | //} 28 | -------------------------------------------------------------------------------- /flutter_qweather.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttercandies/flutter_qweather/8d4be4aedcc5d21f7a2dc899f475b534c23e24e9/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/Api/ApiAir.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiAir.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/18. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiAir : NSObject 14 | /// 获取实时空气质量 15 | + (void) getAirNow:(id)param result:(FlutterResult)result; 16 | /// 空气质量逐天预报 17 | + (void) getAir5Day:(id)param result:(FlutterResult)result; 18 | @end 19 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiAir.m: -------------------------------------------------------------------------------- 1 | // 2 | // ApiAir.m 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/18. 6 | // 7 | 8 | #import "ApiAir.h" 9 | #import "../DebugPrint/DebugPrint.h" 10 | @implementation ApiAir 11 | 12 | /// 获取实时空气质量 13 | + (void) getAirNow:(id _Nullable)param result:(FlutterResult)result{ 14 | QWeatherConfigInstance.location = param; 15 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_WEATHER_AIR_NOW WithSuccess:^(AirBaseClass *rep) { 16 | [DebugPrint print:[@"getAirNow WithSuccess: " stringByAppendingString:rep.description]]; 17 | if (![rep.code isEqualToString:@"200"]){ 18 | result(NULL); 19 | return; 20 | } 21 | NSDictionary *now = @{@"pubTime": rep.now.pubTime, @"aqi": rep.now.aqi, @"level": rep.now.level, @"category": rep.now.category, 22 | @"primary": rep.now.primary, @"pm10": rep.now.pm10, @"pm2p5": rep.now.pm2p5, @"no2": rep.now.no2, 23 | @"so2": rep.now.so2, @"co": rep.now.co, @"o3": rep.now.o3}; 24 | NSMutableArray *stations = [NSMutableArray new]; 25 | for (AirStation *one in rep.airStation) { 26 | NSDictionary *oneStation = @{ 27 | @"name": one.name, @"id": one.cid, @"pubTime":one.pubTime, @"aqi":one.aqi, @"level": one.level, 28 | @"category": one.category, @"primary": one.primary, @"pm10": one.pm10, @"pm2p5": one.pm2p5, 29 | @"no2": one.no2, @"so2": one.so2, @"co": one.co, @"o3": one.o3}; 30 | [stations addObject:oneStation]; 31 | } 32 | 33 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 34 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime": rep.updateTime}; 35 | NSMutableDictionary *dic = [NSMutableDictionary new]; 36 | [dic setValue:rep.code forKey:@"code"]; 37 | [dic setValue:refer forKey:@"refer"]; 38 | [dic setValue:basic forKey:@"basic"]; 39 | [dic setValue:now forKey:@"now"]; 40 | [dic setValue:stations forKey:@"airNowStationBean"]; 41 | result(dic); 42 | } faileureForError:^(NSError *error) { 43 | [DebugPrint print:[@"getAirNow faileureForError: " stringByAppendingString:error.localizedDescription]]; 44 | result(NULL); 45 | }]; 46 | } 47 | 48 | /// 空气质量5天预报 49 | + (void) getAir5Day:(id _Nullable)param result:(FlutterResult)result{ 50 | QWeatherConfigInstance.location = param; 51 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_WEATHER_AIR_5D WithSuccess:^(AirBaseClass *rep) { 52 | [DebugPrint print:[@"getAir5Day WithSuccess: " stringByAppendingString:rep.description]]; 53 | if (![rep.code isEqualToString:@"200"]){ 54 | result(NULL); 55 | return; 56 | } 57 | NSMutableArray *daily = [NSMutableArray new]; 58 | for (AirDaily *one in rep.airStation) { 59 | NSDictionary *oneDaily = @{ 60 | @"fxDate": one.fxDate, @"aqi": one.aqi, @"level":one.level,@"category":one.category, @"primary": one.primary}; 61 | [daily addObject:oneDaily]; 62 | } 63 | 64 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 65 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime": rep.updateTime}; 66 | NSMutableDictionary *dic = [NSMutableDictionary new]; 67 | [dic setValue:rep.code forKey:@"code"]; 68 | [dic setValue:refer forKey:@"refer"]; 69 | [dic setValue:basic forKey:@"basic"]; 70 | [dic setValue:daily forKey:@"airDailyBeans"]; 71 | result(dic); 72 | } faileureForError:^(NSError *error) { 73 | [DebugPrint print:[@"getAir5Day faileureForError: " stringByAppendingString:error.localizedDescription]]; 74 | result(NULL); 75 | }]; 76 | } 77 | @end 78 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiAstronomy.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiAstronomy.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/19. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiAstronomy : NSObject 14 | /// 获取日出日落 15 | + (void) getSun:(id)param result:(FlutterResult)result; 16 | /// 获取月升月落月相 17 | + (void) getMoon:(id)param result:(FlutterResult)result; 18 | /// 获取太阳高度角 19 | + (void) getSolarElevationAngle:(id)param result:(FlutterResult)result; 20 | @end 21 | 22 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiAstronomy.m: -------------------------------------------------------------------------------- 1 | // 2 | // ApiAstronomy.m 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/19. 6 | // 7 | 8 | #import "ApiAstronomy.h" 9 | #import "../DebugPrint/DebugPrint.h" 10 | 11 | @implementation ApiAstronomy 12 | 13 | /// 获取日出日落 14 | + (void) getSun:(id)param result:(FlutterResult)result{ 15 | NSDictionary *paramDic = param; 16 | QWeatherConfigInstance.location = paramDic[@"location"]; 17 | QWeatherConfigInstance.date = paramDic[@"date"]; 18 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_ASTRONOMY_SUN WithSuccess:^(SunBaseModel *rep) { 19 | [DebugPrint print:[@"getSun WithSuccess: " stringByAppendingString:rep.description]]; 20 | if (![rep.code isEqualToString:@"200"]){ 21 | result(NULL); 22 | return; 23 | } 24 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 25 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime": rep.updateTime}; 26 | NSMutableDictionary *dic = [NSMutableDictionary new]; 27 | [dic setValue:rep.code forKey:@"code"]; 28 | [dic setValue:refer forKey:@"refer"]; 29 | [dic setValue:basic forKey:@"basic"]; 30 | [dic setValue:rep.sunrise forKey:@"sunrise"]; 31 | [dic setValue:rep.sunset forKey:@"sunset"]; 32 | result(dic); 33 | } faileureForError:^(NSError *error) { 34 | [DebugPrint print:[@"getSun faileureForError: " stringByAppendingString:error.localizedDescription]]; 35 | result(NULL); 36 | }]; 37 | } 38 | 39 | /// 获取月升月落月相 40 | + (void) getMoon:(id)param result:(FlutterResult)result{ 41 | NSDictionary *paramDic = param; 42 | QWeatherConfigInstance.location = paramDic[@"location"]; 43 | QWeatherConfigInstance.date = paramDic[@"date"]; 44 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_ASTRONOMY_MOON WithSuccess:^(MoonBaseModel *rep) { 45 | [DebugPrint print:[@"getMoon WithSuccess: " stringByAppendingString:rep.description]]; 46 | if (![rep.code isEqualToString:@"200"]){ 47 | result(NULL); 48 | return; 49 | } 50 | NSMutableArray *moonPhaseList = [NSMutableArray new]; 51 | for (MoonPhase *one in rep.moonPhases) { 52 | NSDictionary *oneMoonPhase = @{@"fxTime": one.fxTime, @"value": one.value, @"name":one.name, 53 | @"icon":one.icon, @"illumination": one.illumination}; 54 | [moonPhaseList addObject:oneMoonPhase]; 55 | } 56 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 57 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime": rep.updateTime}; 58 | NSMutableDictionary *dic = [NSMutableDictionary new]; 59 | [dic setValue:rep.code forKey:@"code"]; 60 | [dic setValue:refer forKey:@"refer"]; 61 | [dic setValue:basic forKey:@"basic"]; 62 | [dic setValue:rep.moonrise forKey:@"moonrise"]; 63 | [dic setValue:rep.moonset forKey:@"moonset"]; 64 | [dic setValue:moonPhaseList forKey:@"moonPhaseBeanList"]; 65 | result(dic); 66 | } faileureForError:^(NSError *error) { 67 | [DebugPrint print:[@"getMoon faileureForError: " stringByAppendingString:error.localizedDescription]]; 68 | result(NULL); 69 | }]; 70 | } 71 | 72 | /// 获取太阳高度角 73 | + (void) getSolarElevationAngle:(id)param result:(FlutterResult)result{ 74 | NSDictionary *paramDic = param; 75 | QWeatherConfigInstance.location = paramDic[@"location"]; 76 | QWeatherConfigInstance.date = paramDic[@"date"]; 77 | QWeatherConfigInstance.time = paramDic[@"time"]; 78 | QWeatherConfigInstance.tz = paramDic[@"tz"]; 79 | QWeatherConfigInstance.alt = paramDic[@"alt"]; 80 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_ASTRONOMY_SUN_ANGLE WithSuccess:^(SunAngleBaseModel *rep) { 81 | [DebugPrint print:[@"getSolarElevationAngle WithSuccess: " stringByAppendingString:rep.description]]; 82 | if (![rep.code isEqualToString:@"200"]){ 83 | result(NULL); 84 | return; 85 | } 86 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 87 | NSMutableDictionary *dic = [NSMutableDictionary new]; 88 | [dic setValue:rep.code forKey:@"code"]; 89 | [dic setValue:refer forKey:@"refer"]; 90 | [dic setValue:rep.solarElevationAngle forKey:@"solarElevationAngle"]; 91 | [dic setValue:rep.solarAzimuthAngle forKey:@"solarAzimuthAngle"]; 92 | [dic setValue:rep.solarHour forKey:@"solarHour"]; 93 | [dic setValue:rep.hourAngle forKey:@"hourAngle"]; 94 | } faileureForError:^(NSError *error) { 95 | [DebugPrint print:[@"getSolarElevationAngle faileureForError: " stringByAppendingString:error.localizedDescription]]; 96 | result(NULL); 97 | }]; 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiGeo.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiGeo.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2021/5/31. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiGeo : NSObject 14 | /// 城市信息查询 15 | + (void) geoCityLookup:(id)param result:(FlutterResult)result; 16 | /// 热门城市查询 17 | + (void) getGeoTopCity:(id)param result:(FlutterResult)result; 18 | /// POI信息搜索 19 | + (void) geoPoiLookup:(id)param result:(FlutterResult)result; 20 | /// POI范围搜索 21 | + (void) geoPoiRangeLookup:(id)param result:(FlutterResult)result; 22 | @end 23 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiHistorical.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiHistorical.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/19. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiHistorical : NSObject 14 | /// 获取历史天气 15 | + (void) getHistoricalWeather:(id)param result:(FlutterResult)result; 16 | /// 获取历史空气质量 17 | + (void) getHistoricalAir:(id)param result:(FlutterResult)result; 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiHistorical.m: -------------------------------------------------------------------------------- 1 | // 2 | // ApiHistorical.m 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/19. 6 | // 7 | 8 | #import "ApiHistorical.h" 9 | #import "../DebugPrint/DebugPrint.h" 10 | 11 | @implementation ApiHistorical 12 | /// 获取历史天气 13 | + (void) getHistoricalWeather:(id)param result:(FlutterResult)result{ 14 | NSDictionary *paramDic = param; 15 | QWeatherConfigInstance.location = paramDic[@"location"]; 16 | QWeatherConfigInstance.date = paramDic[@"date"]; 17 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_HISTORICAL_WEATHER WithSuccess:^(WeatherHistoricalBaseClass *rep) { 18 | [DebugPrint print:[@"getHistoricalWeather WithSuccess: " stringByAppendingString:rep.description]]; 19 | if (![rep.code isEqualToString:@"200"]){ 20 | result(NULL); 21 | return; 22 | } 23 | NSDictionary *weatherDaily = @{@"date": rep.weatherDaily.date, @"sunrise": rep.weatherDaily.sunrise, @"sunset": rep.weatherDaily.sunset, 24 | @"moonrise": rep.weatherDaily.moonrise, @"moonset": rep.weatherDaily.moonset, @"moonPhase": rep.weatherDaily.moonPhase, 25 | @"tempMax": rep.weatherDaily.tempMax, @"tempMin": rep.weatherDaily.tempMin, 26 | @"precip": rep.weatherDaily.precip, @"pressure": rep.weatherDaily.pressure}; 27 | NSMutableArray *weatherHourlyList = [NSMutableArray new]; 28 | for (HistoricalWeatherHourly *one in rep.weatherHourly) { 29 | NSDictionary *oneWeatherHourly = @{ 30 | @"time": one.time, @"temp": one.temp, @"icon":one.icon,@"text":one.text, @"wind360": one.wind360, 31 | @"windDir": one.windDir, @"windScale": one.windScale, @"windSpeed": one.windSpeed, @"humidity": one.humidity, 32 | @"precip": one.precip, @"pressure": one.pressure}; 33 | [weatherHourlyList addObject:oneWeatherHourly]; 34 | } 35 | 36 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 37 | NSDictionary *basic = @{@"fxLink": rep.fxLink}; 38 | NSMutableDictionary *dic = [NSMutableDictionary new]; 39 | [dic setValue:rep.code forKey:@"code"]; 40 | [dic setValue:refer forKey:@"refer"]; 41 | [dic setValue:basic forKey:@"basic"]; 42 | [dic setValue:weatherDaily forKey:@"dailyBean"]; 43 | [dic setValue:weatherHourlyList forKey:@"hourlyBeans"]; 44 | result(dic); 45 | } faileureForError:^(NSError *error) { 46 | [DebugPrint print:[@"getHistoricalWeather faileureForError: " stringByAppendingString:error.localizedDescription]]; 47 | result(NULL); 48 | }]; 49 | } 50 | 51 | /// 获取历史空气质量 52 | + (void) getHistoricalAir:(id)param result:(FlutterResult)result{ 53 | NSDictionary *paramDic = param; 54 | QWeatherConfigInstance.location = paramDic[@"location"]; 55 | QWeatherConfigInstance.date = paramDic[@"date"]; 56 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_HISTORICAL_AIR WithSuccess:^(WeatherHistoricalBaseClass *rep) { 57 | [DebugPrint print:[@"getHistoricalAir WithSuccess: " stringByAppendingString:rep.description]]; 58 | if (![rep.code isEqualToString:@"200"]){ 59 | result(NULL); 60 | return; 61 | } 62 | 63 | NSMutableArray *airHourlyList = [NSMutableArray new]; 64 | for (HistoricalAirHourly *one in rep.airHourly) { 65 | NSDictionary *oneAirHourly = @{ 66 | @"pubTime":one.pubTime, @"aqi":one.aqi, @"level": one.level, @"category": one.category, @"primary": one.primary, 67 | @"pm10": one.pm10, @"pm2p5": one.pm2p5, @"no2": one.no2, @"so2": one.so2, @"co": one.co, @"o3": one.o3}; 68 | [airHourlyList addObject:oneAirHourly]; 69 | } 70 | 71 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 72 | NSDictionary *basic = @{@"fxLink": rep.fxLink}; 73 | NSMutableDictionary *dic = [NSMutableDictionary new]; 74 | [dic setValue:rep.code forKey:@"code"]; 75 | [dic setValue:refer forKey:@"refer"]; 76 | [dic setValue:basic forKey:@"basic"]; 77 | [dic setValue:airHourlyList forKey:@"airHourlyBeans"]; 78 | result(dic); 79 | } faileureForError:^(NSError *error) { 80 | [DebugPrint print:[@"getHistoricalAir faileureForError: " stringByAppendingString:error.localizedDescription]]; 81 | result(NULL); 82 | }]; 83 | } 84 | @end 85 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiIndices.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiIndices.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2021/6/5. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiIndices : NSObject 14 | /// 获取1天生活指数 15 | + (void) getIndices1Day:(id)param result:(FlutterResult)result; 16 | /// 获取3天生活指数 17 | + (void) getIndices3Day:(id)param result:(FlutterResult)result; 18 | /// 获取生活指数 19 | //+ (void) getIndices:(NSString*)name param:(id)param result:(FlutterResult)result; 20 | @end 21 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiIndices.m: -------------------------------------------------------------------------------- 1 | // 2 | // ApiIndices.m 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2021/6/5. 6 | // 7 | 8 | #import "ApiIndices.h" 9 | #import "../DebugPrint/DebugPrint.h" 10 | @implementation ApiIndices 11 | /// 获取1天生活指数 12 | + (void) getIndices1Day:(id)param result:(FlutterResult)result{ 13 | [ApiIndices getIndices:@"getIndices1Day" param:param result:result]; 14 | } 15 | /// 获取3天生活指数 16 | + (void) getIndices3Day:(id)param result:(FlutterResult)result{ 17 | [ApiIndices getIndices:@"getIndices3Day" param:param result:result]; 18 | } 19 | 20 | /// 获取生活指数 21 | + (void) getIndices:(NSString*)name param:(id)param result:(FlutterResult)result{ 22 | NSDictionary *paramDic = param; 23 | QWeatherConfigInstance.location = paramDic[@"location"]; 24 | NSArray *indicesTypes = paramDic[@"indicesTypes"]; 25 | NSMutableArray *indicesTypesTmp = [NSMutableArray new]; 26 | for (int i = 0; i < indicesTypes.count; i++){ 27 | NSString *str = [indicesTypes objectAtIndex:i]; 28 | if ([str isEqualToString:@"SPT"]){ 29 | [indicesTypesTmp addObject: @(INDICES_TYPE_spt)]; 30 | } else if ([str isEqualToString:@"CW"]){ 31 | [indicesTypesTmp addObject: @(INDICES_TYPE_cw)]; 32 | } else if ([str isEqualToString:@"DRSG"]){ 33 | [indicesTypesTmp addObject: @(INDICES_TYPE_drsg)]; 34 | } else if ([str isEqualToString:@"FIS"]){ 35 | [indicesTypesTmp addObject: @(INDICES_TYPE_fis)]; 36 | } else if ([str isEqualToString:@"UV"]){ 37 | [indicesTypesTmp addObject: @(INDICES_TYPE_uv)]; 38 | } else if ([str isEqualToString:@"TRAV"]){ 39 | [indicesTypesTmp addObject: @(INDICES_TYPE_trav)]; 40 | } else if ([str isEqualToString:@"AG"]){ 41 | [indicesTypesTmp addObject: @(INDICES_TYPE_ag)]; 42 | } else if ([str isEqualToString:@"COMF"]){ 43 | [indicesTypesTmp addObject: @(INDICES_TYPE_comf)]; 44 | } else if ([str isEqualToString:@"FLU"]){ 45 | [indicesTypesTmp addObject: @(INDICES_TYPE_flu)]; 46 | } else if ([str isEqualToString:@"AP"]){ 47 | [indicesTypesTmp addObject: @(INDICES_TYPE_ap)]; 48 | } else if ([str isEqualToString:@"AC"]){ 49 | [indicesTypesTmp addObject: @(INDICES_TYPE_ac)]; 50 | } else if ([str isEqualToString:@"GL"]){ 51 | [indicesTypesTmp addObject: @(INDICES_TYPE_gl)]; 52 | } else if ([str isEqualToString:@"MU"]){ 53 | [indicesTypesTmp addObject: @(INDICES_TYPE_mu)]; 54 | } else if ([str isEqualToString:@"DC"]){ 55 | [indicesTypesTmp addObject: @(INDICES_TYPE_dc)]; 56 | } else if ([str isEqualToString:@"PTEC"]){ 57 | [indicesTypesTmp addObject: @(INDICES_TYPE_ptfc)]; 58 | } else if ([str isEqualToString:@"SPI"]){ 59 | [indicesTypesTmp addObject: @(INDICES_TYPE_spi)]; 60 | } else if ([str isEqualToString:@"SKI"]){ 61 | [indicesTypesTmp addObject: @(INDICES_TYPE_ski)]; 62 | } else { 63 | indicesTypesTmp = [NSMutableArray arrayWithObject:@(INDICES_TYPE_all)]; 64 | break; 65 | } 66 | } 67 | QWeatherConfigInstance.indices = indicesTypesTmp; 68 | INQUIRE_TYPE inquireType = INQUIRE_TYPE_INDICES_1D; 69 | if ([name isEqualToString:@"getIndices3Day"]){ 70 | inquireType = INQUIRE_TYPE_INDICES_3D; 71 | } 72 | [QWeatherConfigInstance weatherWithInquireType:inquireType WithSuccess:^(IndicesBaseClass *rep) { 73 | [DebugPrint print:[name stringByAppendingString:[@" WithSuccess: " stringByAppendingString:rep.description]]]; 74 | if (![rep.code isEqualToString:@"200"]){ 75 | result(NULL); 76 | return; 77 | } 78 | NSMutableArray *dailyList = [NSMutableArray new]; 79 | for (IndicesDaily *one in rep.daily) { 80 | NSDictionary *oneIndicesDaily = @{@"date": one.date, @"type": one.type, @"name":one.name, 81 | @"level":one.level, @"category": one.category, @"text": one.text}; 82 | [dailyList addObject:oneIndicesDaily]; 83 | } 84 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 85 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime": rep.updateTime}; 86 | NSMutableDictionary *dic = [NSMutableDictionary new]; 87 | [dic setValue:rep.code forKey:@"code"]; 88 | [dic setValue:refer forKey:@"refer"]; 89 | [dic setValue:basic forKey:@"basic"]; 90 | [dic setValue:dailyList forKey:@"dailyList"]; 91 | result(dic); 92 | } faileureForError:^(NSError *error) { 93 | [DebugPrint print:[name stringByAppendingString:[@" faileureForError: " stringByAppendingString:error.localizedDescription]]]; 94 | result(NULL); 95 | }]; 96 | } 97 | @end 98 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiOcean.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiOcean.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/19. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiOcean : NSObject 14 | /// 获取潮汐 15 | + (void) getOceanTide:(id)param result:(FlutterResult)result; 16 | /// 获取潮流 17 | + (void) getOceanCurrents:(id)param result:(FlutterResult)result; 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiOcean.m: -------------------------------------------------------------------------------- 1 | // 2 | // ApiOcean.m 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/19. 6 | // 7 | 8 | #import "ApiOcean.h" 9 | #import "../DebugPrint/DebugPrint.h" 10 | @implementation ApiOcean 11 | 12 | /// 获取潮汐 13 | + (void) getOceanTide:(id)param result:(FlutterResult)result{ 14 | NSDictionary *paramDic = param; 15 | QWeatherConfigInstance.location = paramDic[@"location"]; 16 | QWeatherConfigInstance.date = paramDic[@"date"]; 17 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_OCEAN_TIDE WithSuccess:^(OceanTideBaseClass *rep) { 18 | [DebugPrint print:[@"getOceanTide WithSuccess: " stringByAppendingString:rep.description]]; 19 | if (![rep.code isEqualToString:@"200"]){ 20 | result(NULL); 21 | return; 22 | } 23 | 24 | NSMutableArray *tideList = [NSMutableArray new]; 25 | for (TideTable *one in rep.tideTable) { 26 | NSDictionary *oneTide = @{@"fxTime":one.fxTime, @"height":one.height, @"type": one.type}; 27 | [tideList addObject:oneTide]; 28 | } 29 | NSMutableArray *tideHourlyList = [NSMutableArray new]; 30 | for (TideHourly *one in rep.tideHourly) { 31 | NSDictionary *oneTideHourly = @{@"fxTime":one.fxTime, @"height":one.height}; 32 | [tideHourlyList addObject:oneTideHourly]; 33 | } 34 | 35 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 36 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime":rep.updateTime}; 37 | NSMutableDictionary *dic = [NSMutableDictionary new]; 38 | [dic setValue:rep.code forKey:@"code"]; 39 | [dic setValue:refer forKey:@"refer"]; 40 | [dic setValue:basic forKey:@"basic"]; 41 | [dic setValue:tideList forKey:@"tideTable"]; 42 | [dic setValue:tideHourlyList forKey:@"tideHourlyList"]; 43 | result(dic); 44 | } faileureForError:^(NSError *error) { 45 | [DebugPrint print:[@"getOceanTide faileureForError: " stringByAppendingString:error.localizedDescription]]; 46 | result(NULL); 47 | }]; 48 | } 49 | 50 | /// 获取潮流 51 | + (void) getOceanCurrents:(id)param result:(FlutterResult)result{ 52 | NSDictionary *paramDic = param; 53 | QWeatherConfigInstance.location = paramDic[@"location"]; 54 | QWeatherConfigInstance.date = paramDic[@"date"]; 55 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_OCEAN_CURRENTS WithSuccess:^(OceanCurrentsBaseClass *rep) { 56 | [DebugPrint print:[@"getOceanCurrents WithSuccess: " stringByAppendingString:rep.description]]; 57 | if (![rep.code isEqualToString:@"200"]){ 58 | result(NULL); 59 | return; 60 | } 61 | 62 | NSMutableArray *currentsList = [NSMutableArray new]; 63 | for (CurrentsTable *one in rep.currentsTable) { 64 | NSDictionary *oneCurrents = @{@"fxTime":one.fxTime, @"speedMax":one.speedMax, @"dir360": one.dir360}; 65 | [currentsList addObject:oneCurrents]; 66 | } 67 | NSMutableArray *currentsHourlyList = [NSMutableArray new]; 68 | for (CurrentsHourly *one in rep.currentsHourly) { 69 | NSDictionary *oneCurrentsHourly = @{@"fxTime":one.fxTime, @"speed":one.speed, @"dir360": one.dir360}; 70 | [currentsHourlyList addObject:oneCurrentsHourly]; 71 | } 72 | 73 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 74 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime":rep.updateTime}; 75 | NSMutableDictionary *dic = [NSMutableDictionary new]; 76 | [dic setValue:rep.code forKey:@"code"]; 77 | [dic setValue:refer forKey:@"refer"]; 78 | [dic setValue:basic forKey:@"basic"]; 79 | [dic setValue:currentsList forKey:@"tableList"]; 80 | [dic setValue:currentsHourlyList forKey:@"hourlyList"]; 81 | result(dic); 82 | } faileureForError:^(NSError *error) { 83 | [DebugPrint print:[@"getOceanCurrents faileureForError: " stringByAppendingString:error.localizedDescription]]; 84 | result(NULL); 85 | }]; 86 | } 87 | @end 88 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiTropical.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiTropical.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/20. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiTropical : NSObject 14 | /// 台风列表 15 | + (void) getStormList:(id)param result:(FlutterResult)result; 16 | /// 台风实况和路径 17 | + (void) getStormTrack:(id)param result:(FlutterResult)result; 18 | /// 台风预报 19 | + (void) getStormForecast:(id)param result:(FlutterResult)result; 20 | @end 21 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiWarning.h: -------------------------------------------------------------------------------- 1 | // 2 | // WarningApi.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/18. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiWarning : NSObject 14 | /// 获取灾害预警 15 | + (void) getWarning:(id)param result:(FlutterResult)result; 16 | /// 获取灾害预警列表 17 | + (void) getWarningList:(id)param result:(FlutterResult)result; 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiWarning.m: -------------------------------------------------------------------------------- 1 | // 2 | // WarningApi.m 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2022/4/18. 6 | // 7 | 8 | #import "ApiWarning.h" 9 | #import "../DebugPrint/DebugPrint.h" 10 | @implementation ApiWarning 11 | 12 | + (void) getWarning:(id)param result:(FlutterResult)result{ 13 | QWeatherConfigInstance.location = param; 14 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_WARNING WithSuccess:^(WarningBaseClass *rep) { 15 | [DebugPrint print:[@"getWarning WithSuccess: " stringByAppendingString:rep.description]]; 16 | if (![rep.code isEqualToString:@"200"]){ 17 | result(NULL); 18 | return; 19 | } 20 | NSMutableArray *warningList = [NSMutableArray new]; 21 | for (Warning *one in rep.warning) { 22 | NSDictionary *oneWarning = @{ 23 | @"id": one.warningId, @"sender": one.sender, @"pubTime":one.pubTime, @"title":one.title, 24 | @"startTime": one.startTime, @"endTime": one.endTime, @"status": one.status, @"level": one.level, 25 | @"type": one.type, @"typeName": one.typeName, @"text": one.text, @"related": one.related}; 26 | [warningList addObject:oneWarning]; 27 | } 28 | 29 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 30 | NSDictionary *basic = @{@"fxLink": rep.fxLink, @"updateTime": rep.updateTime}; 31 | NSMutableDictionary *dic = [NSMutableDictionary new]; 32 | [dic setValue:rep.code forKey:@"code"]; 33 | [dic setValue:refer forKey:@"refer"]; 34 | [dic setValue:basic forKey:@"basic"]; 35 | [dic setValue:warningList forKey:@"warningList"]; 36 | result(dic); 37 | } faileureForError:^(NSError *error) { 38 | [DebugPrint print:[@"getWarning faileureForError: " stringByAppendingString:error.localizedDescription]]; 39 | result(NULL); 40 | }]; 41 | } 42 | 43 | /// 获取灾害预警列表 44 | + (void) getWarningList:(id)param result:(FlutterResult)result{ 45 | QWeatherConfigInstance.range = param; 46 | [QWeatherConfigInstance weatherWithInquireType:INQUIRE_TYPE_WARNINGLIST WithSuccess:^(WarningListClass *rep) { 47 | [DebugPrint print:[@"getWarningList WithSuccess: " stringByAppendingString:rep.description]]; 48 | if (![rep.code isEqualToString:@"200"]){ 49 | result(NULL); 50 | return; 51 | } 52 | NSMutableArray *warningLocList = [NSMutableArray new]; 53 | for (WarningLoc *one in rep.warningLocList) { 54 | NSDictionary *oneWarningLoc = @{@"locationId": one.locationId}; 55 | [warningLocList addObject:oneWarningLoc]; 56 | } 57 | 58 | NSDictionary *refer = @{@"licenseList": rep.refer.license, @"sourcesList": rep.refer.sources}; 59 | NSDictionary *basic = @{@"updateTime": rep.updateTime}; 60 | NSMutableDictionary *dic = [NSMutableDictionary new]; 61 | [dic setValue:rep.code forKey:@"code"]; 62 | [dic setValue:refer forKey:@"refer"]; 63 | [dic setValue:basic forKey:@"basic"]; 64 | [dic setValue:warningLocList forKey:@"warningBean"]; 65 | result(dic); 66 | } faileureForError:^(NSError *error) { 67 | [DebugPrint print:[@"getWarningList faileureForError: " stringByAppendingString:error.localizedDescription]]; 68 | result(NULL); 69 | }]; 70 | } 71 | @end 72 | -------------------------------------------------------------------------------- /ios/Classes/Api/ApiWeather.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApiWeather.h 3 | // flutter_qweather 4 | // 5 | // Created by CyJay on 2021/4/19. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | 13 | @interface ApiWeather : NSObject 14 | /// 获取当前天气 15 | + (void) getWeatherNow:(id)param result:(FlutterResult)result; 16 | /// 获取逐天预报 17 | + (void) getWeatherDaily:(id)param result:(FlutterResult)result; 18 | /// 获取逐时预报 19 | + (void) getWeatherHourly:(id)param result:(FlutterResult)result; 20 | /// 获取中国地区未来2小时内每5分钟降水 21 | + (void) getWeatherMinuteLy:(id)param result:(FlutterResult)result; 22 | @end 23 | -------------------------------------------------------------------------------- /ios/Classes/DebugPrint/DebugPrint.h: -------------------------------------------------------------------------------- 1 | // 2 | // DebugPrint.h 3 | // qweather 4 | // 5 | // Created by CyJay on 2021/4/19. 6 | // 7 | #import 8 | 9 | @interface DebugPrint : NSObject 10 | + (void)setDebug:(BOOL)debug; 11 | + (void)print:(NSString*)value; 12 | @end 13 | -------------------------------------------------------------------------------- /ios/Classes/DebugPrint/DebugPrint.m: -------------------------------------------------------------------------------- 1 | // 2 | // DebugPrint.m 3 | // qweather 4 | // 5 | // Created by CyJay on 2021/4/19. 6 | // 7 | 8 | 9 | #import "DebugPrint.h" 10 | 11 | @implementation DebugPrint 12 | static BOOL _debug = NO; 13 | + (void)setDebug:(BOOL)debug{ 14 | if (debug)debug = YES; 15 | if (!debug)debug= NO; 16 | if (_debug != debug){ 17 | NSLog(@"设置调试模式:%@", debug?@"YES":@"NO"); 18 | _debug = debug; 19 | } 20 | } 21 | + (void)print:(NSString*)value{ 22 | if (_debug){ 23 | NSLog(@"com.fluttercandies.qweather:%@",value); 24 | } 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /ios/Classes/FlutterQweatherPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | @interface FlutterQweatherPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/FlutterQweatherPlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterQweatherPlugin.h" 2 | #import "MethodConstants.h" 3 | #import "DebugPrint/DebugPrint.h" 4 | #import "Api/ApiAir.h" 5 | #import "Api/ApiAstronomy.h" 6 | #import "Api/ApiGeo.h" 7 | #import "Api/ApiIndices.h" 8 | #import "Api/ApiWeather.h" 9 | #import "Api/ApiWarning.h" 10 | #import "Api/ApiHistorical.h" 11 | #import "Api/ApiOcean.h" 12 | #import "Api/ApiTropical.h" 13 | 14 | @implementation FlutterQweatherPlugin 15 | + (void)registerWithRegistrar:(NSObject*)registrar { 16 | FlutterMethodChannel* channel = [FlutterMethodChannel 17 | methodChannelWithName:@"com.fluttercandies.qweather" binaryMessenger:[registrar messenger]]; 18 | FlutterQweatherPlugin* instance = [[FlutterQweatherPlugin alloc] init]; 19 | [registrar addMethodCallDelegate:instance channel:channel]; 20 | } 21 | 22 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 23 | if ([GetPlatformVersion isEqualToString:call.method]) { 24 | result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); 25 | }else if ([SetDebug isEqualToString:call.method]){ // 设置 Debug 26 | [self setDebug:call.arguments result:result]; 27 | }else if ([Init isEqualToString:call.method]){ /// 初始化 28 | [self init:call.arguments result:result]; 29 | }else if ([GeoCityLookup isEqualToString:call.method]){ /// 城市信息查询 30 | [ApiGeo geoCityLookup:call.arguments result:result]; 31 | }else if ([GetGeoTopCity isEqualToString:call.method]){ /// 热门城市查询 32 | [ApiGeo getGeoTopCity:call.arguments result:result]; 33 | }else if ([GeoPoiLookup isEqualToString:call.method]){ /// POI信息搜索 34 | [ApiGeo geoPoiLookup:call.arguments result:result]; 35 | }else if ([GeoPoiRangeLookup isEqualToString:call.method]){ /// POI范围搜索 36 | [ApiGeo geoPoiRangeLookup:call.arguments result:result]; 37 | }else if ([GetWeatherNow isEqualToString:call.method]){ /// 查询实时天气 38 | [ApiWeather getWeatherNow:call.arguments result:result]; 39 | }else if ([GetWeatherDaily isEqualToString:call.method]){ /// 获取逐天预报 40 | [ApiWeather getWeatherDaily:call.arguments result:result]; 41 | }else if ([GetWeatherHourly isEqualToString:call.method]){ /// 获取逐时预报 42 | [ApiWeather getWeatherHourly:call.arguments result:result]; 43 | }else if ([GetWeatherMinuteLy isEqualToString:call.method]){ /// 获取中国地区未来2小时内每5分钟降水 44 | [ApiWeather getWeatherMinuteLy:call.arguments result:result]; 45 | }else if ([GetIndices1Day isEqualToString:call.method]){ /// 获取1天生活指数 46 | [ApiIndices getIndices1Day:call.arguments result:result]; 47 | }else if ([GetIndices3Day isEqualToString:call.method]){ /// 获取3天生活指数 48 | [ApiIndices getIndices3Day:call.arguments result:result]; 49 | }else if ([GetWarning isEqualToString:call.method]){ /// 获取灾害预警 50 | [ApiWarning getWarning:call.arguments result:result]; 51 | }else if ([GetWarningList isEqualToString:call.method]){ /// 获取灾害预警列表 52 | [ApiWarning getWarningList:call.arguments result:result]; 53 | }else if ([GetAirNow isEqualToString:call.method]){ /// 获取实时空气质量 54 | [ApiAir getAirNow:call.arguments result:result]; 55 | }else if ([GetAir5Day isEqualToString:call.method]){ /// 获取5天空气质量预报 56 | [ApiAir getAir5Day:call.arguments result:result]; 57 | }else if ([GetHistoricalWeather isEqualToString:call.method]){ /// 获取历史天气 58 | [ApiHistorical getHistoricalWeather:call.arguments result:result]; 59 | }else if ([GetHistoricalAir isEqualToString:call.method]){ /// 获取历史空气质量 60 | [ApiHistorical getHistoricalAir:call.arguments result:result]; 61 | }else if ([GetSun isEqualToString:call.method]){ /// 获取日出日落 62 | [ApiAstronomy getSun:call.arguments result:result]; 63 | }else if ([GetMoon isEqualToString:call.method]){ /// 获取月升月落月相 64 | [ApiAstronomy getMoon:call.arguments result:result]; 65 | }else if ([GetSolarElevationAngle isEqualToString:call.method]){ /// 获取太阳高度角 66 | [ApiAstronomy getSolarElevationAngle:call.arguments result:result]; 67 | }else if ([GetOceanTide isEqualToString:call.method]){ /// 获取潮汐 68 | [ApiOcean getOceanTide:call.arguments result:result]; 69 | }else if ([GetOceanCurrents isEqualToString:call.method]){ /// 获取潮流 70 | [ApiOcean getOceanCurrents:call.arguments result:result]; 71 | }else if ([GetStormList isEqualToString:call.method]){ /// 台风列表 72 | [ApiTropical getStormList:call.arguments result:result]; 73 | }else if ([GetStormTrack isEqualToString:call.method]){ /// 台风实况和路径 74 | [ApiTropical getStormTrack:call.arguments result:result]; 75 | }else if ([GetStormForecast isEqualToString:call.method]){ /// 台风预报 76 | [ApiTropical getStormForecast:call.arguments result:result]; 77 | }else{ 78 | result(FlutterMethodNotImplemented); 79 | } 80 | } 81 | 82 | /// 初始化 83 | - (void)init:(NSDictionary*)arguments result:(FlutterResult)result{ 84 | NSNumber *debugNum = arguments[@"debug"]; 85 | [DebugPrint setDebug:[debugNum boolValue]]; 86 | NSNumber *bizNum = arguments[@"biz"]; 87 | BOOL biz = [bizNum boolValue]; 88 | QWeatherConfigInstance.publicID = arguments[@"publicId"]; 89 | QWeatherConfigInstance.appKey = arguments[@"key"]; 90 | if (biz){ 91 | QWeatherConfigInstance.appType = APP_TYPE_BIZ; 92 | }else{ 93 | QWeatherConfigInstance.appType = APP_TYPE_DEV; 94 | } 95 | result([NSNumber numberWithBool:YES]); 96 | } 97 | 98 | /// 设置 Debug 99 | - (void) setDebug:(NSNumber*)debugNum result:(FlutterResult)result{ 100 | [DebugPrint setDebug:[debugNum boolValue]]; 101 | result([NSNumber numberWithBool:YES]); 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /ios/Classes/MethodConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // MethodConstants.h 3 | // qweather 4 | // 5 | // Created by CyJay on 2021/4/18. 6 | // 7 | // 获取平台版本 8 | #define GetPlatformVersion @"GetPlatformVersion" 9 | // 设置 Debug 10 | #define SetDebug @"SetDebug" 11 | // 初始化 12 | #define Init @"Init" 13 | // 城市信息查询 14 | #define GeoCityLookup @"GeoCityLookup" 15 | // 热门城市查询 16 | #define GetGeoTopCity @"GetGeoTopCity" 17 | // POI信息搜索 18 | #define GeoPoiLookup @"GeoPoiLookup" 19 | // POI范围搜索 20 | #define GeoPoiRangeLookup @"GeoPoiRangeLookup" 21 | // 获取实况天气数据 22 | #define GetWeatherNow @"GetWeatherNow" 23 | // 获取逐天预报 24 | #define GetWeatherDaily @"GgetWeatherDaily" 25 | // 获取逐时预报 26 | #define GetWeatherHourly @"GetWeatherHourly" 27 | // 获取中国地区未来2小时内每5分钟降水 28 | #define GetWeatherMinuteLy @"GetWeatherMinuteLy" 29 | // 获取1天生活指数 30 | #define GetIndices1Day @"GetIndices1Day" 31 | // 获取3天生活指数 32 | #define GetIndices3Day @"GetIndices3Day" 33 | // 获取灾害预警 34 | #define GetWarning @"GetWarning" 35 | // 获取灾害预警列表 36 | #define GetWarningList @"GetWarningList" 37 | // 获取实时空气质量 38 | #define GetAirNow @"GetAirNow" 39 | // 获取5天空气质量预报 40 | #define GetAir5Day @"GetAir5Day" 41 | // 获取历史天气 42 | #define GetHistoricalWeather @"GetHistoricalWeather" 43 | // 获取历史空气质量 44 | #define GetHistoricalAir @"GetHistoricalAir" 45 | // 获取日出日落 46 | #define GetSun @"GetSun" 47 | // 获取月升月落月相 48 | #define GetMoon @"GetMoon" 49 | // 获取太阳高度角 50 | #define GetSolarElevationAngle @"GetSolarElevationAngle" 51 | // 获取潮汐 52 | #define GetOceanTide @"GetOceanTide" 53 | // 获取潮流 54 | #define GetOceanCurrents @"GetOceanCurrents" 55 | // 台风列表 56 | #define GetStormList @"GetStormList" 57 | // 台风实况和路径 58 | #define GetStormTrack @"GetStormTrack" 59 | // 台风预报 60 | #define GetStormForecast @"GetStormForecast" 61 | -------------------------------------------------------------------------------- /ios/flutter_qweather.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_qweather.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_qweather' 7 | s.version = '0.0.1' 8 | s.summary = 'A qweather Flutter plugin.' 9 | s.description = <<-DESC 10 | A qweather Flutter plugin. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.xcconfig = { 'OTHER_LDFLAGS' => '-ObjC' } 18 | s.dependency 'AFNetworking','~>4.0.0' 19 | s.dependency 'Flutter' 20 | s.dependency 'QWeather-SDK' 21 | s.platform = :ios, '9.0' 22 | s.static_framework = true 23 | 24 | # Flutter.framework does not contain a i386 slice. 25 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 26 | end 27 | -------------------------------------------------------------------------------- /lib/apis/air_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 实时空气质量和预报 4 | mixin _Air on _ServiceApi { 5 | /// [获取实时空气质量]: https://dev.qweather.com/docs/android-sdk/android-air/#接口参数说明 6 | Future getAirNow(String location) async { 7 | Map? value = await _methodChannel.invokeMapMethod( 8 | MethodConstants.GetAirNow, location); 9 | return value == null ? null : AirNowResp.fromMap(value); 10 | } 11 | 12 | /// [获取5天空气质量预报]: https://dev.qweather.com/docs/android-sdk/android-air/#接口参数说明-1 13 | Future getAir5Day(String location) async { 14 | Map? value = await _methodChannel.invokeMapMethod( 15 | MethodConstants.GetAir5Day, location); 16 | return value == null ? null : AirDailyResp.fromMap(value); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/apis/astronomy_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 太阳和月亮 4 | mixin _Astronomy on _ServiceApi { 5 | /// [获取日出日落]: https://dev.qweather.com/docs/android-sdk/android-astronomy/#接口参数说明 6 | /// date: 查询日期,日期格式为yyyyMMdd,例如 20200531 7 | Future getSun(String location, String date) async { 8 | Map param = {"location": location, "date": date}; 9 | Map? value = 10 | await _methodChannel.invokeMapMethod(MethodConstants.GetSun, param); 11 | return value == null ? null : SunRsp.fromMap(value); 12 | } 13 | 14 | /// [获取月升月落月相]: https://dev.qweather.com/docs/android-sdk/android-astronomy/#接口参数说明-1 15 | /// date: 查询日期,日期格式为yyyyMMdd,例如 20200531 16 | Future getMoon(String location, String date) async { 17 | Map param = {"location": location, "date": date}; 18 | Map? value = 19 | await _methodChannel.invokeMapMethod(MethodConstants.GetMoon, param); 20 | return value == null ? null : MoonRsp.fromMap(value); 21 | } 22 | 23 | /// [获取太阳高度角]: https://dev.qweather.com/docs/android-sdk/android-astronomy/#接口参数说明-2 24 | /// date: 查询日期,日期格式为yyyyMMdd,例如 20200531 25 | /// time: 查询时间,格式为HHmm,24时制,例如 1230 26 | /// tz: 查询地区所在时区,例如0800 或 -0530 27 | /// alt: 海拔高度,单位为米,例如 43 28 | Future getSolarElevationAngle( 29 | {required String location, 30 | required String date, 31 | required String time, 32 | required String tz, 33 | required String alt}) async { 34 | Map param = { 35 | "location": location, 36 | "date": date, 37 | "time": time, 38 | "tz": tz, 39 | "alt": alt 40 | }; 41 | Map? value = await _methodChannel.invokeMapMethod( 42 | MethodConstants.GetSolarElevationAngle, param); 43 | return value == null ? null : SolarElevationAngleRsp.fromMap(value); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/apis/geo_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 地理信息搜索API 4 | mixin _Geo on _ServiceApi { 5 | /// [城市信息查询]: https://dev.qweather.com/docs/android-sdk/android-geo/#城市信息查询 6 | Future geoCityLookup(String location, 7 | {String range = 'world', int number = 10}) async { 8 | Map param = { 9 | "location": location, 10 | "range": range.isEmpty ? 'world' : range, 11 | "number": Platform.isAndroid ? number : number.toString() 12 | }; 13 | Map? value = await _methodChannel.invokeMapMethod( 14 | MethodConstants.GeoCityLookup, param); 15 | return value == null ? null : GeoPoiLocationResp.fromMap(value); 16 | } 17 | 18 | /// [热门城市查询]: https://dev.qweather.com/docs/android-sdk/android-geo/#热门城市查询 19 | Future getGeoTopCity( 20 | {String range = 'world', int number = 10}) async { 21 | Map param = { 22 | "range": range.isEmpty ? 'world' : range, 23 | "number": Platform.isAndroid ? number : number.toString() 24 | }; 25 | Map? value = await _methodChannel.invokeMapMethod( 26 | MethodConstants.GetGeoTopCity, param); 27 | return value == null ? null : GeoPoiLocationResp.fromMap(value); 28 | } 29 | 30 | /// [POI信息搜索]: https://dev.qweather.com/docs/android-sdk/android-geo/#POI信息搜索 31 | Future geoPoiLookup(String location, PoiType type, 32 | {String city = '', int number = 10}) async { 33 | Map param = { 34 | "location": location, 35 | "city": city, 36 | "number": Platform.isAndroid ? number : number.toString(), 37 | "type": type.code 38 | }; 39 | 40 | Map? value = await _methodChannel.invokeMapMethod( 41 | MethodConstants.GeoPoiLookup, param); 42 | return value == null ? null : GeoPoiLocationResp.fromMap(value); 43 | } 44 | 45 | /// [POI范围搜索]: https://dev.qweather.com/docs/android-sdk/android-geo/#POI范围搜索 46 | Future geoPoiRangeLookup(String location, PoiType type, 47 | {int radius = 5, int number = 10}) async { 48 | Map param = { 49 | "location": location, 50 | "radius": Platform.isAndroid ? radius : radius.toString(), 51 | "number": Platform.isAndroid ? number : number.toString(), 52 | "type": type.code 53 | }; 54 | Map? value = await _methodChannel.invokeMapMethod( 55 | MethodConstants.GeoPoiRangeLookup, param); 56 | return value == null ? null : GeoPoiLocationResp.fromMap(value); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/apis/historical_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 历史天气和空气质量 4 | mixin _Historical on _ServiceApi { 5 | /// [获取历史天气]: https://dev.qweather.com/docs/android-sdk/android-historical/#接口参数说明 6 | /// date: 查询日期,日期格式为yyyyMMdd,例如 20200531 7 | Future getHistoricalWeather( 8 | String location, String date) async { 9 | Map param = {"location": location, "date": date}; 10 | Map? value = await _methodChannel.invokeMapMethod( 11 | MethodConstants.GetHistoricalWeather, param); 12 | return value == null ? null : HistoricalWeatherRsp.fromMap(value); 13 | } 14 | 15 | /// [获取历史空气质量]: https://dev.qweather.com/docs/android-sdk/android-historical/#接口参数说明-1 16 | /// date: 查询日期,日期格式为yyyyMMdd,例如 20200531 17 | Future getHistoricalAir( 18 | String location, String date) async { 19 | Map param = {"location": location, "date": date}; 20 | Map? value = await _methodChannel.invokeMapMethod( 21 | MethodConstants.GetHistoricalAir, param); 22 | return value == null ? null : HistoricalHourlyAirRsp.fromMap(value); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/apis/indices_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 天气生活指数API 4 | mixin _Indices on _ServiceApi { 5 | /// [获取1天生活指数]: https://dev.qweather.com/docs/android-sdk/android-indices/#接口参数说明 6 | Future getIndices1Day(String location, 7 | {Set? indicesTypes}) async { 8 | if (indicesTypes == null || 9 | indicesTypes.isEmpty || 10 | (indicesTypes.length > 1 && indicesTypes.contains(IndicesType.ALL))) 11 | indicesTypes = {IndicesType.ALL}; 12 | Map param = { 13 | "location": location, 14 | "indicesTypes": indicesTypes.map((e) => e.code).toList() 15 | }; 16 | Map? value = await _methodChannel.invokeMapMethod( 17 | MethodConstants.GetIndices1Day, param); 18 | return value == null ? null : DailyIndicesResp.fromMap(value); 19 | } 20 | 21 | /// [获取3天生活指数]: https://dev.qweather.com/docs/android-sdk/android-indices/#接口参数说明-1 22 | Future getIndices3Day(String location, 23 | {Set? indicesTypes}) async { 24 | if (indicesTypes == null || 25 | indicesTypes.isEmpty || 26 | (indicesTypes.length > 1 && indicesTypes.contains(IndicesType.ALL))) 27 | indicesTypes = {IndicesType.ALL}; 28 | Map param = { 29 | "location": location, 30 | "indicesTypes": indicesTypes.map((e) => e.code).toList() 31 | }; 32 | Map? value = await _methodChannel.invokeMapMethod( 33 | MethodConstants.GetIndices3Day, param); 34 | return value == null ? null : DailyIndicesResp.fromMap(value); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/apis/ocean_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 潮汐和潮流 4 | mixin _Ocean on _ServiceApi { 5 | /// [获取潮汐]: https://dev.qweather.com/docs/android-sdk/android-ocean/#接口参数说明 6 | /// date: 查询日期,日期格式为yyyyMMdd,例如 20200531 7 | Future getOceanTide(String location, String date) async { 8 | Map param = {"location": location, "date": date}; 9 | Map? value = await _methodChannel.invokeMapMethod( 10 | MethodConstants.GetIndices1Day, param); 11 | return value == null ? null : DailyIndicesResp.fromMap(value); 12 | } 13 | 14 | /// [获取潮流]: https://dev.qweather.com/docs/android-sdk/android-ocean/#接口参数说明-1 15 | /// date: 查询日期,日期格式为yyyyMMdd,例如 20200531 16 | Future getOceanCurrents( 17 | String location, String date) async { 18 | Map param = {"location": location, "date": date}; 19 | Map? value = await _methodChannel.invokeMapMethod( 20 | MethodConstants.GetIndices3Day, param); 21 | return value == null ? null : DailyIndicesResp.fromMap(value); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/apis/tropical_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 热带气旋(台风) 4 | mixin _Tropical on _ServiceApi { 5 | /// [获取灾害预警]: https://dev.qweather.com/docs/android-sdk/android-tropical/#接口参数说明 6 | /// 支持查询本年度和上一年度的台风,year 例如:2020 2019 7 | Future getStormList(String year, Basin basin) async { 8 | Map param = {"year": year, "basin": basin.code}; 9 | Map? value = await _methodChannel.invokeMapMethod( 10 | MethodConstants.GetStormList, param); 11 | return value == null ? null : StormListRsp.fromMap(value); 12 | } 13 | 14 | /// [获取灾害预警列表]: https://dev.qweather.com/docs/android-sdk/android-tropical/#接口参数说明-1 15 | Future getStormTrack(String stormId) async { 16 | Map? value = await _methodChannel.invokeMapMethod( 17 | MethodConstants.GetStormTrack, stormId); 18 | return value == null ? null : StormTracRsp.fromMap(value); 19 | } 20 | 21 | /// [获取灾害预警列表]: https://dev.qweather.com/docs/android-sdk/android-tropical/#接口参数说明-3 22 | Future getStormForecast(String stormId) async { 23 | Map? value = await _methodChannel.invokeMapMethod( 24 | MethodConstants.GetStormForecast, stormId); 25 | return value == null ? null : ForecastRsp.fromMap(value); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/apis/warning_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 天气灾害预警 4 | mixin _Warning on _ServiceApi { 5 | /// [获取灾害预警]: https://dev.qweather.com/docs/android-sdk/android-warning/#接口参数说明 6 | Future getWarning(String location) async { 7 | Map? value = await _methodChannel.invokeMapMethod( 8 | MethodConstants.GetWarning, location); 9 | return value == null ? null : WarningRsp.fromMap(value); 10 | } 11 | 12 | /// [获取灾害预警列表]: https://dev.qweather.com/docs/android-sdk/android-warning/#接口参数说明-1 13 | Future getWarningList({String range = 'cn'}) async { 14 | Map? value = await _methodChannel.invokeMapMethod( 15 | MethodConstants.GetWarningList, range.isEmpty ? 'cn' : range); 16 | return value == null ? null : WarningListRsp.fromMap(value); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/apis/weather_api.dart: -------------------------------------------------------------------------------- 1 | part of qweather; 2 | 3 | /// 城市天气API 4 | mixin _Weather on _ServiceApi { 5 | /// [获取实时天气]: https://dev.qweather.com/docs/android-sdk/android-weather/#接口参数说明 6 | Future getWeatherNow(String location) async { 7 | Map? value = await _methodChannel.invokeMapMethod( 8 | MethodConstants.GetWeatherNow, location); 9 | return value == null ? null : WeatherNowResp.fromMap(value); 10 | } 11 | 12 | /// [获取逐天预报]: https://dev.qweather.com/docs/android-sdk/android-weather/#接口参数说明-1 13 | Future getWeatherDaily( 14 | String location, WeatherDailyForecast dailyForecast) async { 15 | Map param = { 16 | "location": location, 17 | "daily": dailyForecast.day 18 | }; 19 | Map? value = await _methodChannel.invokeMapMethod( 20 | MethodConstants.GetWeatherDaily, param); 21 | return value == null ? null : WeatherDailyResp.fromMap(value); 22 | } 23 | 24 | /// [获取逐时预报]: https://dev.qweather.com/docs/android-sdk/android-weather/#接口参数说明-2 25 | Future getWeatherHourly( 26 | String location, WeatherHourlyForecast hourlyForecast) async { 27 | Map param = { 28 | "location": location, 29 | "hourly": hourlyForecast.hour 30 | }; 31 | 32 | Map? value = await _methodChannel.invokeMapMethod( 33 | MethodConstants.GetWeatherHourly, param); 34 | return value == null ? null : WeatherHourlyResp.fromMap(value); 35 | } 36 | 37 | /// [获取中国地区未来2小时内每5分钟降水数据]: https://dev.qweather.com/docs/android-sdk/android-weather/#接口参数说明-3 38 | Future getWeatherMinuteLy(String location) async { 39 | Map? value = await _methodChannel.invokeMapMethod( 40 | MethodConstants.GetWeatherMinuteLy, location); 41 | return value == null ? null : WeatherMinutelyResp.fromMap(value); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/constants.dart: -------------------------------------------------------------------------------- 1 | /// 方法常量 2 | class MethodConstants { 3 | /// 获取平台版本 4 | static const String GetPlatformVersion = 'GetPlatformVersion'; 5 | 6 | /// 初始化 7 | static const String Init = 'Init'; 8 | 9 | /// 设置 Debug 10 | static const String SetDebug = 'SetDebug'; 11 | 12 | /// 城市信息查询 13 | static const String GeoCityLookup = 'GeoCityLookup'; 14 | 15 | /// 热门城市查询 16 | static const String GetGeoTopCity = 'GetGeoTopCity'; 17 | 18 | /// 热门城市查询 19 | static const String GeoPoiLookup = 'GeoPoiLookup'; 20 | 21 | /// POI范围搜索 22 | static const String GeoPoiRangeLookup = 'GeoPoiRangeLookup'; 23 | 24 | /// 获取实况天气数据 25 | static const String GetWeatherNow = 'GetWeatherNow'; 26 | 27 | /// 获取逐天预报 28 | static const String GetWeatherDaily = 'GetWeatherDaily'; 29 | 30 | /// 获取逐时预报 31 | static const String GetWeatherHourly = 'GetWeatherHourly'; 32 | 33 | /// 获取中国地区未来2小时内每5分钟降水 34 | static const String GetWeatherMinuteLy = 'GetWeatherMinuteLy'; 35 | 36 | /// 获取1天生活指数 37 | static const String GetIndices1Day = "GetIndices1Day"; 38 | 39 | /// 获取3天生活指数 40 | static const String GetIndices3Day = "GetIndices3Day"; 41 | 42 | /// 获取灾害预警 43 | static const String GetWarning = "GetWarning"; 44 | 45 | /// 获取灾害预警列表 46 | static const String GetWarningList = "GetWarningList"; 47 | 48 | /// 获取实时空气质量 49 | static const String GetAirNow = "GetAirNow"; 50 | 51 | /// 获取5天空气质量预报 52 | static const String GetAir5Day = "GetAir5Day"; 53 | 54 | /// 获取历史天气 55 | static const String GetHistoricalWeather = "GetHistoricalWeather"; 56 | 57 | /// 获取历史空气质量 58 | static const String GetHistoricalAir = "GetHistoricalAir"; 59 | 60 | /// 获取日出日落 61 | static const String GetSun = "GetSun"; 62 | 63 | /// 获取月升月落月相 64 | static const String GetMoon = "GetMoon"; 65 | 66 | /// 获取太阳高度角 67 | static const String GetSolarElevationAngle = "GetSolarElevationAngle"; 68 | 69 | /// 获取潮汐 70 | static const String GetOceanTide = "GetOceanTide"; 71 | 72 | /// 获取潮流 73 | static const String GetOceanCurrents = "GetOceanCurrents"; 74 | 75 | /// 台风列表 76 | static const String GetStormList = "GetStormList"; 77 | 78 | /// 台风实况和路径 79 | static const String GetStormTrack = "GetStormTrack"; 80 | 81 | /// 台风预报 82 | static const String GetStormForecast = "GetStormForecast"; 83 | } 84 | 85 | /// 逐天可选枚举 86 | class WeatherDailyForecast { 87 | final int _day; 88 | 89 | int get day => _day; 90 | 91 | const WeatherDailyForecast._(this._day); 92 | 93 | /// 未来 3 天预告 94 | static const WeatherForecast3Day = WeatherDailyForecast._(3); 95 | 96 | /// 未来 7 天预告 97 | static const WeatherForecast7Day = WeatherDailyForecast._(7); 98 | 99 | /// 未来 10 天预告 100 | static const WeatherForecast10Day = WeatherDailyForecast._(10); 101 | 102 | /// 未来 15 天预告 103 | static const WeatherForecast15Day = WeatherDailyForecast._(15); 104 | } 105 | 106 | /// 逐时可选枚举 107 | class WeatherHourlyForecast { 108 | final int _hour; 109 | 110 | int get hour => _hour; 111 | 112 | const WeatherHourlyForecast._(this._hour); 113 | 114 | /// 未来 24 小时预告 115 | static const WeatherForecast24Hour = WeatherHourlyForecast._(24); 116 | 117 | /// 未来 72 小时预告 118 | static const WeatherForecast72Hour = WeatherHourlyForecast._(72); 119 | 120 | /// 未来 168 小时预告 121 | static const WeatherForecast168Hour = WeatherHourlyForecast._(168); 122 | } 123 | 124 | /// POI类型 125 | class PoiType { 126 | final String _code; 127 | 128 | String get code => _code; 129 | 130 | const PoiType._(this._code); 131 | 132 | /// 景点 133 | static const PoiType scenic = PoiType._('scenic'); 134 | 135 | /// 潮流站点 136 | static const PoiType CSTA = PoiType._('CSTA'); 137 | 138 | /// 潮汐站点 139 | static const PoiType TSTA = PoiType._('TSTA'); 140 | } 141 | 142 | /// 生活指数常量 143 | class IndicesType { 144 | final String _code; 145 | 146 | String get code => _code; 147 | 148 | const IndicesType._(this._code); 149 | 150 | /// 全部生活指数 151 | static const IndicesType ALL = IndicesType._('ALL'); 152 | 153 | /// 运动指数 154 | static const IndicesType SPT = IndicesType._('SPT'); 155 | 156 | /// 洗车指数 157 | static const IndicesType CW = IndicesType._('CW'); 158 | 159 | /// 穿衣指数 160 | static const IndicesType DRSG = IndicesType._('DRSG'); 161 | 162 | /// 钓鱼指数 163 | static const IndicesType FIS = IndicesType._('FIS'); 164 | 165 | /// 紫外线指数 166 | static const IndicesType UV = IndicesType._('UV'); 167 | 168 | /// 旅游指数 169 | static const IndicesType TRAV = IndicesType._('TRAV'); 170 | 171 | /// 花粉过敏指数 172 | static const IndicesType AG = IndicesType._('AG'); 173 | 174 | /// 舒适度指数 175 | static const IndicesType COMF = IndicesType._('COMF'); 176 | 177 | /// 感冒指数 178 | static const IndicesType FLU = IndicesType._('FLU'); 179 | 180 | /// 空气污染扩散条件指数 181 | static const IndicesType AP = IndicesType._('AP'); 182 | 183 | /// 空调开启指数 184 | static const IndicesType AC = IndicesType._('AC'); 185 | 186 | /// 太阳镜指数 187 | static const IndicesType GL = IndicesType._('GL'); 188 | 189 | /// 化妆指数 190 | static const IndicesType MU = IndicesType._('MU'); 191 | 192 | /// 晾晒指数 193 | static const IndicesType DC = IndicesType._('DC'); 194 | 195 | /// 交通指数 196 | static const IndicesType PTFC = IndicesType._('PTFC'); 197 | 198 | /// 防晒指数 199 | static const IndicesType SPI = IndicesType._('SPI'); 200 | 201 | /// 滑雪指数,暂时获取不到 202 | static const IndicesType SKI = IndicesType._('SKI'); 203 | } 204 | 205 | /// 单位参数 206 | class Unit { 207 | final String code; 208 | 209 | const Unit._(this.code); 210 | 211 | static const Unit METRIC = Unit._('m'); 212 | static const Unit IMPERIAL = Unit._('i'); 213 | } 214 | 215 | /// 流域 216 | class Basin { 217 | final String _code; 218 | 219 | String get code => _code; 220 | 221 | const Basin._(this._code); 222 | 223 | static const Basin AL = Basin._('AL'); // North Atlantic 北大西洋 224 | static const Basin EP = Basin._('EP'); // Eastern Pacific 东太平洋 225 | static const Basin NP = Basin._('NP'); // NorthWest Pacific 西北太平洋 226 | static const Basin SP = Basin._('SP'); // SouthWestern Pacific 西南太平洋 227 | static const Basin NI = Basin._('NI'); // North Indian 北印度洋 228 | static const Basin SI = Basin._('SI'); // South Indian 南印度洋 229 | } 230 | -------------------------------------------------------------------------------- /lib/flutter_qweather.dart: -------------------------------------------------------------------------------- 1 | library qweather; 2 | 3 | import 'dart:async'; 4 | import 'dart:io'; 5 | 6 | import 'package:flutter/services.dart'; 7 | import 'models/air.dart'; 8 | import 'models/astronomy.dart'; 9 | import 'models/geo.dart'; 10 | import 'models/historical.dart'; 11 | import 'models/indices.dart'; 12 | import 'models/tropical.dart'; 13 | import 'models/warning.dart'; 14 | import 'models/weather.dart'; 15 | import 'constants.dart'; 16 | 17 | export 'models/geo.dart'; 18 | export 'models/weather.dart'; 19 | 20 | part 'apis/air_api.dart'; 21 | 22 | part 'apis/astronomy_api.dart'; 23 | 24 | part 'apis/geo_api.dart'; 25 | 26 | part 'apis/historical_api.dart'; 27 | 28 | part 'apis/indices_api.dart'; 29 | 30 | part 'apis/ocean_api.dart'; 31 | 32 | part 'apis/tropical_api.dart'; 33 | 34 | part 'apis/warning_api.dart'; 35 | 36 | part 'apis/weather_api.dart'; 37 | 38 | /// 和风天气配置 39 | class QweatherConfig { 40 | /// publicId for Android 41 | String publicIdForAndroid; 42 | 43 | /// key for Android 44 | String keyForAndroid; 45 | 46 | /// publicId for iOS 47 | String publicIdForIos; 48 | 49 | /// key for iOS 50 | String keyForIos; 51 | 52 | /// 是否调试模式 53 | bool debug; 54 | 55 | /// 是否商业模式 56 | bool biz; 57 | 58 | QweatherConfig( 59 | {this.publicIdForAndroid = '', 60 | this.keyForAndroid = '', 61 | this.publicIdForIos = '', 62 | this.keyForIos = '', 63 | this.debug = false, 64 | this.biz = false}); 65 | } 66 | 67 | class FlutterQweather extends _ServiceApi 68 | with 69 | _Air, 70 | _Astronomy, 71 | _Geo, 72 | _Historical, 73 | _Indices, 74 | _Ocean, 75 | _Tropical, 76 | _Warning, 77 | _Weather { 78 | FlutterQweather._(); 79 | 80 | static FlutterQweather instance = FlutterQweather._(); 81 | } 82 | 83 | class _ServiceApi { 84 | final _methodChannel = MethodChannel('com.fluttercandies.qweather'); 85 | 86 | Future get platformVersion async { 87 | final String? version = await _methodChannel 88 | .invokeMethod(MethodConstants.GetPlatformVersion); 89 | return version!; 90 | } 91 | 92 | /// 初始化 93 | Future init(QweatherConfig config) async { 94 | String publicId = '', key = ''; 95 | if (Platform.isAndroid) { 96 | publicId = config.publicIdForAndroid; 97 | key = config.keyForAndroid; 98 | } else if (Platform.isIOS) { 99 | publicId = config.publicIdForIos; 100 | key = config.keyForIos; 101 | } 102 | if (publicId.isEmpty || key.isEmpty) 103 | return print("和风天气:当前平台的 publicId 或 key 为空"); 104 | final Map param = { 105 | "publicId": publicId, 106 | "key": key, 107 | "biz": config.biz, 108 | "debug": config.debug 109 | }; 110 | final ok = await _methodChannel.invokeMethod(MethodConstants.Init, param); 111 | if (config.debug) print("和风天气:初始化结果: $ok"); 112 | } 113 | 114 | /// 设置 Debug 115 | Future setDebug([bool debug = true]) async { 116 | return await _methodChannel.invokeMethod(MethodConstants.SetDebug, debug); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /lib/models/air.dart: -------------------------------------------------------------------------------- 1 | import 'basic.dart'; 2 | import 'refer.dart'; 3 | 4 | /// 当前监测站 5 | class StationNow { 6 | /// 数据发布时间 7 | late String pubTime; 8 | 9 | /// 站点名称 10 | late String name; 11 | 12 | /// 站点id 13 | late int id; 14 | 15 | /// 空气质量指数,AQI和PM25的关系 16 | late int aqi; 17 | 18 | /// 主要污染物 19 | late String primary; 20 | 21 | /// 实时空气质量指数等级 22 | late int level; 23 | 24 | /// 实时空气质量指数级别 25 | late String category; 26 | 27 | /// PM 10 28 | late int pm10; 29 | 30 | /// PM 2.5 31 | late int pm2p5; 32 | 33 | /// 二氧化氮 34 | late int no2; 35 | 36 | /// 二氧化硫 37 | late int so2; 38 | 39 | /// 一氧化碳 40 | late double co; 41 | 42 | /// 臭氧 43 | late int o3; 44 | 45 | StationNow.fromMap(Map map) { 46 | pubTime = map['pubTime'] as String; 47 | name = map['name'] as String; 48 | id = map['id'] as int; 49 | aqi = map['aqi'] as int; 50 | primary = map['primary'] as String; 51 | level = map['level'] as int; 52 | category = map['category'] as String; 53 | pm10 = map['pm10'] as int; 54 | pm2p5 = map['pm2p5'] as int; 55 | no2 = map['no2'] as int; 56 | so2 = map['so2'] as int; 57 | co = map['co'] as double; 58 | o3 = map['o3'] as int; 59 | } 60 | } 61 | 62 | /// 实时空气质量 63 | class AirNow { 64 | /// 数据发布时间 65 | late String pubTime; 66 | 67 | /// 空气质量指数,AQI和PM25的关系 68 | late String aqi; 69 | 70 | /// 主要污染物 71 | late String primary; 72 | 73 | /// 实时空气质量指数等级 74 | late String level; 75 | 76 | /// 实时空气质量指数级别 77 | late String category; 78 | 79 | /// PM 10 80 | late String pm10; 81 | 82 | /// PM 2.5 83 | late String pm2p5; 84 | 85 | /// 二氧化氮 86 | late String no2; 87 | 88 | /// 二氧化硫 89 | late String so2; 90 | 91 | /// 一氧化碳 92 | late String co; 93 | 94 | /// 臭氧 95 | late String o3; 96 | 97 | AirNow.fromMap(Map map) { 98 | pubTime = map['pubTime'] as String; 99 | aqi = map['aqi'] as String; 100 | primary = map['primary'] as String; 101 | level = map['level'] as String; 102 | category = map['category'] as String; 103 | pm10 = map['pm10'] as String; 104 | pm2p5 = map['pm2p5'] as String; 105 | no2 = map['no2'] as String; 106 | so2 = map['so2'] as String; 107 | co = map['co'] as String; 108 | o3 = map['o3'] as String; 109 | } 110 | } 111 | 112 | /// 实时空气质量查询结果 113 | class AirNowResp { 114 | /// API状态码 115 | late String code; 116 | 117 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 118 | late Basic basic; 119 | 120 | /// Refer 数据来源信息 121 | late Refer refer; 122 | 123 | /// AirNow 实时空气质量 124 | late AirNow now; 125 | 126 | late List stations; 127 | 128 | /// fromMap 129 | AirNowResp.fromMap(Map map) { 130 | code = map['code'] as String; 131 | basic = Basic.fromMap(map['basic'] ?? Map()); 132 | refer = Refer.fromMap(map['refer'] ?? Map()); 133 | now = AirNow.fromMap(map['now'] ?? Map()); 134 | stations = map.containsKey('airNowStationBean') 135 | ? (map['airNowStationBean'] as List) 136 | .map((v) => StationNow.fromMap(v)) 137 | .toList() 138 | : []; 139 | } 140 | } 141 | 142 | /// 逐天空气质量 143 | class AirDaily { 144 | /// 预报日期 145 | late String fxDate; 146 | 147 | /// 空气质量指数,AQI和PM25的关系 148 | late String aqi; 149 | 150 | /// 主要污染物 151 | late String primary; 152 | 153 | /// 实时空气质量指数等级 154 | late String level; 155 | 156 | /// 实时空气质量指数级别 157 | late String category; 158 | 159 | AirDaily.fromMap(Map map) { 160 | fxDate = map['fxDate'] as String; 161 | aqi = map['aqi'] as String; 162 | primary = map['primary'] as String; 163 | level = map['level'] as String; 164 | category = map['category'] as String; 165 | } 166 | } 167 | 168 | /// 逐天空气质量预报查询结果 169 | class AirDailyResp { 170 | /// API状态码 171 | late String code; 172 | 173 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 174 | late Basic basic; 175 | 176 | /// Refer 数据来源信息 177 | late Refer refer; 178 | 179 | /// 逐天预报 180 | late List daily; 181 | 182 | /// fromMap 183 | AirDailyResp.fromMap(Map map) { 184 | code = map['code'] as String; 185 | basic = Basic.fromMap(map['basic'] ?? Map()); 186 | refer = Refer.fromMap(map['refer'] ?? Map()); 187 | daily = map.containsKey('airDailyBeans') 188 | ? (map['airDailyBeans'] as List) 189 | .map((v) => AirDaily.fromMap(v)) 190 | .toList() 191 | : []; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /lib/models/astronomy.dart: -------------------------------------------------------------------------------- 1 | import 'basic.dart'; 2 | import 'refer.dart'; 3 | 4 | /// 日出日落 5 | class Sun { 6 | /// 日出时间 7 | late String sunrise; 8 | 9 | /// 日落时间 10 | late String sunset; 11 | 12 | Sun.fromMap(Map map) { 13 | sunrise = map['sunrise'] as String; 14 | sunset = map['sunset'] as String; 15 | } 16 | } 17 | 18 | /// 获取日出日落查询结果 19 | class SunRsp { 20 | /// API状态码 21 | late String code; 22 | 23 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 24 | late Basic basic; 25 | 26 | /// Refer 数据来源信息 27 | late Refer refer; 28 | 29 | /// Sun 日出日落 30 | late Sun sun; 31 | 32 | SunRsp.fromMap(Map map) { 33 | code = map['code'] as String; 34 | basic = Basic.fromMap(map['basic'] ?? Map()); 35 | refer = Refer.fromMap(map['refer'] ?? Map()); 36 | sun = Sun.fromMap(map); 37 | } 38 | } 39 | 40 | /// 月相信息 41 | class MoonPhase { 42 | /// 月相逐小时预报时间 43 | late String fxTime; 44 | 45 | /// 月相数值 46 | late String value; 47 | 48 | /// 月相名字 49 | late String name; 50 | 51 | /// 月亮照明度,百分比数值 52 | late String illumination; 53 | 54 | /// 月相图标代码 55 | late String icon; 56 | 57 | MoonPhase.fromMap(Map map) { 58 | fxTime = map['fxTime'] as String; 59 | value = map['value'] as String; 60 | name = map['name'] as String; 61 | illumination = map['illumination'] as String; 62 | icon = map['icon'] as String; 63 | } 64 | } 65 | 66 | /// 月升月落月相 67 | class Moon { 68 | /// 月升时间 69 | late String moonrise; 70 | 71 | /// 月落时间 72 | late String moonset; 73 | 74 | Moon.fromMap(Map map) { 75 | moonrise = map['moonrise'] as String; 76 | moonset = map['moonset'] as String; 77 | } 78 | } 79 | 80 | /// 月升月落月相查询结果 81 | class MoonRsp { 82 | /// API状态码 83 | late String code; 84 | 85 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 86 | late Basic basic; 87 | 88 | /// Refer 数据来源信息 89 | late Refer refer; 90 | 91 | /// Moon 月升月落月相 92 | late Moon moon; 93 | 94 | /// 月相信息 95 | late List moonPhaseList; 96 | 97 | MoonRsp.fromMap(Map map) { 98 | code = map['code'] as String; 99 | basic = Basic.fromMap(map['basic'] ?? Map()); 100 | refer = Refer.fromMap(map['refer'] ?? Map()); 101 | moon = Moon.fromMap(map); 102 | moonPhaseList = List.from((map['moonPhaseBeanList'] as List? ?? []) 103 | .map((v) => MoonPhase.fromMap(v))); 104 | } 105 | } 106 | 107 | /// 太阳高度角 108 | class SolarElevationAngle { 109 | /// 太阳高度角 110 | late String solarElevationAngle; 111 | 112 | /// 太阳方位角,正北顺时针方向角度 113 | late String solarAzimuthAngle; 114 | 115 | /// 太阳时,HHmm格式 116 | late String solarHour; 117 | 118 | /// 时角 119 | late String hourAngle; 120 | 121 | SolarElevationAngle.fromMap(Map map) { 122 | solarElevationAngle = map['solarElevationAngle'] as String; 123 | solarAzimuthAngle = map['solarAzimuthAngle'] as String; 124 | solarHour = map['solarHour'] as String; 125 | hourAngle = map['hourAngle'] as String; 126 | } 127 | } 128 | 129 | /// 太阳高度角查询结果 130 | class SolarElevationAngleRsp { 131 | /// API状态码 132 | late String code; 133 | 134 | /// Refer 数据来源信息 135 | late Refer refer; 136 | 137 | /// SolarElevationAngle 太阳高度角信息 138 | late SolarElevationAngle solarElevationAngle; 139 | 140 | SolarElevationAngleRsp.fromMap(Map map) { 141 | code = map['code'] as String; 142 | refer = Refer.fromMap(map['refer'] ?? Map()); 143 | solarElevationAngle = SolarElevationAngle.fromMap(map); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /lib/models/basic.dart: -------------------------------------------------------------------------------- 1 | /// 结果基础信息 2 | class Basic { 3 | /// 所查询城市的天气预报网页 4 | late String fxLink; 5 | 6 | /// 接口更新时间: 2021-04-19T18:27+08:00 7 | late String updateTime; 8 | 9 | /// fromMap 10 | Basic.fromMap(Map map) { 11 | fxLink = map["fxLink"] ?? ''; 12 | updateTime = map["updateTime"] ?? ''; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/models/geo.dart: -------------------------------------------------------------------------------- 1 | import 'refer.dart'; 2 | 3 | /// PIO地址信息 4 | class GeoPoiLocation { 5 | /// 地区/城市名称/地址 卓资 6 | late String name; 7 | 8 | /// 地区/城市ID 101080402 9 | late String id; 10 | 11 | /// 地区/城市经度 112.577702 12 | late String lon; 13 | 14 | /// 地区/城市纬度 40.89576 15 | late String lat; 16 | 17 | /// 该地区/城市的上级城市 乌兰察布 18 | late String adm2; 19 | 20 | /// 该地区/城市所属行政区域 内蒙古 21 | late String adm1; 22 | 23 | /// 该地区/城市所属国家名称 中国 24 | late String country; 25 | 26 | /// 该地区/城市所在时区 Asia/Shanghai 27 | late String tz; 28 | 29 | /// 该地区/城市目前与UTC时间偏移的小时数 +08:00 30 | late String utcOffset; 31 | 32 | /// 该地区/城市是否当前处于夏令时,1: 表示当前处于夏令时, 0: 表示当前不是夏令时 0 33 | late String isDst; 34 | 35 | /// 该地区/城市的属性 city 36 | late String type; 37 | 38 | /// 该地区/城市评分 10 39 | late String rank; 40 | 41 | /// 城市的天气预报网页链接 http://hfx.link/ae45;安卓 POI信息搜索/POI范围搜索时 为空 42 | late String fxLink; 43 | 44 | /// fromMap 45 | GeoPoiLocation.fromMap(Map map) { 46 | name = map['name'] as String; 47 | id = map['id'] as String; 48 | lon = map['lon'] as String; 49 | lat = map['lat'] as String; 50 | adm1 = map['adm1'] as String; 51 | adm2 = map['adm2'] as String; 52 | country = map['country'] as String; 53 | tz = map['tz'] as String; 54 | utcOffset = map['utcOffset'] as String; 55 | isDst = map['isDst'] as String; 56 | type = map['type'] as String; 57 | rank = map['rank'] as String; 58 | fxLink = map['fxLink'] as String? ?? ''; 59 | } 60 | } 61 | 62 | /// 城市信息查询/热门城市查询/POI信息搜索/POI范围搜索 结果 63 | class GeoPoiLocationResp { 64 | /// API状态码 65 | late String code; 66 | 67 | /// Refer 数据来源信息 68 | late Refer refer; 69 | 70 | /// 城市数据 71 | late List locations; 72 | 73 | /// fromMap 74 | GeoPoiLocationResp.fromMap(Map map) { 75 | code = map['code'] as String; 76 | refer = Refer.fromMap(map['refer'] ?? Map()); 77 | List _tmp = map['locations'] ?? []; 78 | locations = _tmp.map((v) => GeoPoiLocation.fromMap(v)).toList(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/models/historical.dart: -------------------------------------------------------------------------------- 1 | import 'basic.dart'; 2 | import 'refer.dart'; 3 | 4 | /// 历史当天天气 5 | class HistoricalDailyWeather { 6 | /// 当天日期 7 | late String date; 8 | 9 | /// 日出时间 10 | late String sunrise; 11 | 12 | /// 日落时间 13 | late String sunset; 14 | 15 | /// 月升时间 16 | late String moonrise; 17 | 18 | /// 月落时间 19 | late String moonset; 20 | 21 | /// 月相 22 | late String moonPhase; 23 | 24 | /// 最高温度 25 | late String tempMax; 26 | 27 | /// 最低温度 28 | late String tempMin; 29 | 30 | /// 相对温度 31 | late String humidity; 32 | 33 | /// 降雨量 34 | late String precip; 35 | 36 | /// 大气压强 37 | late String pressure; 38 | 39 | HistoricalDailyWeather.fromMap(Map map) { 40 | date = map['date'] as String; 41 | sunrise = map['sunrise'] as String; 42 | sunset = map['sunset'] as String; 43 | moonrise = map['moonrise'] as String; 44 | moonset = map['moonset'] as String; 45 | moonPhase = map['moonPhase'] as String; 46 | tempMax = map['tempMax'] as String; 47 | tempMin = map['tempMin'] as String; 48 | humidity = map['humidity'] as String; 49 | precip = map['precip'] as String; 50 | pressure = map['pressure'] as String; 51 | } 52 | } 53 | 54 | /// 历史当天逐小时天气 55 | class HistoricalHourlyWeather { 56 | /// 历史当天天气时间 57 | late String time; 58 | 59 | /// 温度 60 | late String temp; 61 | 62 | /// 天气状况图标代码 63 | late String icon; 64 | 65 | /// 天气状况代码 66 | late String text; 67 | 68 | /// 风向360角度 69 | late String wind360; 70 | 71 | /// 风向 72 | late String windDir; 73 | 74 | /// 风力 75 | late String windScale; 76 | 77 | /// 风速 78 | late String windSpeed; 79 | 80 | /// 温度 81 | late String humidity; 82 | 83 | /// 打起压强 84 | late String pressure; 85 | 86 | /// 降雨量 87 | late String precip; 88 | 89 | HistoricalHourlyWeather.fromMap(Map map) { 90 | time = map['time'] as String; 91 | temp = map['temp'] as String; 92 | icon = map['icon'] as String; 93 | text = map['text'] as String; 94 | wind360 = map['wind360'] as String; 95 | windDir = map['windDir'] as String; 96 | windScale = map['windScale'] as String; 97 | windSpeed = map['windSpeed'] as String; 98 | humidity = map['humidity'] as String; 99 | pressure = map['pressure'] as String; 100 | precip = map['precip'] as String; 101 | } 102 | } 103 | 104 | /// 历史天气查询结果 105 | class HistoricalWeatherRsp { 106 | /// API状态码 107 | late String code; 108 | 109 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 110 | late Basic basic; 111 | 112 | /// Refer 数据来源信息 113 | late Refer refer; 114 | 115 | /// HistoricalDailyWeather 历史当天天气 116 | late HistoricalDailyWeather dailyWeather; 117 | 118 | /// List 当天逐小时天气 119 | late List hourlyWeatherList; 120 | 121 | /// fromMap 122 | HistoricalWeatherRsp.fromMap(Map map) { 123 | code = map['code'] as String; 124 | basic = Basic.fromMap(map['basic'] ?? Map()); 125 | refer = Refer.fromMap(map['refer'] ?? Map()); 126 | dailyWeather = HistoricalDailyWeather.fromMap(map['dailyBean'] ?? Map()); 127 | hourlyWeatherList = List.from((map['hourlyBeans'] as List? ?? []) 128 | .map((v) => HistoricalHourlyWeather.fromMap(v))); 129 | } 130 | } 131 | 132 | /// 历史当天逐小时空气质量 133 | class HistoricalHourlyAir { 134 | /// 数据发布时间 135 | late String pubTime; 136 | 137 | /// 空气质量指数,AQI和PM25的关系 138 | late String aqi; 139 | 140 | /// 主要污染物 141 | late String primary; 142 | 143 | /// 实时空气质量指数等级 144 | late String level; 145 | 146 | /// 实时空气质量指数级别 147 | late String category; 148 | 149 | /// PM10 150 | late String pm10; 151 | 152 | /// PM2.5 153 | late String pm2p5; 154 | 155 | /// 二氧化氮 156 | late String no2; 157 | 158 | /// 二氧化硫 159 | late String so2; 160 | 161 | /// 一氧化碳 162 | late String co; 163 | 164 | /// 臭氧 165 | late String o3; 166 | 167 | HistoricalHourlyAir.fromMap(Map map) { 168 | pubTime = map['pubTime'] as String; 169 | aqi = map['aqi'] as String; 170 | primary = map['primary'] as String; 171 | level = map['level'] as String; 172 | category = map['category'] as String; 173 | pm10 = map['pm10'] as String; 174 | pm2p5 = map['pm2p5'] as String; 175 | no2 = map['no2'] as String; 176 | so2 = map['so2'] as String; 177 | co = map['co'] as String; 178 | o3 = map['o3'] as String; 179 | } 180 | } 181 | 182 | /// 历史当天逐小时空气质量查询结果 183 | class HistoricalHourlyAirRsp { 184 | /// API状态码 185 | late String code; 186 | 187 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 188 | late Basic basic; 189 | 190 | /// Refer 数据来源信息 191 | late Refer refer; 192 | 193 | /// HistoricalDailyWeather 历史当天天气 194 | late HistoricalDailyWeather dailyWeather; 195 | 196 | /// List 历史当天逐小时空气质量 197 | late List hourlyAirList; 198 | 199 | /// fromMap 200 | HistoricalHourlyAirRsp.fromMap(Map map) { 201 | code = map['code'] as String; 202 | basic = Basic.fromMap(map['basic'] ?? Map()); 203 | refer = Refer.fromMap(map['refer'] ?? Map()); 204 | hourlyAirList = List.from((map['airHourlyBeans'] as List? ?? []) 205 | .map((v) => HistoricalHourlyAirRsp.fromMap(v))); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /lib/models/indices.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_qweather/models/refer.dart'; 2 | 3 | /// 当天生活指数信息 4 | class DailyIndices { 5 | /// 预报日期,格式 yyyy-MM-dd 6 | late String date; 7 | 8 | /// 生活指数预报等级 9 | late String level; 10 | 11 | /// 生活指数预报级别名称 12 | late String category; 13 | 14 | /// 生活指数类型名称 15 | late String name; 16 | 17 | /// 生活指数类型 18 | late String type; 19 | 20 | /// 生活指数详细描述 21 | late String text; 22 | 23 | /// fromMap 24 | DailyIndices.fromMap(Map map) { 25 | date = map['date'] as String; 26 | level = map['level'] as String; 27 | category = map['category'] as String; 28 | name = map['name'] as String; 29 | type = map['type'] as String; 30 | text = map['text'] as String; 31 | } 32 | } 33 | 34 | /// 天气生活指数查询 结果 35 | class DailyIndicesResp { 36 | /// API状态码 37 | late String code; 38 | 39 | /// Refer 数据来源信息 40 | late Refer refer; 41 | 42 | /// 天气生活指数 43 | late List dailyList; 44 | 45 | /// fromMap 46 | DailyIndicesResp.fromMap(Map map) { 47 | code = map['code'] as String; 48 | refer = Refer.fromMap(map['refer'] ?? Map()); 49 | List _tmp = map['dailyList'] ?? []; 50 | dailyList = _tmp.map((v) => DailyIndices.fromMap(v)).toList(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/models/ocean.dart: -------------------------------------------------------------------------------- 1 | import 'basic.dart'; 2 | import 'refer.dart'; 3 | 4 | /// 满潮或干潮数据 5 | class OceanTide { 6 | /// 满潮或干潮时间 7 | late String fxTime; 8 | 9 | /// 海水高度,单位:米 10 | late String height; 11 | 12 | /// 满潮(H)或干潮(L) 13 | late String type; 14 | 15 | OceanTide.fromMap(Map map) { 16 | fxTime = map['fxTime'] as String; 17 | height = map['height'] as String; 18 | type = map['type'] as String? ?? ''; 19 | } 20 | } 21 | 22 | /// 潮汐查询结果 23 | class OceanTideRsp { 24 | /// API状态码 25 | late String code; 26 | 27 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 28 | late Basic basic; 29 | 30 | /// Refer 数据来源信息 31 | late Refer refer; 32 | 33 | /// 潮汐小时数据 34 | late List tideHourlyList; 35 | 36 | /// 满潮或干潮数据 37 | late List tideList; 38 | 39 | /// fromMap 40 | OceanTideRsp.fromMap(Map map) { 41 | code = map['code'] as String; 42 | basic = Basic.fromMap(map['basic'] ?? Map()); 43 | refer = Refer.fromMap(map['refer'] ?? Map()); 44 | tideHourlyList = (map["tideHourlyList"] as List? ?? []) 45 | .map((v) => OceanTide.fromMap(v)) 46 | .toList(); 47 | tideList = (map["tideTable"] as List? ?? []) 48 | .map((v) => OceanTide.fromMap(v)) 49 | .toList(); 50 | } 51 | } 52 | 53 | /// 潮流数据 54 | class OceanCurrents { 55 | /// 潮流最大流速时间 56 | late String fxTime; 57 | 58 | /// 潮流最大流速,单位:厘米/秒 59 | late String speedMax; 60 | 61 | /// 潮流360度方向 62 | late String dir360; 63 | 64 | OceanCurrents.fromMap(Map map) { 65 | fxTime = map['fxTime'] as String; 66 | speedMax = map['speedMax'] as String; 67 | dir360 = map['dir360'] as String; 68 | } 69 | } 70 | 71 | /// 潮流数据查询结果 72 | class OceanCurrentsRsp { 73 | /// API状态码 74 | late String code; 75 | 76 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 77 | late Basic basic; 78 | 79 | /// Refer 数据来源信息 80 | late Refer refer; 81 | 82 | /// 潮流小时数据 83 | late List currentsHourlyList; 84 | 85 | /// 潮流数据 86 | late List currentsList; 87 | 88 | /// fromMap 89 | OceanCurrentsRsp.fromMap(Map map) { 90 | code = map['code'] as String; 91 | basic = Basic.fromMap(map['basic'] ?? Map()); 92 | refer = Refer.fromMap(map['refer'] ?? Map()); 93 | currentsHourlyList = (map["hourlyList"] as List? ?? []) 94 | .map((v) => OceanCurrents.fromMap(v)) 95 | .toList(); 96 | currentsList = (map["tableList"] as List? ?? []) 97 | .map((v) => OceanCurrents.fromMap(v)) 98 | .toList(); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /lib/models/refer.dart: -------------------------------------------------------------------------------- 1 | /// 数据源 2 | class Refer { 3 | /// 原始数据来源,或数据源说明 4 | List sources = []; 5 | 6 | /// 数据许可或版权声明 7 | List license = []; 8 | 9 | /// fromMap 10 | Refer.fromMap(Map map) { 11 | if (map.containsKey("sourcesList")) sources = List.from(map["sourcesList"]); 12 | if (map.containsKey("licenseList")) license = List.from(map["licenseList"]); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/models/tropical.dart: -------------------------------------------------------------------------------- 1 | import 'basic.dart'; 2 | import 'refer.dart'; 3 | 4 | /// 台风 5 | class Storm { 6 | /// 台风ID 7 | late String id; 8 | 9 | /// 台风名称 10 | late String name; 11 | 12 | /// 台风所处流域 13 | late String basin; 14 | 15 | /// 台风所处年份 16 | late String year; 17 | 18 | /// 是否为活跃台风 19 | late String active; 20 | 21 | Storm.fromMap(Map map) { 22 | id = map['id'] as String; 23 | name = map['name'] as String; 24 | basin = map['basin'] as String; 25 | year = map['year'] as String; 26 | active = map['active'] as String; 27 | } 28 | } 29 | 30 | /// 台风列表查询结果 31 | class StormListRsp { 32 | /// API状态码 33 | late String code; 34 | 35 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 36 | late Basic basic; 37 | 38 | /// Refer 数据来源信息 39 | late Refer refer; 40 | 41 | /// 台风列表数据 42 | late List stormList; 43 | 44 | /// fromMap 45 | StormListRsp.fromMap(Map map) { 46 | code = map['code'] as String; 47 | basic = Basic.fromMap(map['basic'] ?? Map()); 48 | refer = Refer.fromMap(map['refer'] ?? Map()); 49 | stormList = (map["stormList"] ?? []).map((v) => Storm.fromMap(v)).toList(); 50 | } 51 | } 52 | 53 | /// 台风风圈 54 | class StormTrackWind { 55 | /// 东北半径 56 | late String neRadius; 57 | 58 | /// 东南半径 59 | late String seRadius; 60 | 61 | /// 西南半径 62 | late String swRadius; 63 | 64 | /// 西北半径 65 | late String nwRadius; 66 | 67 | StormTrackWind.fromMap(Map map) { 68 | neRadius = map['neRadius'] as String; 69 | seRadius = map['seRadius'] as String; 70 | swRadius = map['swRadius'] as String; 71 | nwRadius = map['nwRadius'] as String; 72 | } 73 | } 74 | 75 | /// 台风当前信息数据 76 | class StormTrackNow { 77 | /// 台风信息发布时间 78 | late String pubTime; 79 | 80 | /// 台风所处经度 81 | late String lon; 82 | 83 | /// 台风所处纬度 84 | late String lat; 85 | 86 | /// 台风类型 87 | late String type; 88 | 89 | /// 台风中心气压 90 | late String pressure; 91 | 92 | /// 台风附近最大风速 93 | late String windSpeed; 94 | 95 | /// 台风移动速度 96 | late String moveSpeed; 97 | 98 | /// 台风移动方位 99 | late String moveDir; 100 | 101 | /// 台风移动方位360度方向 ,可能为空 102 | late String move360; 103 | 104 | /// 台风7级风圈,可能为空 105 | StormTrackWind? windRadius30; 106 | 107 | /// 台风10级风圈,可能为空 108 | StormTrackWind? windRadius50; 109 | 110 | /// 台风12级风圈,可能为空 111 | StormTrackWind? windRadius64; 112 | 113 | StormTrackNow.fromMap(Map map) { 114 | pubTime = map['pubTime'] as String; 115 | lon = map['lon'] as String; 116 | lat = map['lat'] as String; 117 | type = map['type'] as String; 118 | pressure = map['pressure'] as String; 119 | windSpeed = map['windSpeed'] as String; 120 | moveSpeed = map['moveSpeed'] as String; 121 | moveDir = map['moveDir'] as String; 122 | move360 = map['move360'] as String? ?? ''; 123 | if (map.containsKey('windRadius30')) { 124 | windRadius30 = StormTrackWind.fromMap(map['windRadius30']); 125 | } 126 | if (map.containsKey('windRadius50')) { 127 | windRadius50 = StormTrackWind.fromMap(map['windRadius50']); 128 | } 129 | if (map.containsKey('windRadius64')) { 130 | windRadius64 = StormTrackWind.fromMap(map['windRadius64']); 131 | } 132 | } 133 | } 134 | 135 | /// 台风路径数据 136 | class StormTrack { 137 | /// 台风信息发布时间 138 | late String time; 139 | 140 | /// 台风所处经度 141 | late String lon; 142 | 143 | /// 台风所处纬度 144 | late String lat; 145 | 146 | /// 台风类型 147 | late String type; 148 | 149 | /// 台风中心气压 150 | late String pressure; 151 | 152 | /// 台风附近最大风速 153 | late String windSpeed; 154 | 155 | /// 台风移动速度 156 | late String moveSpeed; 157 | 158 | /// 台风移动方位 159 | late String moveDir; 160 | 161 | /// 台风移动方位360度方向 ,可能为空 162 | late String move360; 163 | 164 | /// 台风7级风圈,可能为空 165 | StormTrackWind? windRadius30; 166 | 167 | /// 台风10级风圈,可能为空 168 | StormTrackWind? windRadius50; 169 | 170 | /// 台风12级风圈,可能为空 171 | StormTrackWind? windRadius64; 172 | 173 | StormTrack.fromMap(Map map) { 174 | time = map['time'] as String; 175 | lon = map['lon'] as String; 176 | lat = map['lat'] as String; 177 | type = map['type'] as String; 178 | pressure = map['pressure'] as String; 179 | windSpeed = map['windSpeed'] as String; 180 | moveSpeed = map['moveSpeed'] as String; 181 | moveDir = map['moveDir'] as String; 182 | move360 = map['move360'] as String? ?? ''; 183 | if (map.containsKey('windRadius30')) { 184 | windRadius30 = StormTrackWind.fromMap(map['windRadius30']); 185 | } 186 | if (map.containsKey('windRadius50')) { 187 | windRadius50 = StormTrackWind.fromMap(map['windRadius50']); 188 | } 189 | if (map.containsKey('windRadius64')) { 190 | windRadius64 = StormTrackWind.fromMap(map['windRadius64']); 191 | } 192 | } 193 | } 194 | 195 | /// 台风实况和路径查询结果 196 | class StormTracRsp { 197 | /// API状态码 198 | late String code; 199 | 200 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 201 | late Basic basic; 202 | 203 | /// Refer 数据来源信息 204 | late Refer refer; 205 | 206 | /// 是否为活跃台风 1:活跃台风; 0:停编 207 | late String isActive; 208 | 209 | /// 台风当前信息数据 210 | late StormTrackNow now; 211 | 212 | /// 台风路径数据 213 | late List trackList; 214 | 215 | /// fromMap 216 | StormTracRsp.fromMap(Map map) { 217 | code = map['code'] as String; 218 | basic = Basic.fromMap(map['basic'] ?? Map()); 219 | refer = Refer.fromMap(map['refer'] ?? Map()); 220 | isActive = map['isActive'] ?? '0'; 221 | now = StormTrackNow.fromMap(map['now']); 222 | trackList = (map["trackList"] as List? ?? []) 223 | .map((v) => StormTrack.fromMap(v)) 224 | .toList(); 225 | } 226 | } 227 | 228 | /// 台风预报 229 | class Forecast { 230 | late String fxTime; 231 | late String lon; 232 | late String lat; 233 | late String type; 234 | late String pressure; 235 | late String windSpeed; 236 | late String moveSpeed; 237 | late String moveDir; 238 | late String move360; 239 | 240 | Forecast.fromMap(Map map) { 241 | fxTime = map['fxTime'] as String; 242 | lon = map['lon'] as String; 243 | lat = map['lat'] as String; 244 | type = map['type'] as String; 245 | pressure = map['pressure'] as String; 246 | windSpeed = map['windSpeed'] as String; 247 | moveSpeed = map['moveSpeed'] as String; 248 | moveDir = map['moveDir'] as String; 249 | move360 = map['move360'] as String? ?? ''; 250 | } 251 | } 252 | 253 | /// 台风预报查询结果 254 | class ForecastRsp { 255 | /// API状态码 256 | late String code; 257 | 258 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 259 | late Basic basic; 260 | 261 | /// Refer 数据来源信息 262 | late Refer refer; 263 | 264 | /// 台风预报列表 265 | late List forecastList; 266 | 267 | /// fromMap 268 | ForecastRsp.fromMap(Map map) { 269 | code = map['code'] as String; 270 | basic = Basic.fromMap(map['basic'] ?? Map()); 271 | refer = Refer.fromMap(map['refer'] ?? Map()); 272 | forecastList = (map["forecastList"] as List? ?? []) 273 | .map((v) => Forecast.fromMap(v)) 274 | .toList(); 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /lib/models/warning.dart: -------------------------------------------------------------------------------- 1 | import 'basic.dart'; 2 | import 'refer.dart'; 3 | 4 | /// 灾害预警 5 | class Warning { 6 | /// 预警id 7 | late String id; 8 | 9 | /// 预警发布时间 10 | late String pubTime; 11 | 12 | /// 预警信息标题 13 | late String title; 14 | 15 | /// 预警发布单位,可能为空 16 | late String sender; 17 | 18 | /// 预警开始时间 19 | late String startTime; 20 | 21 | /// 预警结束时间 22 | late String endTime; 23 | 24 | /// 预警状态 25 | late String status; 26 | 27 | /// 预警等级:蓝黄橙红白 28 | late String level; 29 | 30 | /// 预警类型,全部类型参考本文简介 31 | late String type; 32 | 33 | /// 预警类型,全部类型参考本文简介 34 | late String typeName; 35 | 36 | /// 预警详细信息 37 | late String text; 38 | 39 | /// 与本条预警相关联的预警ID,当预警状态为cancel或update时返回。可能为空 40 | late String related; 41 | 42 | Warning.fromMap(Map map) { 43 | id = map['id'] as String; 44 | pubTime = map['pubTime'] as String; 45 | title = map['title'] as String; 46 | sender = map['sender'] as String; 47 | startTime = map['startTime'] as String; 48 | endTime = map['endTime'] as String; 49 | status = map['status'] as String; 50 | level = map['level'] as String; 51 | type = map['type'] as String; 52 | typeName = map['typeName'] as String; 53 | text = map['text'] as String; 54 | related = map['related'] as String; 55 | } 56 | } 57 | 58 | /// 灾害预警查询结果 59 | class WarningRsp { 60 | /// API状态码 61 | late String code; 62 | 63 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 64 | late Basic basic; 65 | 66 | /// Refer 数据来源信息 67 | late Refer refer; 68 | 69 | /// WeatherNow 实时天气 70 | late List warningList; 71 | 72 | /// fromMap 73 | WarningRsp.fromMap(Map map) { 74 | code = map['code'] as String; 75 | basic = Basic.fromMap(map['basic'] ?? Map()); 76 | refer = Refer.fromMap(map['refer'] ?? Map()); 77 | warningList = map.containsKey('warningList') 78 | ? (map['warningList'] as List).map((v) => Warning.fromMap(v)).toList() 79 | : []; 80 | } 81 | } 82 | 83 | /// 预警城市 84 | class WarningLocation { 85 | late String locationId; 86 | 87 | WarningLocation.fromMap(Map map) { 88 | locationId = map['locationId'] as String; 89 | } 90 | } 91 | 92 | /// 灾害预警列表查询结果 93 | class WarningListRsp { 94 | /// API状态码 95 | late String code; 96 | 97 | /// Basic 包含 接口更新时间, 所查询城市的天气预报网页 98 | late Basic basic; 99 | 100 | /// Refer 数据来源信息 101 | late Refer refer; 102 | 103 | /// WeatherNow 实时天气 104 | late List warningList; 105 | 106 | /// fromMap 107 | WarningListRsp.fromMap(Map map) { 108 | code = map['code'] as String; 109 | basic = Basic.fromMap(map['basic'] ?? Map()); 110 | refer = Refer.fromMap(map['refer'] ?? Map()); 111 | warningList = List.from((map['warningBean'] as List? ?? []) 112 | .map((v) => WarningLocation.fromMap(v))); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.10.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.2.1" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.17.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_test: 58 | dependency: "direct dev" 59 | description: flutter 60 | source: sdk 61 | version: "0.0.0" 62 | js: 63 | dependency: transitive 64 | description: 65 | name: js 66 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" 67 | url: "https://pub.flutter-io.cn" 68 | source: hosted 69 | version: "0.6.5" 70 | matcher: 71 | dependency: transitive 72 | description: 73 | name: matcher 74 | sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" 75 | url: "https://pub.flutter-io.cn" 76 | source: hosted 77 | version: "0.12.13" 78 | material_color_utilities: 79 | dependency: transitive 80 | description: 81 | name: material_color_utilities 82 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 83 | url: "https://pub.flutter-io.cn" 84 | source: hosted 85 | version: "0.2.0" 86 | meta: 87 | dependency: transitive 88 | description: 89 | name: meta 90 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" 91 | url: "https://pub.flutter-io.cn" 92 | source: hosted 93 | version: "1.8.0" 94 | path: 95 | dependency: transitive 96 | description: 97 | name: path 98 | sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "1.8.2" 102 | sky_engine: 103 | dependency: transitive 104 | description: flutter 105 | source: sdk 106 | version: "0.0.99" 107 | source_span: 108 | dependency: transitive 109 | description: 110 | name: source_span 111 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 112 | url: "https://pub.flutter-io.cn" 113 | source: hosted 114 | version: "1.9.1" 115 | stack_trace: 116 | dependency: transitive 117 | description: 118 | name: stack_trace 119 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 120 | url: "https://pub.flutter-io.cn" 121 | source: hosted 122 | version: "1.11.0" 123 | stream_channel: 124 | dependency: transitive 125 | description: 126 | name: stream_channel 127 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "2.1.1" 131 | string_scanner: 132 | dependency: transitive 133 | description: 134 | name: string_scanner 135 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 136 | url: "https://pub.flutter-io.cn" 137 | source: hosted 138 | version: "1.2.0" 139 | term_glyph: 140 | dependency: transitive 141 | description: 142 | name: term_glyph 143 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 144 | url: "https://pub.flutter-io.cn" 145 | source: hosted 146 | version: "1.2.1" 147 | test_api: 148 | dependency: transitive 149 | description: 150 | name: test_api 151 | sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 152 | url: "https://pub.flutter-io.cn" 153 | source: hosted 154 | version: "0.4.16" 155 | vector_math: 156 | dependency: transitive 157 | description: 158 | name: vector_math 159 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 160 | url: "https://pub.flutter-io.cn" 161 | source: hosted 162 | version: "2.1.4" 163 | sdks: 164 | dart: ">=2.18.0 <4.0.0" 165 | flutter: ">=1.20.0" 166 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_qweather 2 | description: A qweather Flutter plugin. Free use of qweather api. Only Android and IOS platforms are supported. 3 | version: 0.0.11 4 | homepage: https://github.com/fluttercandies/flutter_qweather 5 | environment: 6 | sdk: ">=2.12.0 <3.0.0" 7 | flutter: ">=1.20.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | dev_dependencies: 14 | flutter_test: 15 | sdk: flutter 16 | 17 | # For information on the generic Dart part of this file, see the 18 | # following page: https://dart.dev/tools/pub/pubspec 19 | 20 | # The following section is specific to Flutter. 21 | flutter: 22 | # This section identifies this Flutter project as a plugin project. 23 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily 24 | # be modified. They are used by the tooling to maintain consistency when 25 | # adding or updating assets for this project. 26 | plugin: 27 | platforms: 28 | android: 29 | package: com.fluttercandies.flutter_qweather 30 | pluginClass: FlutterQweatherPlugin 31 | ios: 32 | pluginClass: FlutterQweatherPlugin 33 | 34 | # To add assets to your plugin package, add an assets section, like this: 35 | # assets: 36 | # - images/a_dot_burr.jpeg 37 | # - images/a_dot_ham.jpeg 38 | # 39 | # For details regarding assets in packages, see 40 | # https://flutter.dev/assets-and-images/#from-packages 41 | # 42 | # An image asset can refer to one or more resolution-specific "variants", see 43 | # https://flutter.dev/assets-and-images/#resolution-aware. 44 | 45 | # To add custom fonts to your plugin package, add a fonts section here, 46 | # in this "flutter" section. Each entry in this list should have a 47 | # "family" key with the font family name, and a "fonts" key with a 48 | # list giving the asset and other descriptors for the font. For 49 | # example: 50 | # fonts: 51 | # - family: Schyler 52 | # fonts: 53 | # - asset: fonts/Schyler-Regular.ttf 54 | # - asset: fonts/Schyler-Italic.ttf 55 | # style: italic 56 | # - family: Trajan Pro 57 | # fonts: 58 | # - asset: fonts/TrajanPro.ttf 59 | # - asset: fonts/TrajanPro_Bold.ttf 60 | # weight: 700 61 | # 62 | # For details regarding fonts in packages, see 63 | # https://flutter.dev/custom-fonts/#from-packages 64 | -------------------------------------------------------------------------------- /test/flutter_qweather_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:flutter_qweather/flutter_qweather.dart'; 4 | 5 | void main() { 6 | const MethodChannel channel = MethodChannel('flutter_qweather'); 7 | 8 | TestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | setUp(() { 11 | channel.setMockMethodCallHandler((MethodCall methodCall) async { 12 | return '42'; 13 | }); 14 | }); 15 | 16 | tearDown(() { 17 | channel.setMockMethodCallHandler(null); 18 | }); 19 | 20 | test('getPlatformVersion', () async { 21 | expect(await FlutterQweather.instance.platformVersion, '42'); 22 | }); 23 | } 24 | --------------------------------------------------------------------------------