I am new to app development and i've run into a problem. Before my weather app only had one activity with search and results on the same layout file.
Now i have divided it into a StartActivity with just a EditText to enter the city name and a search button, and in the results activity i've put all the result textviews. Now to the problem at hand:
When i press the search button all it does is switch to my result activity but it doesn't make the API call or parse the JSON data and fill the textviews.
I am not using ActionSearch atm i'm just manipulating the String in the API call which represents the city. Here is my StartActivity class:
public class StartActivity extends AppCompatActivity {
static final int REQ = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
configureSearchButton();
}
private void configureSearchButton() {
Button searchButt = (Button) findViewById(R.id.searchButtonStart);
final Intent intent = new Intent(StartActivity.this, ResultActivity.class);
searchButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(intent, REQ);
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQ) {
if (resultCode == RESULT_OK) {
String updatedAt = data.getStringExtra("updatedAtKey");
String tz = data.getStringExtra("tzKey");
String updatedAtText = data.getStringExtra("updatedAtTextKey");
String tzText = data.getStringExtra("tzTextKey");
String temp = data.getStringExtra("tempKey");
String pressure = data.getStringExtra("pressureKey");
String humidity = data.getStringExtra("humidityKey");
String tempMin = data.getStringExtra("tempMinKey");
String tempMax = data.getStringExtra("tempMaxKey");
String windSpeed = data.getStringExtra("windSpeedKey");
String weatherTypeDescription = data.getStringExtra("weatherTypeDescriptionKey");
String cityCountryAddress = data.getStringExtra("cityCountryAddressKey");;
String sunrise = data.getStringExtra("sunriseKey");
String sunset = data.getStringExtra("sunsetKey");
}
}
}
Heres my code from ResultActivity:
public class ResultActivity extends AppCompatActivity {
private static final String API_KEY = "blabla";
TextView cityText, weatherUpdateText, weatherTypeText, temperatureText, minTempText, maxTempText, sunriseText, sunsetText, windSpeedText,
pressureText, humidityPrcntText, timezoneText;
Button getLoc;
private LocationManager locationManager;
private LocationListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cityText = findViewById(R.id.address);
weatherUpdateText = findViewById(R.id.weatherUpdateAt);
weatherTypeText = findViewById(R.id.weatherType);
temperatureText = findViewById(R.id.temperature);
minTempText = findViewById(R.id.minTemp);
maxTempText = findViewById(R.id.maxTemp);
sunriseText = findViewById(R.id.sunrise);
sunsetText = findViewById(R.id.sunset);
windSpeedText = findViewById(R.id.windSpeed);
pressureText = findViewById(R.id.pressure);
humidityPrcntText = findViewById(R.id.humidity);
timezoneText = findViewById(R.id.tz);
final EditText searchEdit = (EditText) findViewById(R.id.cityEdtText);
final Button submit = (Button) findViewById(R.id.searchButton);
submit.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
new WeatherTask().execute();
}
});
searchEdit.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
submit.performClick();
}
return false;
}
});
final SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
cityText.setText("CITY,COUNTRY");
weatherUpdateText.setText("-,-PM");
weatherTypeText.setText("-");
temperatureText.setText("-°C");
minTempText.setText("Min Temp");
maxTempText.setText("Max Temp");
sunriseText.setText("-");
sunsetText.setText("-");
windSpeedText.setText("-");
pressureText.setText("-");
humidityPrcntText.setText("-");
timezoneText.setText("-");
new WeatherTask().execute();
pullToRefresh.setRefreshing(false);
}
});
getLoc = findViewById(R.id.getLocation);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
listener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
searchEdit.setText(String.valueOf(location.getLongitude()));
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
//
}
@Override
public void onProviderEnabled(String s) {
//
}
@Override
public void onProviderDisabled(String s) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(i);
}
};
getLoc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
configure_button();
}
});
configureBackButton();
Intent data = new Intent();
data.putExtra("updatedAtKey","updatedAt");
data.putExtra("tzKey","tz");
data.putExtra("updatedAtTextKey","updatedAtText");
data.putExtra("tzTextKey", "tzText");
data.putExtra("tempKey", "temp");
data.putExtra("pressureKey", "pressure");
data.putExtra("humidityKey", "humidity");
data.putExtra("tempMinKey", "tempMin");
data.putExtra("tempMaxKey", "tempMax");
data.putExtra("windSpeedKey", "windSpeed");
data.putExtra("weatherTypeDescriptionKey", "weatherTypeDescription");
data.putExtra("cityCountryAddressKey", "cityCountryAddress");
data.putExtra("sunriseKey", "sunrise");
data.putExtra("sunsetKey", "sunset");
setResult(RESULT_OK,data);
finish();
}
private void configureBackButton() {
Button back = (Button) findViewById(R.id.goBack);
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 10:
configure_button();
break;
default:
break;
}
}
void configure_button() {
// first check for permissions
if (ActivityCompat.checkSelfPermission(ResultActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(ResultActivity.this,
ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
request_permission();
}
} else {
// permission has been granted
locationManager.requestLocationUpdates("gps", 5000, 0, listener);
}
}
private void request_permission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(ResultActivity.this,
ACCESS_COARSE_LOCATION)) {
Snackbar.make(findViewById(R.id.mainContainer), "Location permission is needed because ...",
Snackbar.LENGTH_LONG)
.setAction("retry", new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 10);
}
}
})
.show();
} else {
// permission has not been granted yet. Request it directly.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 10);
}
}
}
//FIXA
class GeocoderHandler extends Handler {
final EditText searchEdit = (EditText) findViewById(R.id.cityEdtText);
@Override
public void handleMessage(Message message) {
String result;
switch (message.what) {
case 1:
Bundle bundle = message.getData();
result = bundle.getString("address");
break;
default:
result = null;
}
// replace by what you need to do
searchEdit.setText(result);
}
}
class WeatherTask extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
super.onPreExecute();
findViewById(R.id.loadingCircle).setVisibility(View.VISIBLE);
findViewById(R.id.mainContainer).setVisibility(View.GONE);
findViewById(R.id.errorTxt).setVisibility(View.GONE);
}
protected String doInBackground(String... args) {
EditText search = findViewById(R.id.cityEdtText);
String CITY_COUNTRY = "";
CITY_COUNTRY = search.getText().toString();
if (CITY_COUNTRY.matches("")) {
runOnUiThread(new Runnable() {
//Om inputen är tom dyker ett Toast Message upp som förklarar att inputen inte får vara tom och ber användaren att försöka igen.
public void run() {
Toast toast = Toast.makeText(getApplicationContext(), "Your input cannot be empty, enter a city name.", Toast.LENGTH_LONG);
toast.show();
}
});
}
String URL = "https://api.openweathermap.org/data/2.5/weather?q=" + CITY_COUNTRY + "&units=metric&appid=" + API_KEY;
String result = HttpGetRequest.executeHttpGetRequest(URL);
return result;
}
protected void onPostExecute(String result) {
try {
JSONObject jsonObj = new JSONObject(result);
JSONObject main = jsonObj.getJSONObject("main");
JSONObject sys = jsonObj.getJSONObject("sys");
JSONObject wind = jsonObj.getJSONObject("wind");
JSONObject weather = jsonObj.getJSONArray("weather").getJSONObject(0);
Long updatedAt = jsonObj.getLong("dt");
Long tz = jsonObj.getLong("timezone");
String updatedAtText = "Weather updated at: " + new SimpleDateFormat("dd/MM/yyy hh:mm a", Locale.ENGLISH)
.format(new Date(updatedAt * 1000));
String tzText = String.valueOf(tz);
String temp = main.getString("temp") + "°C";
String pressure = main.getString("pressure") + " hpa";
String humidity = main.getString("humidity") + " %";
String tempMin = "Min Temp \n" + " " + main.getString("temp_min") + "°C";
String tempMax = "Max Temp \n" + " " + main.getString("temp_max") + "°C";
String windSpeed = wind.getString("speed") + " m/s";
String weatherTypeDescription = weather.getString("description");
String cityCountryAddress = jsonObj.getString("name") + ", " + sys.getString("country");
Long sunrise = sys.getLong("sunrise");
Long sunset = sys.getLong("sunset");
cityText.setText(cityCountryAddress);
weatherUpdateText.setText(updatedAtText);
weatherTypeText.setText(weatherTypeDescription.toUpperCase());
temperatureText.setText(temp);
minTempText.setText(tempMin);
maxTempText.setText(tempMax);
sunriseText.setText(new SimpleDateFormat("hh:mm a", Locale.ENGLISH).format(new Date(sunrise * 1000)));
sunsetText.setText(new SimpleDateFormat("hh:mm a", Locale.ENGLISH).format(new Date(sunset * 1000)));
windSpeedText.setText(windSpeed);
pressureText.setText(pressure);
humidityPrcntText.setText(humidity);
timezoneText.setText(tzText);
findViewById(R.id.loadingCircle).setVisibility(View.GONE);
findViewById(R.id.mainContainer).setVisibility(View.VISIBLE);
} catch (JSONException e) {
findViewById(R.id.loadingCircle).setVisibility(View.GONE);
findViewById(R.id.errorTxt).setVisibility(View.VISIBLE);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(getApplicationContext(), ResultActivity.class);
startActivity(intent);
}
}, 5000);
}
}
}
}
Please read https://developer.android.com/training/basics/intents/result and Android: how to make an activity return results to the activity which calls it?
The basic idea is that you need to use
startActivityForResult()to start your next activity, then callsetResult()inside that activity, andfinish()when you think is necessary. Then you need to overrideonActivityResult()in your main activity.