2011-06-05 60 views
0

我有一個服務綁定到一個活動。該活動是可播放文件的ListView。該服務播放某個音頻文件,從Activty傳遞。在之前的版本中,我沒有綁定服務,因此當在播放元素上多次點擊時,會發生多個聲音實例。我想我可以通過綁定服務來解決這個問題,所以我會每次都使用同一個實例進行通信,但是如果點擊它,它仍然會播放多個文件。也許我理解綁定的概念是錯誤的,我不確定,android文檔有時會有些模糊和誤導。這是我的代碼,謝謝你的任何意見。綁定服務的行爲,MP仍在播放多個文件

活動:

public class ViewSounds extends ListActivity { 

    private PlayService myService; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setVolumeControlStream(AudioManager.STREAM_MUSIC); 

    // Bind Service 
    Intent intent = new Intent(ViewSounds.this, PlayService.class);  
    getApplicationContext().bindService(intent, serviceConncetion, BIND_AUTO_CREATE); 

    // Get list vars 
    String[] lex_names = getResources().getStringArray(R.array.lex_names); 
    //final String[] lex_files = getResources().getStringArray(R.array.lex_files); 

    setListAdapter(new ArrayAdapter<String>(this, R.layout.list_sounds, lex_names)); 
    final ListView lv = getListView(); 
    lv.setTextFilterEnabled(true); 

    lv.setOnItemClickListener(new OnItemClickListener() { 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {     

    //int playFile = getResources().getIdentifier(lex_files[position], "raw", getPackageName()); 
    myService.playAudio(); 

    } 
    }); 
    } 

    private ServiceConnection serviceConncetion = new ServiceConnection() { 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     // TODO Auto-generated method stub 
     myService = ((PlayService.MyBinder)service).getService();     
     } 

     @Override 
     public void onServiceDisconnected(ComponentName name) { 
     // TODO Auto-generated method stub 
     myService = null; 
     } 
     }; 

     @Override 
     public void onDestroy(){ 
     super.onDestroy(); 
     unbindService(serviceConncetion);  
     } 
} 

服務:

public class PlayService extends Service { 

MediaPlayer player; 

private final IBinder binder = new MyBinder(); 

@Override 
public IBinder onBind(Intent intent) { 
    return binder; 
}  

public class MyBinder extends Binder { 
    PlayService getService() { 
     return PlayService.this; 
    } 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
} 

public void playAudio(){ 
      // I hardcoded the file name for this preview 

    player = MediaPlayer.create(this, R.raw.no_harm); 
    player.setLooping(false); // Set looping 
    if (!player.isPlaying()) {  
    player.start(); 
    } 
} 

public void onStart(Intent intent, int startId){ 
    super.onStart(intent, startId); 
    Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show(); 

    // Get veriable from Activity 
    // int extras; 
    // extras = intent.getExtras().getInt("playFile");   

} 
@Override 
public void onDestroy() { 
    super.onDestroy(); 
} 
} 

回答

0

你應該玩另一個文件之前,必須停止以前的文件的播放。在你的代碼中,你實際上爲每個新媒體文件創建新的MediaPlayer

這裏是如何您playAudio應該是這樣的:

public void playAudio(){ 
    // I hardcoded the file name for this preview 

    if(player != null){ 
     player.release(); 
    } 

    player = MediaPlayer.create(this, R.raw.no_harm); 
    player.setLooping(false); // Set looping 
    if (!player.isPlaying()) {  
     player.start(); 
    } 
} 

但是要避免新的媒體播放器爲每個新創建的播放。你可以這樣做下一個方法:

public void playAudio(){ 
    // I hardcoded the file name for this preview 

    if(player == null){ 
     player = new MediaPlayer(); 
    } 

    if(player.isPlaying()){ 
     player.stop(); 
    } 

    player.reset(); 
    player.setLooping(false); 

    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){ 
     @Override 
     void onPrepared(MediaPlayer mp){ 
      mp.play(); 
     } 
    });  
    player.prepareAsync(); 
} 

您還應該使用onSetErrorListener(...)onSetComlpletionListener(...)超過了玩家更多的控制。因此,您的活動可以對MediaPlayer中的狀態更改做出反應。

相關問題