Home > Software design >  OpenWeatherMap api doesn't work on Flutter apk
OpenWeatherMap api doesn't work on Flutter apk

Time:08-25

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();
  }


}
  • Related