根据图标播放天气声音
Play weather sounds based on it's icons
我刚刚完成应用的天气图标实现,现在我正尝试根据应用显示的图标在应用上播放天气声音。经过长时间的深入研究,令我震惊的是,在任何平台上都没有人问过类似的问题。
我对 java 词典的了解非常狭窄,即使花时间阅读和研究他们的示例,我仍然很难理解文档。即我找到了一份我认为符合我在这里要实现的目标的文档 https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
说明
V put(K key,
V value)
将指定值与此映射中的指定键相关联。在那种情况下,我想使用 K 作为图标,使用 V 作为我的声音,但我不知道如何应用它,所以我寻找示例并看到了这个 https://study.com/academy/lesson/the-java-dictionary-class-definition-example.html 它提供的示例仍然不足以提供帮助我通过了,我知道如果我自己尝试解决它会把它搞砸,所以我决定在这里提出这个问题,看看是否有人可以提供帮助,我将非常感激。
按照 API 说明,我正在使用 https://openweathermap.org/weather-conditions。
有9种主要天气状况。
这些是我尝试根据图标播放声音的目标:
- 如果城市显示 clear_sky 图标,播放 clear_sky_sound
- 否则,如果显示few_clouds图标,播放few_clouds_sound
- 否则,如果显示scattered_clouds图标,播放scattered_clouds_sound
- 否则,如果显示broken_clouds,播放broken_clouds_sound
- 否则,如果显示shower_rain图标,播放shower_rain_sound
- 否则,如果显示下雨图标,播放rain_sound
- 否则,如果显示雷雨图标,播放thunderstorm_sound
- 否则,如果显示雪花图标,播放snow_sound
- 否则,如果显示雾状图标,播放mist_sound。
这是我的片段代码:
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);
}
}
编辑:
DennisVA 提供了一个我可以遵循的示例(我尝试了他的第二个建议),但当我尝试时,我遇到了一些错误,我在他的评论部分使用 link 分享了这些错误。
我决定悬赏这个 post 以引起更多关注,这样我就可以被更多地引导到正确的方向。
我会创建一个包装器,以便更轻松地向您展示内容 UI
例如:
public class Weather{
@DrawableRes
private int icon; //Resource id of the drawable
private String sound; //Name or path the the sound file
public Weather(WeatherPojo pojo){
switch(pojo.icon){
case "01d":
case "01n":
this.icon = R.drawable.sun;
this.sound = ...
}
}
}
这个 class 也可以包含一个 play(MediaPlayer player)
方法
我注意到的其他一些事情:
- 避免对字符串进行硬编码
- 您可能想看看视图绑定以减少大量丑陋的
rootView.findViewById
调用 (https://developer.android.com/topic/libraries/view-binding)
编辑:
另一个可能更好的选择是创建某种 WeatherFactory class 或生成抽象天气 class 的子class 的解析器,
并让摘要 class 包含播放媒体文件的代码:
public abstract class Weather{
@DrawableRes
private int iconResId;
@RawRes
private int soundResId;
protected Weather(@DrawableRes int iconResId, @RawRes int soundResId){
this.iconResId = iconResId;
this.soundResId = soundResId
}
public void playSound(MediaPlayer mediaPlayer, Context context){
String assetFileDescriptor = context.resources.openRawResourceFd(soundResId);
if(assetFileDescriptor == null)
return;
mediaPlayer.reset();
mediaPlayer.setDataSource(assetFileDescriptor.fileDescriptor,
assetFileDescriptor.startOffset, assetFileDescriptor.declaredLength);
mediaPlayer.prepareAsync();
}
}
public class Snow extends Weather{
public Snow(){
super(R.drawable.snow, R.raw.snow)
}
}
现在您可以在您的片段或 viewModel 中调用 snow.playSound()
并在抽象中生成 getter 和 setter class 以获取可绘制对象并显示它。
其他变量例如描述也可以注入到子class的构造函数中,或者你可以为不同类型的雪(LightSnow,HeavySnow)扩展子classes , ...)
注意:我还没有测试过这段代码的任何部分,所以它可能需要在这里和那里进行一些更改
MediaPlayer firstSound, secondSound, thirdSound, fourthSound, fifthSound, sixthSound, seventhSound, eightSound, ninethSound;
这里您创建了 9 个 MediaPlayer
对象,并且从它们的名称和数量来看,它们与图标的数量完全相同;我意识到每个人都会处理某个图标的声音。
不过,您只能使用一个 MediaPlaer
对象来播放您拥有的 9 种声音中的任何一种。把它想象成你的操作系统媒体播放器,你有一个单一的媒体播放器应用程序,你可以一次拖放任何媒体文件,并随时更改它,而无需更改应用程序本身。
只要您想一次播放一个媒体文件,这就有效;但是,如果您想同时播放多个声音,您可能需要多个 MediaPlayer
对象。
所以,在你的情况下,你一次只有一个是否条件,所以我假设你想一次播放一个文件;因此你一次只有一个图标(由于 switch
语句),因此你需要将上面提到的代码片段更改为单个变量:
MediaPlayer mediaPlayer;
My knowledge of java dictionary is quite narrow and I find it hard to understand documentation
一个字典(或者java准确的说是一个Map),把它想象成一个phone目录:你知道人名(Key),需要得到对应的phone 数字(值);此示例中的不同之处在于,在 phone 目录中,每个 key/person 只有一个唯一值;但在 java Map
中,您可以有重复的值(即多个 key/person 可以拥有相同的 value/phone 号码)。
V put(K key,
V value)
此外,在 java 中,键和值几乎可以是任何东西,这可以通过 generics.
的 (K & V) 符号来表示
I thought of using K as Icon and V as my sound but I didn't know how to apply it
在共享的简单示例中,我真的不认为您需要地图;由于声音资源与相应的图标可绘制资源高度耦合,因此您可以像处理可绘制资源一样处理声音原始文件。
因此,无论何时更改当前可绘制对象(即在 switch 语句中),您还需要在 switch
语句中更改当前声音,假设它们与可绘制对象具有相同的名称:
MediaPlayer mediaPlayer; // single MediaPlayer object
int drawableResource = -1; // here define default icon for example R.drawable.default_weather_icon
int soundResource = -1; // Default sound is nothing
String icon = data.getWeather().get(0).getIcon();
switch (icon) {
case "01d":
case "01n":
drawableResource = R.drawable.sun;
soundResource = R.raw.sun;
break;
case "02d":
case "021n":
drawableResource = R.drawable.few_clouds;
soundResource = R.raw.few_clouds;
break;
case "03d":
case "03n":
drawableResource = R.drawable.scattered_clouds;
soundResource = R.raw.scattered_clouds;
break;
case "04d":
case "04n":
drawableResource = R.drawable.broken_clouds;
soundResource = R.raw.broken_clouds;
break;
case "09d":
case "09n":
drawableResource = R.drawable.shower_rain;
soundResource = R.raw.shower_rain;
break;
case "10d":
case "10n":
drawableResource = R.drawable.small_rain;
soundResource = R.raw.small_rain;
break;
case "11d":
case "11n":
drawableResource = R.drawable.thunderstorm;
soundResource = R.raw.thunderstorm;
break;
case "13d":
case "13n":
drawableResource = R.drawable.snow;
soundResource = R.raw.snow;
break;
case "50d":
case "50n":
drawableResource = R.drawable.mist;
soundResource = R.raw.mist;
break;
}
if (drawableResource != -1)
current_icon.setImageResource(drawableResource);
if (soundResource != -1) {
prepareMediaPlayer(soundResource);
}
// In FirstFragment:
private void prepareMediaPlayer(int resource) {
// add track file
mMediaPlayer = MediaPlayer.create(requireActivity(), resource);
// listening to when the media file finishes playing so that we can release the resources
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (mMediaPlayer != null) {
mMediaPlayer.release();
}
}
});
}
并且无论什么时候你想播放声音,只要调用mMediaPlayer.start()
,但要确保提前调用prepareMediaPlayer()
。
提示:如果你想使用地图,我建议你为天气创建一个 POJO/Data class,这样我们可能会有一个地图。
我刚刚完成应用的天气图标实现,现在我正尝试根据应用显示的图标在应用上播放天气声音。经过长时间的深入研究,令我震惊的是,在任何平台上都没有人问过类似的问题。
我对 java 词典的了解非常狭窄,即使花时间阅读和研究他们的示例,我仍然很难理解文档。即我找到了一份我认为符合我在这里要实现的目标的文档 https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
说明
V put(K key,
V value)
将指定值与此映射中的指定键相关联。在那种情况下,我想使用 K 作为图标,使用 V 作为我的声音,但我不知道如何应用它,所以我寻找示例并看到了这个 https://study.com/academy/lesson/the-java-dictionary-class-definition-example.html 它提供的示例仍然不足以提供帮助我通过了,我知道如果我自己尝试解决它会把它搞砸,所以我决定在这里提出这个问题,看看是否有人可以提供帮助,我将非常感激。
按照 API 说明,我正在使用 https://openweathermap.org/weather-conditions。 有9种主要天气状况。
这些是我尝试根据图标播放声音的目标:
- 如果城市显示 clear_sky 图标,播放 clear_sky_sound
- 否则,如果显示few_clouds图标,播放few_clouds_sound
- 否则,如果显示scattered_clouds图标,播放scattered_clouds_sound
- 否则,如果显示broken_clouds,播放broken_clouds_sound
- 否则,如果显示shower_rain图标,播放shower_rain_sound
- 否则,如果显示下雨图标,播放rain_sound
- 否则,如果显示雷雨图标,播放thunderstorm_sound
- 否则,如果显示雪花图标,播放snow_sound
- 否则,如果显示雾状图标,播放mist_sound。
这是我的片段代码:
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);
}
}
编辑:
DennisVA 提供了一个我可以遵循的示例(我尝试了他的第二个建议),但当我尝试时,我遇到了一些错误,我在他的评论部分使用 link 分享了这些错误。 我决定悬赏这个 post 以引起更多关注,这样我就可以被更多地引导到正确的方向。
我会创建一个包装器,以便更轻松地向您展示内容 UI
例如:
public class Weather{
@DrawableRes
private int icon; //Resource id of the drawable
private String sound; //Name or path the the sound file
public Weather(WeatherPojo pojo){
switch(pojo.icon){
case "01d":
case "01n":
this.icon = R.drawable.sun;
this.sound = ...
}
}
}
这个 class 也可以包含一个 play(MediaPlayer player)
方法
我注意到的其他一些事情:
- 避免对字符串进行硬编码
- 您可能想看看视图绑定以减少大量丑陋的
rootView.findViewById
调用 (https://developer.android.com/topic/libraries/view-binding)
编辑:
另一个可能更好的选择是创建某种 WeatherFactory class 或生成抽象天气 class 的子class 的解析器, 并让摘要 class 包含播放媒体文件的代码:
public abstract class Weather{
@DrawableRes
private int iconResId;
@RawRes
private int soundResId;
protected Weather(@DrawableRes int iconResId, @RawRes int soundResId){
this.iconResId = iconResId;
this.soundResId = soundResId
}
public void playSound(MediaPlayer mediaPlayer, Context context){
String assetFileDescriptor = context.resources.openRawResourceFd(soundResId);
if(assetFileDescriptor == null)
return;
mediaPlayer.reset();
mediaPlayer.setDataSource(assetFileDescriptor.fileDescriptor,
assetFileDescriptor.startOffset, assetFileDescriptor.declaredLength);
mediaPlayer.prepareAsync();
}
}
public class Snow extends Weather{
public Snow(){
super(R.drawable.snow, R.raw.snow)
}
}
现在您可以在您的片段或 viewModel 中调用 snow.playSound()
并在抽象中生成 getter 和 setter class 以获取可绘制对象并显示它。
其他变量例如描述也可以注入到子class的构造函数中,或者你可以为不同类型的雪(LightSnow,HeavySnow)扩展子classes , ...)
注意:我还没有测试过这段代码的任何部分,所以它可能需要在这里和那里进行一些更改
MediaPlayer firstSound, secondSound, thirdSound, fourthSound, fifthSound, sixthSound, seventhSound, eightSound, ninethSound;
这里您创建了 9 个 MediaPlayer
对象,并且从它们的名称和数量来看,它们与图标的数量完全相同;我意识到每个人都会处理某个图标的声音。
不过,您只能使用一个 MediaPlaer
对象来播放您拥有的 9 种声音中的任何一种。把它想象成你的操作系统媒体播放器,你有一个单一的媒体播放器应用程序,你可以一次拖放任何媒体文件,并随时更改它,而无需更改应用程序本身。
只要您想一次播放一个媒体文件,这就有效;但是,如果您想同时播放多个声音,您可能需要多个 MediaPlayer
对象。
所以,在你的情况下,你一次只有一个是否条件,所以我假设你想一次播放一个文件;因此你一次只有一个图标(由于 switch
语句),因此你需要将上面提到的代码片段更改为单个变量:
MediaPlayer mediaPlayer;
My knowledge of java dictionary is quite narrow and I find it hard to understand documentation
一个字典(或者java准确的说是一个Map),把它想象成一个phone目录:你知道人名(Key),需要得到对应的phone 数字(值);此示例中的不同之处在于,在 phone 目录中,每个 key/person 只有一个唯一值;但在 java Map
中,您可以有重复的值(即多个 key/person 可以拥有相同的 value/phone 号码)。
V put(K key, V value)
此外,在 java 中,键和值几乎可以是任何东西,这可以通过 generics.
的 (K & V) 符号来表示I thought of using K as Icon and V as my sound but I didn't know how to apply it
在共享的简单示例中,我真的不认为您需要地图;由于声音资源与相应的图标可绘制资源高度耦合,因此您可以像处理可绘制资源一样处理声音原始文件。
因此,无论何时更改当前可绘制对象(即在 switch 语句中),您还需要在 switch
语句中更改当前声音,假设它们与可绘制对象具有相同的名称:
MediaPlayer mediaPlayer; // single MediaPlayer object
int drawableResource = -1; // here define default icon for example R.drawable.default_weather_icon
int soundResource = -1; // Default sound is nothing
String icon = data.getWeather().get(0).getIcon();
switch (icon) {
case "01d":
case "01n":
drawableResource = R.drawable.sun;
soundResource = R.raw.sun;
break;
case "02d":
case "021n":
drawableResource = R.drawable.few_clouds;
soundResource = R.raw.few_clouds;
break;
case "03d":
case "03n":
drawableResource = R.drawable.scattered_clouds;
soundResource = R.raw.scattered_clouds;
break;
case "04d":
case "04n":
drawableResource = R.drawable.broken_clouds;
soundResource = R.raw.broken_clouds;
break;
case "09d":
case "09n":
drawableResource = R.drawable.shower_rain;
soundResource = R.raw.shower_rain;
break;
case "10d":
case "10n":
drawableResource = R.drawable.small_rain;
soundResource = R.raw.small_rain;
break;
case "11d":
case "11n":
drawableResource = R.drawable.thunderstorm;
soundResource = R.raw.thunderstorm;
break;
case "13d":
case "13n":
drawableResource = R.drawable.snow;
soundResource = R.raw.snow;
break;
case "50d":
case "50n":
drawableResource = R.drawable.mist;
soundResource = R.raw.mist;
break;
}
if (drawableResource != -1)
current_icon.setImageResource(drawableResource);
if (soundResource != -1) {
prepareMediaPlayer(soundResource);
}
// In FirstFragment:
private void prepareMediaPlayer(int resource) {
// add track file
mMediaPlayer = MediaPlayer.create(requireActivity(), resource);
// listening to when the media file finishes playing so that we can release the resources
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (mMediaPlayer != null) {
mMediaPlayer.release();
}
}
});
}
并且无论什么时候你想播放声音,只要调用mMediaPlayer.start()
,但要确保提前调用prepareMediaPlayer()
。
提示:如果你想使用地图,我建议你为天气创建一个 POJO/Data class,这样我们可能会有一个地图。