我在Flutter中开发了一个天气预报应用程序,但是当我在手机(Android)上运行它时,它在屏幕上显示错误:
“异常:发生加载天气数据失败”;
在终端中我收到这些错误:
E/ion(18018):ioctl c0044901 失败,代码为 -1:参数无效 D/hw-ProcessState(18018):用于启用单向垃圾邮件检测的 Binder ioctl 失败:
无效参数
代码:
weather_model.dart:
class WeatherModel {
final String temp;
final String city;
final String desc;
WeatherModel.fromMap(Map<String, dynamic> json)
: temp = json['main']['temp'].toString(),
city = json['name'],
desc = json['weather'][0]['description'];
}
call_to_api.dart:
import 'dart:convert';
import 'dart:developer';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import "package:http/http.dart" as http;
import 'package:easyweather/constants/api_key.dart';
import 'package:easyweather/logic/models/weather_model.dart';
class CallToApi {
Future<WeatherModel> callWeatherAPi(bool current, String cityName) async {
try {
Position currentPosition = await getCurrentPosition();
if (current) {
List<Placemark> placemarks = await placemarkFromCoordinates(
currentPosition.latitude, currentPosition.longitude);
Placemark place = placemarks[0];
cityName = place.locality!;
}
var url = Uri.https('api.openweathermap.org', '/data/2.5/weather',
{'q': cityName, "units": "metric", "appid": apiKey});
final http.Response response = await http.get(url);
log(response.body.toString());
if (response.statusCode == 200) {
final Map<String, dynamic> decodedJson = json.decode(response.body);
return WeatherModel.fromMap(decodedJson);
} else {
throw Exception('Failed to load weather data');
}
} catch (e) {
throw Exception('Failed to load weather data');
}
}
Future<Position> getCurrentPosition() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best,
);
}
}
weather_page.dart:
import 'dart:developer';
import 'package:anim_search_bar/anim_search_bar.dart';
import 'package:flutter/material.dart';
import 'package:easyweather/constants/constants.dart';
import 'package:easyweather/logic/models/weather_model.dart';
import 'package:easyweather/logic/services/call_to_api.dart';
class WeatherPage extends StatefulWidget {
const WeatherPage({Key? key}) : super(key: key);
@override
State<WeatherPage> createState() => _WeatherPageState();
}
class _WeatherPageState extends State<WeatherPage> {
Future<WeatherModel> getData(bool isCurrentCity, String cityName) async {
return await CallToApi().callWeatherAPi(isCurrentCity, cityName);
}
TextEditingController textController = TextEditingController(text: "");
Future<WeatherModel>? _myData;
@override
void initState() {
setState(() {
_myData = getData(true, "");
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
body: FutureBuilder(
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If error occured
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error.toString()} occurred',
style: const TextStyle(fontSize: 18),
),
);
// if data has no errors
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data as WeatherModel;
return Container(
padding:
const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment(0.8, 1),
colors: <Color>[
Color.fromARGB(255, 120, 60, 240), // Rosa
Color.fromARGB(255, 30, 144, 255), // Azul Elétrico
Color.fromARGB(255, 0, 255, 255), // Ciano
Color.fromARGB(255, 128, 0, 128), // Roxo
Color.fromARGB(255, 255, 0, 128), // Rosa Choque
],
tileMode: TileMode.mirror,
),
),
width: double.infinity,
height: double.infinity,
child: SafeArea(
child: Column(
children: [
AnimSearchBar(
rtl: true,
width: 400,
color: const Color(0xffffb56b),
textController: textController,
suffixIcon: const Icon(
Icons.search,
color: Colors.black,
size: 26,
),
onSuffixTap: () async {
textController.text == ""
? log("No city entered")
: setState(() {
_myData = getData(false, textController.text);
});
FocusScope.of(context).unfocus();
textController.clear();
},
style: f14RblackLetterSpacing2,
onSubmitted: (String) {},
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
data.city,
style: f24Rwhitebold,
),
height25,
Text(
data.desc,
style: f16PW,
),
height25,
Text(
"${data.temp}°C",
style: f42Rwhitebold,
),
],
),
),
],
),
),
);
}
} else if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return Center(
child: Text("${snapshot.connectionState} occured"),
);
}
return const Center(
child: Text("Server timed out!"),
);
},
future: _myData!,
),
);
}
}
main.dart:
import 'package:flutter/material.dart';
import 'package:easyweather/view/weather_page.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Easy Weather',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.green,
),
home: const WeatherPage(),
);
}
}
显然代码没有任何问题,所有库都已更新为最新版本,并且我正确遵循 openweather 官方网站上报告的 API 使用方式。连 ChatGPT 都帮不了我...
我最近还使用 flutter 创建了一个天气应用程序,并且在 VSCode 调试控制台中遇到了完全相同的错误。 我也尝试过 Gemini 寻求解决方案。
在我搜索了几个小时的解决方案后,我发现我的代码中我的 API 密钥存在问题:)
它的编码末尾有一个空格。因此,请清楚检查您放置 API 密钥的引号 ('') 之间是否有任何不必要的空格。
但是如果您仍然遇到错误,