Flutter天气应用集成定位后跨城市访问API报错求助
解决Flutter天气应用异地运行的网络及位置问题
1. 修复API请求URL的拼写错误
从错误日志可见,你的请求URL存在无效空格:https://api.openweathermap.org/data/2.5/ forecast?q=Islamabad,2.5/后的空格会直接导致主机解析失败。检查代码中URL拼接逻辑,确保格式正确:
String weatherUrl = 'https://api.openweathermap.org/data/2.5/forecast?q=$targetCity&APPID=$yourApiKey';
2. 补全Android网络与位置权限
在android/app/src/main/AndroidManifest.xml中添加必要权限:
<!-- 网络权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
若目标设备是Android 9及以上,在<application>标签内添加以下配置(兼容特殊网络场景):
android:usesCleartextTraffic="true"
3. 完善位置获取的容错逻辑
使用Geolocator获取位置时,必须先请求权限并处理异常,避免因位置获取失败传递无效城市名:
// 检查并请求位置权限 LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { // 权限被拒,引导用户手动输入城市 showDialog( context: context, builder: (ctx) => AlertDialog( title: Text('需开启位置权限'), content: Text('请在设置中开启位置权限以获取当地天气'), actions: [TextButton(onPressed: () => Navigator.pop(ctx), child: Text('知道了'))] ) ); return; } } // 安全获取位置并转换为城市名 try { Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); List<Placemark> placemarks = await placemarkFromCoordinates(position.latitude, position.longitude); String cityName = placemarks.first.locality ?? 'Beijing'; // 设置默认城市兜底 // 发起天气API请求 fetchWeatherData(cityName); } catch (e) { // 位置获取失败,切换到手动输入模式 switchToManualCityInput(); }
4. 其他排查项
- 确认用户设备可正常访问外网(测试能否打开
api.openweathermap.org) - 检查OpenWeatherMap API Key是否有效,未超出请求限额
- 若使用release打包,确保混淆规则未拦截网络请求库,可在
proguard-rules.pro中添加:-keep class okhttp3.** { *; } -keep class retrofit2.** { *; } -keep class com.yourpackage.network.** { *; }
内容的提问来源于stack exchange,提问作者Muhammad Daniyal Khan
相关产品推荐
相关产品推荐

