Поведение bind Service, MP по-прежнему воспроизводит несколько файлов - PullRequest
0 голосов
/ 05 июня 2011

У меня есть услуга, связанная с деятельностью. Активность - это ListView воспроизводимых файлов. Служба воспроизводит определенный аудиофайл, переданный из Activty. В предыдущей версии у меня не было привязки Сервиса, поэтому при многократном нажатии на элемент воспроизведения может появиться несколько звуков. Я думал, что смогу решить эту проблему, связав службу, поэтому я буду каждый раз связываться с одним и тем же экземпляром, однако он все равно будет воспроизводить несколько файлов, если на них щелкнуть. Возможно, я неправильно понял концепцию привязки, я не уверен, документация для Android иногда немного расплывчата и вводит в заблуждение. Вот мой код, спасибо за любой вклад.

Активность:

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();
}
}

1 Ответ

0 голосов
/ 05 июня 2011

Вы должны остановить воспроизведение предыдущего файла перед воспроизведением другого файла. В своем коде вы фактически создаете новый 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.

...