簡體   English   中英

重寫onPrepared不會自動調用

[英]overriden onPrepared not being called automatically

以下是音樂播放器的服務類,從未調用實現的onPrepared()方法,因此我必須使用setOnPreparedListener來完成任務。 我想從未實現的部分執行它。

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

這不是Java的工作方式。

您正在擴展Service對象。 該對象的生命周期中沒有任何事件可以觸發對onPrepared()的調用。 觸發該呼叫的是您的player成員:

private MediaPlayer player;

為了實現這一點,即讓player觸發對onPrepared()的調用,您需要將其指向實現onPrepared()的對象。 該對象是您的MusicService對象,因此您需要調用:

player.setOnPreparedListener(this);

您沒有設置正確的OnPreparedListener。

創建播放器時,在onCreate() ,應在此處設置偵聽器:

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

並刪除另一個,否則它將覆蓋第一個。


實現接口時,只需在類上設置協定:“該類具有這些特定方法,請隨時調用它們”。 MediaPlayer需要知道要使用哪個 OnPreparedListenerMediaPlayer.setOnPreparedListener ),否則它將無法執行任何操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM