Android MediaPlayer.reset () вызывает onCompletion

У меня возникла проблема со следующим кодом. Я вызвал setPrevNextListener на моем MediaController и определил два onClickListeners для Prev и Next. Когда я нажимаю на следующую кнопку, а не на один трек, я иду вперед двумя треками. Кажется, это связано с тем, что onCompletion как-то называется. Вызывает ли MediaPlayer.reset () onCompletion? Я включил вывод logcat и мой код. Дайте мне знать, если я что-то делаю неправильно. Заранее спасибо.

Logcat:

02-24 00:36:34.826: D/MP(6675): Next Button Clicked, index was: 0 02-24 00:36:34.837: D/MP(6675): About to call Reset() 02-24 00:36:34.906: D/MP(6675): Inside setUpPlayer 02-24 00:36:34.917: D/MP(6675): Called setDataSource with index: 1 02-24 00:36:34.917: D/MP(6675): Leaving setUpPlayer 02-24 00:36:34.917: D/MP(6675): About to call prepareAsync() 02-24 00:36:34.937: D/MP(6675): Leaving next button 02-24 00:36:35.226: E/MediaPlayer(6675): Attempt to call getDuration without a valid mediaplayer 02-24 00:36:35.226: E/MediaPlayer(6675): error (-38, 0) 02-24 00:36:35.276: E/MediaPlayer(6675): Error (-38,0) 02-24 00:36:35.287: D/MP(6675): Inside onCompletion 02-24 00:36:35.337: D/MP(6675): About to call Reset() 02-24 00:36:35.347: D/MP(6675): Inside setUpPlayer 02-24 00:36:35.356: D/MP(6675): Called setDataSource with index: 2 02-24 00:36:35.356: D/MP(6675): Leaving setUpPlayer 02-24 00:36:35.356: D/MP(6675): About to call prepareAsync() 02-24 00:36:35.377: D/MP(6675): Leaving onCompletion 02-24 00:36:36.517: D/MP(6675): Inside onPrepared, index is: 2 02-24 00:36:36.577: D/MP(6675): Leaving onPrepared 

