Reputation: 402
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
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
Reputation: 33
You have tried with onResume() method?
You can use it and when the view is visible wi
Upvotes: 0
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