If you have an Android device, you will notice that when you press the increase or decrease button, the different volume settings you control depend on the application you are running. During a call, you control the volume of the input audio stream. In a video player, you control the volume of the Video audio. On the home screen, you control the volume of the ringtone. Android provides different audio streams for different purposes. When playing audio in a game, you can use classes to output sound effects and music to specific music streams. However, before we want to play a sound effect or music, make sure that the volume button controls the correct audio stream. To this end, we use another method of the Context interface: context. setVolumeControlStream (AudioManager. STREAM_MUSIC); As always, the implementation of Context is still the responsibility of our activities. After this method is called, the volume button controls the music stream and we can use it to output our sound effects and music. You only need to call this method once within the lifecycle of an Activity. It is best to call it in the Activity. onCreate () method. First, we need to distinguish between music streams and sound effects. The latter is generally stored in the memory and its length does not exceed several seconds. The Android system provides us with a SoundPool class, which enables sound playback easily. We can initialize a new SoundPool instance as follows: SoundPool soundPool = new SoundPool (20, AudioManager. STREAM_MUSIC, 0); the first parameter specifies the maximum number of sound effects that can be played at the same time. This does not mean that we cannot load more audio files, but it only limits the number of sound effects that can be played simultaneously. The second parameter specifies the audio stream used by SoundPool to output the audio. Here we select the music stream and have set the volume control for it. The last parameter is not used now. It should be the default value 0. To load sound effects from an audio file to heap memory, we can use the SoundPool. load () method. All files are stored in the assets/directory, so we need to reload the SoundPool. load () method. All files are stored in the assets/directory. Therefore, we need to overload the SoundPool. load () method to obtain an AssetFileDescriptor. How can we obtain AssetFileDescriptor? Use AssetManager. Here we use SoundPool to upload an OGG file named explosion.ogg from assets/directories: AssetFileDescriptor descriptor = assetManager. openFd ("explosion.ogg"); int explosionId = soundPool. load (descriptor, 1); Through AssetManager. the openFd () method can directly obtain the AssetFileDescriptor, And the SoundPool can easily load the sound effect. The second parameter is used to specify the priority of the sound effect. This parameter is not currently used. For future compatibility, it should be set to 1. The SoundPool. load () method will return an integer value, which will be used as a handle for loading sound effects. When you want to play a sound effect, you only need to specify the handle, and the SoundPool will know which audio to play. SoundPool. play (explosionId, 1.0f, 1.0f, 0, 0, 1); the first parameter is to accept the handle from the SoundPool. load () method. The next two parameters are used to specify the volume of the left and right channels. The value should be from 0 (mute) to 1 (max). The next two parameters are rarely used. The first parameter is the priority, it is not used currently and should be set to 0. another parameter is used to specify the loop playback frequency. Generally, loop playback is not recommended, so it is set to 0. The last parameter is the playback speed. When it is set to greater than 1, the playback speed of the sound effect will be faster than it was during recording. When it is set to less than 1, playing the sound will be slow. You can use SoundPool when you no longer need a sound effect and want to release the memory. unload () method: soundPool. unload (explosionId); we only need. the load () method can pass in the sound handle received by the load () method. This method uninstalls the sound from the memory. When we finish all audio output without needing a SoundPool, we need to call the SoundPool. release () method to release all resources occupied by SoundPool. Of course, after being released, we cannot use SoundPool any more, and all the sound effects loaded by SoundPool will also be released. Now, you can write a simple test activity to play an explosive sound every time you click the screen. The Code is as follows: [java] package org. example. ch04_android_basics; import java. io. IOException; import android. app. activity; import android. content. res. assetFileDescriptor; import android. content. res. assetManager; import android. media. audioManager; import android. media. soundPool; import android. OS. bundle; import android. view. motionEvent; import android. view. view; import android. view. view. onTouchListener; import Ndroid. widget. textView; public class SoundPoolTest extends Activity implements OnTouchListener {SoundPool soundPool; int explosionId =-1; @ Override protected void onCreate (Bundle role) {// TODO Auto-generated method stub super. onCreate (savedInstanceState); TextView textView = new TextView (this); textView. setOnTouchListener (this); setContentView (textView); setVolumeControlStream (Aud IoManager. STREAM_MUSIC); soundPool = new SoundPool (20, AudioManager. STREAM_MUSIC, 0); try {AssetManager assetManager = getAssets (); AssetFileDescriptor descriptor = assetManager. openFd ("explosion.ogg"); explosionId = soundPool. load (descriptor, 1);} catch (IOException e) {textView. setText ("Couldn't load sound effect from asset," + e. getMessage () ;}@ Override public boolean onTouch (View v, Motio NEvent event) {// TODO Auto-generated method stub if (event. getAction () = MotionEvent. ACTION_UP) {if (explosionId! =-1) {soundPool. play (explosionId, 1, 1, 0, 0, 1) ;}} return true ;}@ Override protected void onPause () {// TODO Auto-generated method stub super. onPause (); soundPool. release () ;}} SoundPool is faulty when processing MP3 files or long audio files. The definition of long files exceeds 5 or 6 seconds. We recommend that you use OGG audio files instead of MP3 files, and use as low as possible sampling rate and duration while maintaining sound quality. Short sound effects are usually stored in the heap memory allocated by the Android Application from the operating system, which is not suitable for large audio files that contain long music files. Therefore, we need to output the music to the audio hardware as a stream, which means that each time we can only read a small piece of data, this data is enough to be decoded into Native PCM Data and output to the audio chip. It sounds scary. Fortunately, we have a MediaPlayer class that can handle everything. Initialize the MediaPlayer class: MediaPlayer mediaPlayer = new MediaPlayer (). Next we need to tell the MediaPlayer what files to play. This is also achieved through AssetFileDescriptor: AssetFileDescriptor descriptor = assetManager. openFd ("music.ogg"); mediaPlayer. setDataSource (descriptor. getFileDescriptor (), descriptor. getStartOffset (), descriptor. getLength (); it is a little more complex than SoundPool. MediaPlayer. the setDataSource () method does not directly obtain AssetFileDescriptor. Instead, it uses a FileDescriptor through AssetFileDescriptor (). getFileDescriptor () method to obtain the descriptor. In addition, we need to specify the offset and length of the audio file. Why is the offset? In fact, resources are stored in the form of a single file. In order for MediaPlayer to obtain the starting address of the file, we need to provide the file offset in the asset folder to it. Before playing the music file, you need to call another method to prepare for playing the MediaPlayer: MediaPlayer. prepare (); this will actually open the file and check whether it can be read and played using the MediaPlayer instance. From here, we can play, pause, and stop audio files at will, or set loop playback and change the volume. You can start playing by calling the following method: mediaPlayer. start (); note that this method must be successfully called MediaPlayer. the prepare () method can be called only after it is called (you will notice whether it throws a runtime exception ). After playing the video, you can call the pause () method to pause the video: MediaPlayer. pause (); this method takes effect only when you have prepared the MediaPlayer and enabled the video. To restore a paused MediaPlayer, you can call the MediaPlayer. start () method again without any preparation. Call the following method to stop playing: MediaPlayer. stop (); Note: To start a stopped MediaPlayer, call the MediaPlayer. prepare () method again. We can set loop playback through the following method: MediaPlayer. setLooping (true); the following method can be used to adjust the music playback volume: MediaPlayer. setVolume (1, 1); this will reset the volume of the left and right channels. The range of these two parameters is not specified in this document. From the results of multiple attempts, the valid value is 0-1. Finally, we need a method to check whether the playback is complete. There are two ways to achieve this. For the first method, you can register an OnCompletionListener with MediaPlayer. When the playback is complete, it will be called: mediaPlayer. setOnCompletionListener (listener); to poll the MediaPlayer status, use the following method: boolean isPlaying = mediaPlayer. isPlaying (); Note: If the MediaPlayer is set to loop playback, neither of the preceding methods can indicate that the MediaPlayer has stopped. Finally, if the MediaPlayer instance has completed all the operations, you need to use the following method to ensure that the resources it occupies are released: mediaPlayer. release (); it should be a good practice to perform this operation before dropping an instance. If you have not set MediaPlayer to a loop and the playback has ended, you can restart MediaPlayer through the MediaPlayer. prepare () and MediaPlayer. start () methods. Most of these methods are asynchronous. Therefore, when MediaPlayer. stop () is called, The MediaPlayer. isPlaying () method may take some time to return. Write a test activity to play an audio file in the assets/directory in cyclic mode. This sound effect will be paused and restored Based on the lifecycle of the activity. When the activity is paused, the music will also be paused. When the activity is resumed, the music will also start playing from the last paused place. The Code is as follows: [java] package org. example. ch04_android_basics; import java. io. IOException; import android. app. activity; import android. content. res. assetFileDescriptor; import android. content. res. assetManager; import android. media. audioManager; import android. media. mediaPlayer; import android. OS. bundle; import android. widget. textView; public class MediaPlayerTest extends Activity {MediaPlayer mediaPlayer; @ O Verride protected void onCreate (Bundle savedInstanceState) {// TODO Auto-generated method stub super. onCreate (savedInstanceState); TextView textView = new TextView (this); setContentView (textView); setVolumeControlStream (AudioManager. STREAM_MUSIC); mediaPlayer = new MediaPlayer (); try {AssetManager assetManager = getAssets (); AssetFileDescriptor descriptor = assetManager. openFd ("music.ogg"); media Player. setDataSource (descriptor. getFileDescriptor (), descriptor. getStartOffset (), descriptor. getLength (); mediaPlayer. prepare (); mediaPlayer. setLooping (true);} catch (IOException e) {textView. setText ("Couldn't load music file," + e. getMessage (); mediaPlayer = null ;}@ Override protected void onPause () {// TODO Auto-generated method stub super. onPause (); if (mediaPlayer! = Null) {mediaPlayer. pause (); if (isFinishing () {mediaPlayer. stop (); mediaPlayer. release () ;}www.2cto.com }}@ Override protected void onResume () {// TODO Auto-generated method stub super. onResume (); if (mediaPlayer! = Null) mediaPlayer. start () ;}} in the onResume () method, we only need to start MediaPlayer (if it has been successfully created ). The onResume () method is perfect for processing this operation because it is called after the onCreate () method and the onPause () method. In the first case, it starts playing for the first time; in the second case, it simply restores the paused MediaPlayer. In the onPause () method, we pause the MediaPlayer. If this activity is destroyed, we also need to stop the MediaPlayer and release all resources.