We are about to switch to a new forum software. Until then we have removed the registration on this forum.
This is a follow up to an old post: http://forum.processing.org/one/topic/mediaplayer-oncompletionlistener#25080000001854529.html
I am using the android.media.MediaPlayer; on a sketch, and I want to evoke the onCompletion method when a a music reaches its end. Unfortunately I'm having some issues properly overriding this method. My music class is as follows:
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.content.res.*;
public class MusicPlayer
{
private ArrayList<MediaPlayer> songs;
private String[] titles = {"redhot", "gaga", "vincent", "psy"};
private int songIndex;
private boolean playing;
private AssetManager assets;
public MusicPlayer(PApplet theParent)
{
songs = new ArrayList<MediaPlayer>();
playing = false;
assets = theParent.getAssets();
for (String songTitle : titles)
{
MediaPlayer song = new MediaPlayer();
AssetFileDescriptor fd;
// PROBLEM IS HERE
myOnCompletionListener songEnds = new myOnCompletionListener();
try
{
fd = assets.openFd(songTitle + ".mp3");
song.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
song.setOnCompletionListener(songEnds); // AND HERE
song.prepare();
}
catch (IOException e)
{
println("Error loading music: " + e);
}
songs.add(song);
}
songIndex = 0;
}
public void previousTrack()
{
if (playing) songs.get(songIndex).pause();
if (songIndex > 0) songIndex -= 1;
else songIndex = titles.length - 1;
startNewSong();
}
public void nextTrack()
{
if (playing) songs.get(songIndex).pause();
if (songIndex < titles.length - 1) songIndex += 1;
else songIndex = 0;
startNewSong();
}
private void startNewSong()
{
songs.get(songIndex).seekTo(0);
songs.get(songIndex).start();
playing = true;
}
public void pausePlay(int status)
{
if (status == 0 && !playing) songs.get(songIndex).start();
else if (status == 1 && playing) songs.get(songIndex).pause();
playing = !playing;
}
public boolean isPlaying()
{
return playing;
}
// AND HERE
public class myOnCompletionListener implements OnCompletionListener
{
@ Override // In the original code there is not space after @
public void onCompletion(MusicPlayer player)
{
player.nextTrack();
}
}
}
This code always generates the following errors :
error: Watch.MusicPlayer.myOnCompletionListener is not abstract and does not override abstract method onCompletion(MediaPlayer) in OnCompletionListener
[javac] public class myOnCompletionListener implements OnCompletionListener
error: method does not override or implement a method from a supertype
[javac] @ Override
Answers
Please, when pasting code w/
@Override
in it, insert a space between@
&Override
:@ Override
.It won't interfere w/ Java's parser! This forum still didn't fix it! :-<
AFAIK, in your line #21 :
MediaPlayer song = new MediaPlayer();
, that MediaPlayer will always use its original members. You can't force it to use your custom MyOnCompletionListener the way you're doing it! [-XYou should write your own MediaPlayer class extending it; and modify it in a way it uses your MyOnCompletionListener in place of its original OnCompletionListener! :-B
However, if its fields are
private
, you won't be able to pull that out w/o some heavy hack! :-SS"You should write your own MediaPlayer class extending it"
That's not the purpose here.
He creates a OnCompletionListener (strange name, usually they are just called CompletionListener; whatever) override, actually. The onCompletion method is the one overridden / implemented. By definition, these classes (or interface, more likely) are designed to be overridden, so that's not the problem here.
The real problem, per the error message, is that you try to override a method onCompletion(MediaPlayer) (taking a MediaPlayer parameter), and the one you declare is onCompletion(MusicPlayer). But your MusicPlayer class doesn't override MediaPlayer (and shouldn't).
Fix your declaration, it should be fine.
That did it, thank you PhiLho.