在我的天氣應用程式上成功實作聲音后,搜索城市時播放效果非常好。但問題是,即使我最小化應用程式,它仍然會重復播放聲音,直到我關閉/退出應用程式。我希望它在我最小化應用程式時暫停,然后從我輸入回來的那一刻停止的地方繼續播放。
所以我嘗試添加以下代碼:
@Override
public void onStop() {
super.onStop();
mMediaPlayer.pause();
}
@Override
public void onDestroy() {
super.onDestroy();
mMediaPlayer.pause();
}
它只會在最小化后完全停止聲音,并且在回傳時不會恢復。它還減慢了應用程式搜索城市的速度。
此外,該應用程式包含 3 個片段(今天、每小時和每日標簽),我通過單擊底部導航瀏覽這些片段。如果我在第一個選項卡上并且正在播放聲音,那么我切換到第二/第三個選項卡,然后移回第一個選項卡,聲音會自動重新啟動它正在播放的任何聲音。我也想解決這個問題。
這是片段的代碼:
public class FirstFragment extends Fragment {
private WeatherDataViewModel viewModel;
private MediaPlayer mMediaPlayer; // Single MediaPlayer object
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
int soundResource = -1; // Default sound is nothing
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;
soundResource = R.raw.clear_sky_sound;
break;
case "02d":
case "021n":
drawableResource = R.drawable.few_clouds;
soundResource = R.raw.clouds_sound;
break;
case "03d":
case "03n":
drawableResource = R.drawable.scattered_clouds;
soundResource = R.raw.clouds_sound;
break;
case "04d":
case "04n":
drawableResource = R.drawable.broken_clouds;
soundResource = R.raw.clouds_sound;
break;
case "09d":
case "09n":
drawableResource = R.drawable.shower_rain;
soundResource = R.raw.shower_rain_sound;
break;
case "10d":
case "10n":
drawableResource = R.drawable.small_rain;
soundResource = R.raw.shower_rain_sound;
break;
case "11d":
case "11n":
drawableResource = R.drawable.thunderstorm;
soundResource = R.raw.thunderstorm_sound;
break;
case "13d":
case "13n":
drawableResource = R.drawable.snow;
soundResource = R.raw.snow_sound;
break;
case "50d":
case "50n":
drawableResource = R.drawable.mist;
soundResource = R.raw.mist_sound;
break;
}
if (drawableResource != -1)
current_icon.setImageResource(drawableResource);
if (soundResource != -1) {
if (mMediaPlayer != null) {
// stop the playing
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
// release mMediaPlayer resoruces
mMediaPlayer.release();
mMediaPlayer = null;
}
// Play the new resource
prepareMediaPlayer(soundResource);
}
} 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);
}
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.setLooping(true);
mMediaPlayer.start();
}
}
編輯:
天氣資料視圖模型:
public class WeatherDataViewModel extends ViewModel {
// This will save the city name
private SavedStateHandle state;
// This is where we'll store our result from the server
private MutableLiveData<Example> mutableWeatherData = new MutableLiveData<>();
public WeatherDataViewModel(SavedStateHandle savedStateHandle) {
state = savedStateHandle;
String savedCityName = state.get("name");
if (savedCityName != null) {
// We already had a previously saved name, so we'll
// start loading right away
loadData();
}
}
// This is what our Fragment will use to get the latest weather data
public LiveData<Example> getWeatherDataLiveData() {
return mutableWeatherData;
}
// When you get a new city name, we'll save that in our
// state, then load the new data from the server
public void setCityName(String name) {
state.set("name", name);
loadData();
}
private void loadData() {
// Get the last name that was set
String name = state.get("name");
// Now kick off a load from the server
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(@NonNull Call<Example> call, @NonNull Response<Example> response) {
// Save the response we've gotten
// This will automatically update our UI
mutableWeatherData.setValue(response.body());
}
@Override
public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
t.printStackTrace();
}
});
}
}
uj5u.com熱心網友回復:
當我最小化應用程式時,它仍然會重復播放聲音,直到我關閉/退出應用程式。我希望它在我最小化應用程式時暫停,然后從我輸入回來的那一刻停止的地方繼續播放。
當片段未顯示在螢屏上時,即在onPause()回呼中,您可以暫停 mediPlayer ,并在onResume().
但是要小心mediaPlayer,onCreate()因為它不會立即啟動,因為它會等到從天氣 API 中獲取資料;所以你需要做空能力檢查:
public void onResume() {
super.onResume();
if (mMediaPlayer != null)
mMediaPlayer.start();
}
@Override
public void onPause() {
super.onPause();
if (mMediaPlayer != null)
mMediaPlayer.pause();
}
旁注:為了避免在進行碎片事務時潛在的記憶體/電池泄漏,mediaPlayer如果應用程式被破壞,應釋放資源:
@Override
public void onDestroy() {
super.onDestroy();
// release mMediaPlayer resoruces
mMediaPlayer.release();
mMediaPlayer = null;
}
但我建議將該mMediaPlayer物件添加到 中ViewModel,以便在配置更改(如電話方向)期間保存其狀態。
uj5u.com熱心網友回復:
您需要使用服務:https : //developer.android.com/guide/components/services
也可以看看這個簡單的例子:https : //www.tutorialspoint.com/how-to-play-background-music-in-android-app
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/323362.html
