#android #service #bind
#Android #Обслуживание #привязка
Вопрос:
У меня есть служба, привязанная к действию. Действие представляет собой 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:
Вы должны остановить воспроизведение предыдущего файла перед воспроизведением другого файла. В вашем коде вы фактически создаете новый 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
.