2014-07-13 24 views
1

以下是我的音乐播放器的服务类,实现onPrepared()方法从不调用,所以我必须使用setOnPreparedListener来完成所做的事情。 我想从未实现的部分执行它。重写onPrepared未被自动调用

public class MusicService extends Service implements MediaPlayer.OnPreparedListener, 
MediaPlayer.OnErrorListener,MediaPlayer.OnCompletionListener { 

    //media player 
    private MediaPlayer player; 
    //song list 
    private ArrayList<Song> songs; 
    //current position 
    private int songPosn; 
    private String songTitle=""; 
    private static final int NOTIFY_ID=1; 
    private final IBinder musicBind = new MusicBinder(); 

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

    public boolean onUnbind(Intent intent){ 
     player.stop(); 
     player.release(); 
     return false; 
    } 

    @Override 
    public void onCreate() { 
     // TODO Auto-generated method stub 
     super.onCreate(); 
     //initialize position 
     songPosn = 0; 
     //create player 
     player = new MediaPlayer(); 
    } 

    @Override 
    public void onCompletion(MediaPlayer mp) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public boolean onError(MediaPlayer mp, int what, int extra) { 
     // TODO Auto-generated method stub 
     return false; 
    } 

    //this is never being called and instead of this the one in setOnPreparedListener is called 
    @Override 
    public void onPrepared(MediaPlayer mp) { 
     // TODO Auto-generated method stub 
     //start music 
     mp.start(); 

     Intent notIntent = new Intent(this, MainActivity.class); 
     notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     PendingIntent pendInt = PendingIntent.getActivity(this, 0, notIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

     NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 
     builder.setContentIntent(pendInt) 
     .setSmallIcon(R.drawable.play) 
     .setTicker(songTitle) 
     .setOngoing(true) 
     .setContentText("Playing") 
     .setContentText(songTitle); 
     Notification not = builder.build(); 
     startForeground(NOTIFY_ID, not); 
    } 

    public void initMusicPlayer(){ 
     //set player properties 
     player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK); 
     player.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    } 

    public void setSong(int songIndex){ 
     songPosn=songIndex; 
    } 

    public void setList(ArrayList<Song> theSongs){ 
     songs = theSongs; 
    } 

    public void playSong(){ 
     //play a cool song 
     player.reset(); 
     //get song 

     Song playSong = songs.get(songPosn); 
     songTitle = playSong.getTitle(); 
     //get ID 
     long currSong = playSong.getId(); 
     //set path to sdcard or squaremash server 
     Uri trackUri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, currSong); 
     try { 
      player.setDataSource(getApplicationContext(), trackUri); 
     } catch (Exception e) { 
      Log.e("Music service","Error: setting data source",e); } 
     player.prepareAsync(); 
     //this one is called, If I remove this, the above onPrepared method isnt called 
     player.setOnPreparedListener(new OnPreparedListener() { 

      @Override 
      public void onPrepared(MediaPlayer mp) { 
       // TODO Auto-generated method stub 
       mp.start(); 
      } 
     }); 
    } 

    public void go(){ 
     player.start(); 
    } 
    //previous song 
    public void playPrev() { 
     songPosn--; 
     if(songPosn<0) 
      songPosn=songs.size()-1; 
     playSong(); 
    } 
    //next song 
    public void playNext() { 
     songPosn++; 
     if(songPosn>=songs.size()) 
      songPosn=0; 
     playSong(); 
    } 
} 

回答

1

您不设置正确的OnPreparedListener。

onCreate()当您创建的玩家,你应该设置有听众:

player = new MediaPlayer(); 
player.setOnPreparedListener(this) 

,并删除另外一个,否则它会覆盖第一。


当你实现一个接口,它只是设置在类合同:“这个类这些特殊的方法,随时给他们打电话。” MediaPlayer需要知道其中OnPreparedListener要使用(MediaPlayer.setOnPreparedListener),否则它不会执行任何操作。

+0

onPreparedListener工作,但通常因为我已经实现了接口,这样的方法onPrepared应该叫,这是行不通的,这就是为什么我添加onPreparedListener –

+0

你把听众('this')放在播放器上了吗? – ataulm

+0

是的,我刚刚做了,并将所有我的代码从onPreparedListener添加到“”public void onPrepared(MediaPlayer mp).. –

3

这不是Java的工作原理。

您正在扩展一个Service对象。该对象的生命周期中没有任何内容触发对onPrepared()的调用。是什么触发了呼叫您player成员:

private MediaPlayer player; 

而要做到这一点,即对于player触发调用onPrepared(),你需要把它指向实现onPrepared()的对象。这个对象是你的MusicService对象,因此你需要调用:

player.setOnPreparedListener(this); 
+0

@AdityaVerma如果你喜欢答案,请将其标记为解决方案。 – Vaiden