Код:

 public class MusicPlayerActivity extends Activity implements OnPreparedListener, OnCompletionListener, MediaController.MediaPlayerControl { private MediaPlayer mp; private MediaController mc; private SonarDatabase db; private SubsonicAPIConnector sonic; ArrayList<String> songs; int index = 0; private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.music_player); // Get params from intent Intent i = getIntent(); String albumId = i.getStringExtra("albumId"); String artistId = i.getStringExtra("artistId"); String albumName = i.getStringExtra("albumName"); String songName = i.getStringExtra("songName"); String songId = i.getStringExtra("songId"); String coverArt = "al-"+albumId+".jpeg"; String duration = i.getStringExtra("duration"); Log.d("MP", "results: albumName:" + albumName + ", songName: " + songName + ", songId: " + songId + ", duration: " + duration + ", coverArt: " + coverArt + ", artistId: " + artistId + ", albumId: " + albumId); db = new SonarDatabase(getApplicationContext()); sonic = new SubsonicAPIConnector(db.getURL(), db.getUsername(), db.getPassword()); String artistName = db.getArtistNameById(artistId); setTitle("Now Playing"); songs = db.getSongListForAlbum(albumId); index = songs.indexOf(songId); Log.d("MP", "songid: " + songId + ", index: " + index); // Update text views with song information TextView txtArtist = (TextView) findViewById(R.id.txtArtistName); txtArtist.setText(artistName); TextView txtAlbum = (TextView) findViewById(R.id.txtAlbumName); txtAlbum.setText(albumName); TextView txtSong = (TextView) findViewById(R.id.txtSongName); txtSong.setText(songName); // Show the album art File img = new File(this.getFilesDir()+"/covers/"+coverArt); if(img.exists()) { Log.d("MP", "Found image at: " + img.toString()); ImageView imgView = (ImageView) findViewById(R.id.cover_art); imgView.setImageBitmap(BitmapFactory.decodeFile(img.getPath())); } else { Log.d("MP", "Couldn't find image: " + img.toString()); } // Create the media player and controller mp = new MediaPlayer(); mp.setOnPreparedListener(this); mp.setOnCompletionListener(this); mc = new NonHidingMediaController(this); mc.setPrevNextListeners(new View.OnClickListener() { @Override public void onClick(View v) { // next button clicked Log.d("MP", "Next Button Clicked, index was: " + index); playNextTrack(); Log.d("MP", "Leaving next button"); } }, new View.OnClickListener() { @Override public void onClick(View v) { // previous button clicked Log.d("MP", "Previous button clicked, index was: " + index); if(mp.isPlaying() && mp.getCurrentPosition() < 2000 && index != 0) { Log.d("MP", "Start the prior song."); playPreviousTrack(); } else { Log.d("MP", "Restart this song."); restartCurrentTrack(); } Log.d("MP", "Leaving previous button"); } }); mc.setMediaPlayer(this); setUpPlayer(); Log.d("MP", "About to call prepareAsync()"); mp.prepareAsync(); } @Override public void onCompletion(MediaPlayer mp) { Log.d("MP", "Inside onCompletion"); //TODO add code for scrobbling here. playNextTrack(); Log.d("MP", "Leaving onCompletion"); } private void playNextTrack() { index++; TextView txtSong = (TextView) findViewById(R.id.txtSongName); txtSong.setText(db.getSongNameById(songs.get(index))); Log.d("MP", "About to call Reset()"); mp.reset(); setUpPlayer(); Log.d("MP", "About to call prepareAsync()"); mp.prepareAsync(); } private void playPreviousTrack() { index--; TextView txtSong = (TextView) findViewById(R.id.txtSongName); txtSong.setText(db.getSongNameById(songs.get(index))); Log.d("MP", "About to call Reset()"); mp.reset(); setUpPlayer(); Log.d("MP", "About to call prepareAsync()"); mp.prepareAsync(); } private void restartCurrentTrack() { mp.seekTo(0); } public void onPrepared(MediaPlayer mp) { Log.d("MP", "Inside onPrepared, index is: " + index); mc.setMediaPlayer(this); mc.setAnchorView(findViewById(R.id.music_player_view)); mp.start(); handler.post(new Runnable() { public void run() { mc.setEnabled(true); mc.show(); } }); Log.d("MP", "Leaving onPrepared"); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_music_player, menu); return true; } @Override public boolean onTouchEvent(MotionEvent event) { Log.d("MP", "OnTouchEvent called"); mc.show(); return false; } private void setUpPlayer() { Log.d("MP", "Inside setUpPlayer"); mp.setAudioStreamType(AudioManager.STREAM_MUSIC); try { mp.setDataSource(sonic.streamString("&id=" + songs.get(index))); Log.d("MP", "Called setDataSource with index: " + index); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.d("MP", "Leaving setUpPlayer"); } @Override protected void onStop() { super.onStop(); mc.hide(); mp.stop(); mp.release(); } public void start() { mp.start(); } public void pause() { mp.pause(); } public int getDuration() { return mp.getDuration(); } public int getCurrentPosition() { return mp.getCurrentPosition(); } public void seekTo(int i) { mp.seekTo(i); } public boolean isPlaying() { return mp.isPlaying(); } public int getBufferPercentage() { return 0; } public boolean canPause() { return true; } public boolean canSeekBackward() { return true; } public boolean canSeekForward() { return true; } public class NonHidingMediaController extends MediaController { public NonHidingMediaController(Context context, AttributeSet attrs) { super(context, attrs); } public NonHidingMediaController(Context context, boolean useFastForward) { super(context, useFastForward); } public NonHidingMediaController(Context context) { super(context); } @Override public void show(int timeout) { super.show(0); } } } 

Я немного поработал через источник android и обнаружил, что любые необработанные ошибки заставляют MediaPlayer вызывать обработчик onCompletion. В этом случае вы вызываете getDuration в состояниях Idle, Initialized или Error. Возможно внутри контроллера. Я бы предложил добавить некоторые Log.d () прямо перед любыми местами, которые вызывают getDuration, чтобы узнать, где вызван вызов, вызывающий проблему.

Добавьте MediaPlayer.OnErrorLisener и верните true из метода с переопределением

 mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { return true; } }); 
Intereting Posts
Может ли кто-нибудь дать пример кода для TabHost в Android? Reddit oAuth 2 для Android «беспроигрышное» приложение с дооснащением Как ссылаться на внешнюю банку в проекте библиотеки Android в IntelliJ v10 Внедрить разделитель между последним элементом дочернего элемента и следующим Groupheader expandableListview Разрешение отказа читать с emailprovider в android Возврат истории назад с использованием ng-include Исключение при использовании файлов dexing: Перевод был прерван IllegalArgumentException: com.google.android.gms.common.internal.db Использование Dropbox API для загрузки файла с Android Сделать обычную тему использовать нулевой фон (предложение Android lint) Преобразование последовательности изображений в видео файл android java Как анализировать комплексный ответ с использованием библиотеки ksoap2 в android Как создать курсор из JSONArray? Как поддерживать разные языки с помощью динамических веб-данных на Android? Что произойдет, если я изменю категорию в Play Store?