Chandler Davis
Chandler Davis

Reputation: 402

How to update weather with onCreate()?

I've been working on a weather app, and I know it's not perfect (I'm just starting out with android development), but I'm not sure how to update the weather info on every startup. I tried to keep everything in the onCreate() method, but it just "sticks" on the location and conditions that I used when I first started.

I have been able to work around this with a button that gets the new location and weather conditions when it is pressed, but that's not very intuitive. I'm wondering how I can get new conditions on app startup. Might it involve calling onRestart()?

Here's my only activity in the app:

package com.photonfighterlabs.dropweather;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.ftoslab.openweatherretrieverz.CurrentWeatherInfo;
import com.ftoslab.openweatherretrieverz.OpenWeatherRetrieverZ;
import com.ftoslab.openweatherretrieverz.WeatherCallback;
import com.ftoslab.openweatherretrieverz.WeatherUnitConverter;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class WeatherActivity extends Activity {

    private double lat;
    private double lng;

    private String temp;
    private String icon;

    private TextView tempTextView;
    private TextView cityTextView;
    private TextView conditionsTextView;

    private int LOCATION_PERMISSION_ID = 1001;

    CurrentWeatherInfo currentWeatherInfoF;

    private String city;
    private List<Address> addresses;

    private FusedLocationProviderClient mFusedLocationClient;

    OpenWeatherRetrieverZ retriever;

    ImageView image;

    Geocoder geocoder;

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_weather);

        retriever = new OpenWeatherRetrieverZ(API_KEY); // hidden for obvious reasons, but working


        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        geocoder = new Geocoder(this, Locale.getDefault());

        tempTextView = (TextView) findViewById(R.id.temp_text_view);
        cityTextView = (TextView) findViewById(R.id.city_text_view);
        conditionsTextView = (TextView) findViewById(R.id.conditions_text_view);

        image = (ImageView) findViewById(R.id.conditions_image);






        if (ContextCompat.checkSelfPermission(WeatherActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(WeatherActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_ID);
            return;
        }

        mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location != null)
                            lat = location.getLatitude();
                        lng = location.getLongitude();

                        try {
                            addresses = geocoder.getFromLocation(lat, lng, 1);

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        if (!addresses.isEmpty()) {
                            city = addresses.get(0).getLocality();
                            cityTextView.setText("Current Weather - " + city);
                            Log.d("City", city);
                        }

                        Log.d("LAT", String.valueOf(lat));
                        Log.d("LNG", String.valueOf(lng));
                    }
                });

        retriever.updateCurrentWeatherInfo(lat, lng, new WeatherCallback() {
            @Override
            public void onReceiveWeatherInfo(CurrentWeatherInfo currentWeatherInfo) {
                currentWeatherInfoF = WeatherUnitConverter.convertToImperial(currentWeatherInfo);

            }

            @Override
            public void onFailure(String error) {
                Toast.makeText(WeatherActivity.this, error, Toast.LENGTH_SHORT).show();
            }
        });

    }

    public void onRetrieveButtonClick(View view) {

        mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location != null)
                            lat = location.getLatitude();
                        lng = location.getLongitude();

                        try {
                            addresses = geocoder.getFromLocation(lat, lng, 1);

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        if (!addresses.isEmpty()) {
                            city = addresses.get(0).getLocality();
                            cityTextView.setText("Current Weather - " + city);
                            Log.d("City", city);
                        }

                        Log.d("LAT", String.valueOf(lat));
                        Log.d("LNG", String.valueOf(lng));
                    }
                });


        retriever.updateCurrentWeatherInfo(lat, lng, new WeatherCallback() {
            @Override
            public void onReceiveWeatherInfo(CurrentWeatherInfo currentWeatherInfo) {
                currentWeatherInfoF = WeatherUnitConverter.convertToImperial(currentWeatherInfo);

            }

            @Override
            public void onFailure(String error) {
                Toast.makeText(WeatherActivity.this, error, Toast.LENGTH_SHORT).show();
            }
        });

        temp = currentWeatherInfoF.getCurrentTemperature();

        Log.d("TMP : ", String.valueOf(temp));

        tempTextView.setText( String.valueOf((int) Double.parseDouble(temp)) + (char) 0x00B0);
        conditionsTextView.setText(currentWeatherInfoF.getWeatherDescriptionLong());


        String iconURL = currentWeatherInfoF.getWeatherIconLink().toString();

        Pattern p = Pattern.compile("\\d\\w(n|d)");
        Matcher m = p.matcher(iconURL);


        if (m.find()) {
            icon = m.group();
            Log.d("ICON", icon);
            String iconName = "r" + icon;
            image.setImageResource(getResources().getIdentifier(iconName, "drawable", getPackageName()));
            Log.d("NAME", iconName);
        }

    }




}

Upvotes: 0

Views: 183

Answers (3)

MRC
MRC

Reputation: 56

Awareness offers a snapshot-API for obtaining the weather via getWeather() API method at the device location without managing location access or integrating with APIs that query weather from server on-demand.

Illustrative code-snippet:

Awareness.SnapshotApi.getWeather(mGoogleApiClient)
  .setResultCallback(new ResultCallback<WeatherResult>() {
    @Override
    public void onResult(@NonNull WeatherResult weatherResult) {
      if (!weatherResult.getStatus().isSuccess()) {
        Log.e(TAG, "Could not get weather.");
        return;
       }
       Weather weather = weatherResult.getWeather();
       Log.i(TAG, "Weather: " + weather);
    }
  });

Please refer here for description of the Weather class whose instance is returned by the API.

The advantage of using this is that you can massively simplify your code, avoid having to manage location requests and call the API as often as needed (I believe it has a cache to avoid too many network requests that are battery draining).

Upvotes: 0

Amauri Guzm&#225;n
Amauri Guzm&#225;n

Reputation: 33

You have tried with onResume() method?

You can use it and when the view is visible wi

Upvotes: 0

Henry
Henry

Reputation: 43738

getLastLocation() and updateCurrentWeatherInfo(...) are both asynchronous operations. You start them both at the same time which means that updateCurrentWeatherInfo will most likely run before the position is available.

You must start it only after you have got the position, for example from the onSuccess listener.

Upvotes: 1

Related Questions