I've just finished implementing my app's weather icons, now I'm trying to play weather sounds on the app based on the icons the app is displaying. After doing long hours of thorough research, I found out to my shock that no one has ever asked similar questions on any platform.
My knowledge of java dictionary is quite narrow and I find it hard to understand documentation even after taking my time to read and study their samples. i.e I found a doc I believe would correspond with what I am trying to achieve here https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
It explains that
V put(K key,
V value)
Associates the specified value with the specified key in this map. In that case, I thought of using K as Icon and V as my sound but I didn't know how to apply it so I looked for examples and saw this https://study.com/academy/lesson/the-java-dictionary-class-definition-example.html The examples it provided still wasn't enough to help me through and I know I will mess it up if I try to work it out myself, so I decided to come up with this here to see if anyone can help, I'll really appreciate it.
Following the API instructions, I'm using https://openweathermap.org/weather-conditions. There are 9 main weather conditions.
These are my goals in trying to play the sounds based on the icons:
- If the city displays the clear_sky icon, play the clear_sky_sound
- Otherwise, If it displays the few_clouds icon, play the few_clouds_sound
- Otherwise, If it displays the scattered_clouds icon, play the scattered_clouds_sound
- Otherwise, If it displays the broken_clouds, play the broken_clouds_sound
- Otherwise, If it displays the shower_rain icon, play the shower_rain_sound
- Otherwise, If it displays the rain icon, play the rain_sound
- Otherwise, If it displays the thunderstorm icon, play the thunderstorm_sound
- Otherwise, If it displays the snow icon, play the snow_sound
- Otherwise, If it displays the mist icon, play the mist_sound.
Here is my Fragment's code:
public class FirstFragment extends Fragment {
private WeatherDataViewModel viewModel;
MediaPlayer firstSound, secondSound, thirdSound, fourthSound, fifthSound, sixthSound, seventhSound, eightSound, ninethSound;
public FirstFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
// For displaying weather data
final TextView current_temp = rootView.findViewById(R.id.textView10);
final TextView current_output = rootView.findViewById(R.id.textView11);
final TextView rise_time = rootView.findViewById(R.id.textView25);
final TextView set_time = rootView.findViewById(R.id.textView26);
final TextView temp_out = rootView.findViewById(R.id.textView28);
final TextView Press_out = rootView.findViewById(R.id.textView29);
final TextView Humid_out = rootView.findViewById(R.id.textView30);
final TextView Ws_out = rootView.findViewById(R.id.textView33);
final TextView Visi_out = rootView.findViewById(R.id.textView34);
final TextView Cloud_out = rootView.findViewById(R.id.textView35);
final ImageView current_icon = rootView.findViewById(R.id.imageView6);
final SwipeRefreshLayout realSwipe = rootView.findViewById(R.id.real_swipe);
// Get our ViewModel instance
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// And whenever the data changes, refresh the UI
viewModel.getWeatherDataLiveData().observe(getViewLifecycleOwner(), data -> {
realSwipe.setOnRefreshListener(() -> {
// perform you action here for ex. add refresh screen code here
new Handler().postDelayed(() -> {
// this code is for stop refreshing icon, After 1000 ms automatically refresh icon will stop
realSwipe.setRefreshing(false);
}, 1000);
});
int drawableResource = -1; // here define default icon for example R.drawable.default_weather_icon
if (data != null) {
current_temp.setVisibility(View.VISIBLE);
current_temp.setText(data.getMain().getTemp() + " ℃"); // for that you can use strings resource and templates more in https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings
current_output.setVisibility(View.VISIBLE);
current_output.setText(data.getWeather().get(0).getDescription());
rise_time.setVisibility(View.VISIBLE);
rise_time.setText(data.getSys().getSunrise() + " ");
set_time.setVisibility(View.VISIBLE);
set_time.setText(data.getSys().getSunset() + " ");
temp_out.setVisibility(View.VISIBLE);
temp_out.setText(data.getMain().getTemp() + " ℃");
Press_out.setVisibility(View.VISIBLE);
Press_out.setText(data.getMain().getPressure() + " hpa");
Humid_out.setVisibility(View.VISIBLE);
Humid_out.setText(data.getMain().getHumidity() + " %");
Ws_out.setVisibility(View.VISIBLE);
Ws_out.setText(data.getWind().getSpeed() + " Km/h");
Visi_out.setVisibility(View.VISIBLE);
Visi_out.setText(data.getVisibility() + " m");
Cloud_out.setVisibility(View.VISIBLE);
Cloud_out.setText(data.getClouds().getAll() + " %");
// get actual weather.
String icon = data.getWeather().get(0).getIcon();
switch (icon) {
case "01d":
case "01n":
drawableResource = R.drawable.sun;
break;
case "02d":
case "021n":
drawableResource = R.drawable.few_clouds;
break;
case "03d":
case "03n":
drawableResource = R.drawable.scattered_clouds;
break;
case "04d":
case "04n":
drawableResource = R.drawable.broken_clouds;
break;
case "09d":
case "09n":
drawableResource = R.drawable.shower_rain;
break;
case "10d":
case "10n":
drawableResource = R.drawable.small_rain;
break;
case "11d":
case "11n":
drawableResource = R.drawable.thunderstorm;
break;
case "13d":
case "13n":
drawableResource = R.drawable.snow;
break;
case "50d":
case "50n":
drawableResource = R.drawable.mist;
break;
}
if (drawableResource != -1)
current_icon.setImageResource(drawableResource);
} else {
Log.e("TAG", "No City found");
current_temp.setVisibility(View.GONE);
current_output.setVisibility(View.GONE);
rise_time.setVisibility(View.GONE);
set_time.setVisibility(View.GONE);
temp_out.setVisibility(View.GONE);
Press_out.setVisibility(View.GONE);
Humid_out.setVisibility(View.GONE);
Ws_out.setVisibility(View.GONE);
Visi_out.setVisibility(View.GONE);
Cloud_out.setVisibility(View.GONE);
Toast.makeText(requireActivity(), "No City found", Toast.LENGTH_SHORT).show();
}
});
return rootView;
}
public void getWeatherData(String name) {
// The ViewModel controls loading the data, so we just
// tell it what the new name is - this kicks off loading
// the data, which will automatically call through to
// our observe() call when the data load completes
viewModel.setCityName(name);
}
}
EDIT:
DennisVA helped by providing a sample I could follow(i tried his 2nd suggestion) but when I tried it, I got some errors which I shared using a link in his comment section. I decided to bounty this post to draw more attention, so I can be directed more in the right direction.