1. 游戲中的即時音效:
在游戲中,根據情況播放的即時音效較為短暫、可以重復、也可以同時播放。由于Android中提供的MediaPlayer會占用大量的系統資源,而且播放時還會進行緩沖,有較大的延時,因此使用MediaPlayer無法實現即時音效的播放。而在Android中專門提供的SoundPool類主要用于管理和播放應用程序中的聲音資源,使用該類時首先需要通過該類將聲音資源加載到內存中,然后在需要的即時音效的地方播放即可,幾乎沒有延時現象?!居捎赟oundPool設計的初衷是用于無延時地播放游戲中的即時音效,因此實際開發中應該只講長度小于7s的聲音資源放進soundPool,否則可能會加載失敗或內存占用過大】
SoundPool類:
public SoundPool (int maxSreams, int streamType, int srcQuality):創建SoundPool對象:maxStreams[該參數用于設置最多同時播放多少個音效]streamType[該參數設置音頻類型,在游戲中通常設置為STREAM_MUSIC]srcQuality[該參數設置音頻文件的質量,目前還沒有具體的作用,設置為0(默認值)]
public int load(Context context, int resId, int PRiority):架子啊音頻文件:context[該參數為應用程序的上下文]resId[該參數為要加載的音效資源的ID]priority[優先級]
public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate):播放音效:soundID[該參數為要播放的音效ID]leftVolume[用來控制左聲道音量]rightVolume[用來控制右聲道音量]priority[該參數為優先級,0為最低]loop[該參數為音效的循環次數,0為不循環,-1為永遠循環]rate[該參數為音效的回放速率,該值在0.5~2.0f,1.0f為正常速度]
public final void pause(int streamID):暫停音效的播放:streamID[要暫停音效的ID]
public final void stop(int streamID):停止播放音效:streamID[要停止播放音效的ID]
實例:
//初始化聲音池的方法 public void initialsnd() { //初始化SoundPool對象 sp=new SoundPool(4,AudioManager.STREAM_MUSIC,0); //初始化hashMap hm=new HashMap<Integer,Integer>(); //加載音效文件ff,并設置為1號聲音放入到hm中 hm.put(1,sp.load(this,R.raw.ff,1)); }//音效播放 public void playSound(int sound,int loop) { //獲取AudioManager引用 AudioManager am=(AudioManager)this.getSystemService(Context.AUDIO_SERVICE); //獲取當前系統音量 float v1=am.getStreamVolume(AudioManager.STREAM_MUSIC); //獲取系統的最大音量 float v2=am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //計算得到播放音量 float v=v1/v2; //調用SoundPool的play方法播放文件 currentId=sp.play(hm.get(sound),v,v,1,loop,1.0f); }
2.背景音樂播放:
在游戲中,背景音樂可以使用不大于7s的一小節音樂將SoundPool的loop設置為-1即可;但在實際開發中,背景音效對延時并不是特別敏感,因此較長音效可以使用MediaPlayer進行播放。
2.1MediaPlayer的聲明周期:MediaPlayer的生命周期包括10種狀態,每種狀態下可以調用相應的方法來實現音/視頻文件的管理或播放。
<1>Idle狀態:使用new方法創建一個MediaPlayer對象或者調用了其reset方法時,該MediaPlayer對象處于idle狀態。在此狀態下調用getDuration等方法,reset方法進入idle狀態的話會觸發OnErrorListener.onError,同時MediaPlayer對象進入Error狀態,當然new方法不會。
<2>End狀態:通過release方法可以進入End狀態,只要MediaPlayer對象不再被使用,就應當盡快將其通過release方法釋放掉,以釋放占用的軟、硬件資源,這其中有些資源是互斥的。如果MediaPlayer進入到End狀態就不會再進行其他任何狀態。
<3>Initialized狀態:MediaPlayer調用setDataSource方法就進入了Initialized狀態,表示此時要播放的文件已經裝備好了。
<4>Prepared狀態:初始化完成之后還需要調用prepare或prepareAsync方法進行準備,這兩種方法一種是同步的,一種是異步的。只有進入了Prepared狀態,才表明MediaPlayer到目前為止都工作正常,可以進行音樂文件的播放。
<5>Preparing狀態:主要是與prepareAsync異步準備方法配合,如果異步準備完成,會觸發OnPreparedListener.onPrepared,進而進入Prepared狀態。
<6>Started狀態:MediaPlayer準備完成之后,通過調用start方法,將進入Started狀態。所謂Started狀態,也就是播放中的狀態,開發中可以使用isPlaying方法測試MediaPlayer是否處于Started狀態。
<7>Paused狀態:Started狀態下調用paused方法可以暫停播放,從而進入Paused狀態。暫停狀態時可以調用seekTo方法,這時此MediaPlayer的狀態是不變的。
<8>Stop狀態:Started狀態和Paused狀態下均可調用stop方法并進入Stop狀態,如果處于Stop狀態的MediaPlayer要想重新播放,需要通過調用prepareAsync或prepare方法返回到先前的Prepared狀態重新開始才可以。
<9>PlaybackCompleted狀態:文件正常播放完畢,而又沒有設置循環播放的話就進入該狀態,并會觸發OnCompletionListener接口中的OnCompletion方法。此時可以調用start方法重新從頭開始播放文件呢,也可以調用stop方法停止播放,或者調用seekTo方法來重新定位播放位置。
<10>Error狀態:由于某種原因MediaPlayer出現了錯誤,就會觸發OnErrorListener.onError回調方法,此時MediaPlayer將會進入Error狀態。及時捕捉并妥善處理這些錯誤可以釋放相關的軟、硬件資源,也可以改善用戶體驗。如果MediaPlayer進入了Error狀態,可以通過調用reset方法來恢復,使得MediaPlayer重新返回Idle狀態。
2.2MediaPlayer類:
首首先需要調用Activity對象的getSystemService(Context.AUDIO_SERVICE)方法獲取AudioManager對象。然后調用MediaPlayer類中的相關方法進行音量控制。
public void adjustVolume(int direction, int flags):調用該方法可以調節音量大小。參數direction為調節的方向,ADJUST_LOWER減小音量、ADJUST_RAISE增大音量、ADJUST_SAME保持音量不變;參數flags為標記,通常設置為0。
public int getStreamMaxVolume(int streamtype):獲取系統最大音量。
public int getStreamVolume(int StreamType):獲取系統當前音量。
void android.media.AudioManager.setStreamVolume(int streamType, int index, int flags):調用該方法可以設置音量的大小,參數streamType為聲音的類型,index為要設置的音頻的索引值,參數flags為標記,通常設置為AudioManager.FLAG_PLAY_SOUND。
package com.mycompany.myapp;import android.app.*;import android.os.*;import android.view.*;import android.widget.*;import android.media.*;import android.content.*;import android.view.View.*;public class MainActivity extends Activity{ MediaPlayer mp; AudioManager am; private int maxvolume; private int curvolume; private int stpvolume; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mp=new MediaPlayer(); try{ mp.setDataSource("sdcard/kgmusic/download/One T - The Magic Key.mp3"); mp.prepare(); }catch(Exception e){ e.printStackTrace(); } am=(AudioManager)this.getSystemService(Context.AUDIO_SERVICE); maxvolume=am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); stpvolume=maxvolume/6; Button bstart=(Button)this.findViewById(R.id.playbtn); Button bpause=(Button)this.findViewById(R.id.pausebtn); Button bstop=(Button)this.findViewById(R.id.stopbtn); Button bincrease=(Button)this.findViewById(R.id.increasevolumebtn); Button breduce= (Button)this.findViewById(R.id.reducevolumebtn); bstart.setOnClickListener(new OnClickListener(){ public void onClick(View v){ mp.start(); Toast.makeText(getBaseContext(),"開始播放",Toast.LENGTH_LONG).show(); } }); bpause.setOnClickListener(new OnClickListener(){ public void onClick(View v){ mp.pause(); Toast.makeText(getBaseContext(),"暫停播放",Toast.LENGTH_LONG).show(); } }); bstop.setOnClickListener(new OnClickListener(){ public void onClick(View v){ mp.stop(); Toast.makeText(getBaseContext(),"停止播放",Toast.LENGTH_LONG).show(); } }); bincrease.setOnClickListener(new OnClickListener(){ public void onClick(View v){ curvolume=am.getStreamVolume(AudioManager.STREAM_MUSIC); int tmpvolume=curvolume+stpvolume; am.setStreamVolume(AudioManager.STREAM_MUSIC,curvolume,AudioManager.FLAG_PLAY_SOUND); Toast.makeText(getBaseContext(),"音量增加",Toast.LENGTH_LONG).show(); } }); breduce.setOnClickListener(new OnClickListener(){ public void onClick(View v){ curvolume=am.getStreamVolume(AudioManager.STREAM_MUSIC); int tmpvolume=curvolume-stpvolume; curvolume=tmpvolume>0?tmpvolume:0; am.setStreamVolume(AudioManager.STREAM_MUSIC,curvolume,AudioManager.FLAG_PLAY_SOUND); Toast.makeText(getBaseContext(),"音量減小",Toast.LENGTH_LONG); } }); }}
新聞熱點
疑難解答