This is a weird problem, when using an emulator, the data from OpenWeatherMap is displayed on the screen as it should. It has no errors with fetching data. But, when I create an apk from Build -> Flutter -> Build Apk (using Idea), it doesn't fetch data for some reason. And normally, it displays null.
Weather Controller:
class WeatherController extends GetxController {
final WeatherService _weatherService = Get.find();
Rxn<WeatherData> weatherData = Rxn();
String get address =>
"${weatherData.value?.name}, ${weatherData.value?.country}";
String get temperature => "${weatherData.value?.temp}";
String get icon => "${weatherData.value?.icon}";
@override
void onInit() async {
super.onInit();
getWeather();
}
Future<void> getWeather() async {
final response = await _weatherService.getWeatherForLocation();
if (response != null) {
weatherData.value = response;
} else {
Get.defaultDialog(
middleText: 'Error fetching weather data from API',
textConfirm: 'OK',
confirmTextColor: Colors.white,
onConfirm: () {
Get.back();
});
}
}
}
Weather Service:
class WeatherService {
final apiKey = "7e23369c183254302bda0471cc3f848c";
final LocationController _locationController = Get.find();
Future<WeatherData?> getWeatherForLocation() async {
WeatherData? weatherData;
var params = {
"lat": _locationController.currentLocation.value?.latitude.toString(),
"lon": _locationController.currentLocation.value?.longitude.toString(),
"appId": apiKey,
};
var url = Uri.http('api.openweathermap.org', '/data/2.5/weather', params);
final response = await get(url);
if (response.statusCode == HttpStatus.ok) {
var jsonResponse = jsonDecode(response.body) as Map<String, dynamic>;
weatherData = WeatherData.fromJson(jsonResponse);
print("Request successful: $jsonResponse");
return weatherData;
} else {
print("Request failed with status: ${response.statusCode}");
return weatherData;
}
}
}
Weather Model:
class WeatherData {
int? temp;
String? icon;
String? name;
String? country;
WeatherData({
this.temp,
this.icon,
this.name,
this.country,
});
WeatherData.fromJson(dynamic json) {
var tempInKelvin = json["main"]["temp"];
temp = (tempInKelvin - 273.15).round();
icon = json["weather"][0]["icon"];
name = json["name"];
country=json["sys"]["country"];
}
}
Update:
the problem is that openweathermap api needs location that I'm getting from Geolocator package, and that takes time to happend. It works on a simulator because location is always the same (default), but on the real phone, where geolocator must be used, it isn't as fast, so that's why I'm getting null as a response (cause my latitude and longitude are null when I'm passing them to Weather Service).
It doesn't load on first render.
CodePudding user response:
This could be because your release app might be missing internet permissions.
Go to android > app > src > main >
Add the following line in your AndroidManifest.xml file before the <application>
section:
<uses-permission android:name="android.permission.INTERNET" />
CodePudding user response:
had to check if location is null in home controller (for home screen), and then send location again
class HomeController extends GetxController {
RxList<NearbyMountainDto> nearbyMountainsObx = RxList.empty();
RxList<NearbyMountainDto> popularMountainsObx = RxList.empty();
final LocationController _locationController=Get.find();
final WeatherController _weatherController=Get.find();
@override
void onInit() {
if(_locationController.currentLocation.value == null) {
_awaitLocation().then((value) {
if(value) {
_weatherController.getWeather();
_weatherController.address;
_weatherController.temperature;
_weatherController.icon;
}
});
} else {
_weatherController.getWeather();
_weatherController.address;
_weatherController.temperature;
_weatherController.icon;
}
super.onInit();
}
Future<bool> _awaitLocation() {
return _locationController.setInitialLocation();
}
}