The following are all converted from the android game programming entry-level classic. For more information, see the source.
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.
You can initialize a new soundpool instance as follows:
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 );
The assetmanager. openfd () method can be used to directly obtain the assetfiledescriptor, while 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 in use and should be set to 1 for future compatibility.
The soundpool. Load () method returns an integer value, which serves 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 (maximum)
The next two parameters are rarely used. The first parameter is the priority, which 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.
When we no longer need a sound effect and want to release the memory, we can use the soundpool. Unload () method:
Soundpool. Unload (explosionid );
We only need to pass in the sound handle received from the soundpool. Load () method. This method will unload 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:
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 android.widget.TextView;public class SoundPoolTest extends Activity implements OnTouchListener{SoundPool soundPool;int explosionId = -1;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);TextView textView = new TextView(this);textView.setOnTouchListener(this);setContentView(textView);setVolumeControlStream(AudioManager.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());}}@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubif(event.getAction() == MotionEvent.ACTION_UP){if(explosionId != -1){soundPool.play(explosionId, 1, 1, 0, 0, 1);}}return true;}@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();soundPool.release();}}
Soundpool may cause problems 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 = new mediaplayer ();
Next we need to tell mediaplayer what files to play, which is also achieved through assetfiledescriptor:
Assetfiledescriptor descriptor = assetmanager. openfd ("music.ogg ");
Mediaplayer. setdatasource (descriptor. getfiledescriptor (), descriptor. getstartoffset (), descriptor. getlength ());
This 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: This method can only be called after the mediaplayer. Prepare () method is successfully called (you will notice whether it throws a runtime exception ).
After playing the video, we can call the pause () method to pause the video:
Mediaplayer. Pause ();
This method takes effect only when mediaplayer is ready and played. To restore a paused mediaplayer, you can call the mediaplayer. Start () method again without any preparation.
You can stop playing a video by calling the following method:
Mediaplayer. Stop ();
Note: To start a stopped mediaplayer, call the mediaplayer. Prepare () method again.
You can set loop playback using the following method:
Mediaplayer. setlooping (true );
You can adjust the volume of the music in the following ways:
Mediaplayer. setvolume (1, 1 );
This will reset the left-right audio volume. 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 mediaplayer is set to loop playback, neither of the preceding two 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 is 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:
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;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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");mediaPlayer.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;}}@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();if(mediaPlayer != null){mediaPlayer.pause();if(isFinishing()){mediaPlayer.stop();mediaPlayer.release();}}}@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();if(mediaPlayer != null)mediaPlayer.start();}}
In the onresume () method, we only need to start the 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.