0

У меня было 2 мероприятия (а именно MainActivity, который показывает список песен и стандартный медиа-контроллер внизу, и AndroidBuildingMusicPlayerActivity с настраиваемым макетом для воспроизведения) и Bound Обслуживание. Проблема: playNext и playPrevios (из класса MusicService) отлично работают с контроллером MainActivity, хотя работают неправильно (вроде перетасовываются) из другой активности. Я позже удалил контроллер MainActivity (поскольку я не хочу его). Я работал над исправлением playNext и playPrevios для AndroidBuildingMusicPlayerActivity, но проблема остается. Как это решить? Спасибо заранее.Music Play Next и Play Previous не работают в студии Android

Эти коды:

MusicService:

public void onCreate(){ 
    super.onCreate(); 
    songPosn=0; 
    player = new MediaPlayer(); 
    initMusicPlayer(); 
    rand=new Random(); 
} 

@Override 
public void onDestroy() { 
    stopForeground(true); 
} 


public class MusicBinder extends Binder { 
    MusicService getService() { 
     return MusicService.this; 
    } 
} 

//initializes the MediaPlayer class 
public void initMusicPlayer(){ 
    //set player properties 
    player.setWakeMode(getApplicationContext(), 
      PowerManager.PARTIAL_WAKE_LOCK); 
    player.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    player.setOnPreparedListener(this); 
    player.setOnCompletionListener(this); 
    player.setOnErrorListener(this); 
} 


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

//Let's now set the app up to play a track 
public void playSong(){ 
    player.reset(); 
    //get song 
    Song playSong = songs.get(songPosn); 
    songTitle=playSong.getTitle(); 
    //get id 
    long currSong = playSong.getID(); 
    //set uri 
    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(); 
} 

//We will call this when the user picks a song from the list. 
public void setSong(int songIndex){ 
    songPosn=songIndex; 
} 

public void playPrev(){ 
    songPosn--; 
    if(songPosn<0) songPosn=songs.size()-1; 
    playSong(); 
} 

//skip to next 
public void playNext(){ 
    if(shuffle){ 
     int newSong = songPosn; 
     while(newSong==songPosn){ 
      newSong=rand.nextInt(songs.size()); 
     } 
     songPosn=newSong; 
    } 
    else{ 
     songPosn++; 
     if(songPosn>=songs.size()) songPosn=0; 
    } 
    playSong(); 
} 


public int getPosn(){ 
    return player.getCurrentPosition(); 
} 

public int getDur(){ 
    return player.getDuration(); 
} 

public boolean isPng(){ 
    return player.isPlaying(); 
} 

public void pausePlayer(){ 
    player.pause(); 
} 

public void seek(int posn){ 
    player.seekTo(posn); 
} 

public void go(){ 
    player.start(); 
} 

public void setShuffle(){ 
    if(shuffle) shuffle=false; 
    else shuffle=true; 
} 


//When the MediaPlayer is prepared, the onPrepared method will be executed. 
@Override 
public void onPrepared(MediaPlayer mp) { 
    //start playback 
    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); 

    Notification.Builder builder = new Notification.Builder(this); 

    builder.setContentIntent(pendInt) 
      .setSmallIcon(R.drawable.play) 
      .setTicker(songTitle) 
      .setOngoing(true) 
      .setContentTitle("Playing").setContentText(songTitle); 
    Notification not = builder.build(); 

    startForeground(NOTIFY_ID, not); 
} 

@Override 
public void onCompletion(MediaPlayer mp) { 
    if(player.getCurrentPosition()>0){ 
     mp.reset(); 
     playNext(); 
    } 
} 

@Override 
public boolean onError(MediaPlayer mp, int what, int extra) { 
    mp.reset(); 
    return false; 
} 


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

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

AndroidBuildingMusicPlayerActivity:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.player); 

// All player buttons 
    btnPlay = (ImageButton) findViewById(R.id.btnPlay); 
    btnNext = (ImageButton) findViewById(R.id.btnNext); 
    btnPrevious = (ImageButton) findViewById(R.id.btnPrevious); 
    btnRepeat = (ImageButton) findViewById(R.id.btnRepeat); 
    btnShuffle = (ImageButton) findViewById(R.id.btnShuffle); 
    songProgressBar = (SeekBar) findViewById(R.id.songProgressBar); 
    songTitleLabel = (TextView) findViewById(R.id.songTitle); 
    songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel); 
    songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel); 
    equalizer = (EqualizerView) findViewById(R.id.equalizer_view); 
    // Mediaplayer 
    mp = new MediaPlayer(); 
    utils = new Utilities(); 

    songProgressBar.setOnSeekBarChangeListener(this); 
    // set Progress bar values 
    songProgressBar.setProgress(0); 
    songProgressBar.setMax(100); 
    // Updating progress bar 
    updateProgressBar(); 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
    if(playIntent2==null){ 
     playIntent2 = new Intent(this, MusicService.class); 
     bindService(playIntent2, musicConnection2, Context.BIND_AUTO_CREATE); 
     startService(playIntent2); 
    } 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
} 

//connect to the service 
private ServiceConnection musicConnection2 = new ServiceConnection(){ 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     MusicService.MusicBinder binder = (MusicService.MusicBinder)service; 
     //get service 
     ms = binder.getService(); 
     musicBound2 = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     musicBound2 = false; 
    } 
}; 

public void updateProgressBar() { 
    mHandler.postDelayed(mUpdateTimeTask, 100); 
} 

/** 
* Background Runnable thread 
* */ 
private Runnable mUpdateTimeTask = new Runnable() { 
    public void run() { 
     long totalDuration = ms.getDur(); 
     long currentDuration = ms.getPosn(); 

     // Displaying Total Duration time 
     songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration)); 
     // Displaying time completed playing 
     songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration)); 

     // Updating progress bar 
     int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration)); 
     //Log.d("Progress", ""+progress); 
     songProgressBar.setProgress(progress); 

     // Running this thread after 100 milliseconds 
     mHandler.postDelayed(this, 100); 
    } 
}; 

@Override 
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { 

} 

/** 
* When user starts moving the progress handler 
* */ 
@Override 
public void onStartTrackingTouch(SeekBar seekBar) { 
    // remove message Handler from updating progress bar 
    mHandler.removeCallbacks(mUpdateTimeTask); 
} 

/** 
* When user stops moving the progress hanlder 
* */ 
@Override 
public void onStopTrackingTouch(SeekBar seekBar) { 
    mHandler.removeCallbacks(mUpdateTimeTask); 
    int totalDuration = ms.getDur(); 
    int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration); 

    // forward or backward to certain seconds 
    ms.seek(currentPosition); 

    // update timer progress again 
    updateProgressBar(); 
} 


public void playClicked(View view){ 
    if(!ms.isPng()){ 
     btnPlay.setImageResource(R.drawable.btn_pause); 
     ms.go(); 
     equalizer.animateBars(); 
    } 
    else { 
     btnPlay.setImageResource(R.drawable.btn_play); 
     ms.pausePlayer(); 
     equalizer.stopBars(); 
    } 
} 

public void prvClicked(View view){ 
    ms.playPrev(); 
} 

public void nextClicked(View view){ 
    ms.playNext(); 
} 

MainActivity:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
    if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED) { 

     requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1); 
     // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an 
     // app-defined int constant 
     return; 
    } 
    } 
    songView = (ListView)findViewById(R.id.song_list); 
    songList = new ArrayList<Song>(); 
    getSongList(); 
    Collections.sort(songList, new Comparator<Song>(){ 
     public int compare(Song a, Song b){ 
      return a.getTitle().compareTo(b.getTitle()); 
     } 
    }); 
    SongAdapter songAdt = new SongAdapter(this, songList); 
    songView.setAdapter(songAdt); 
} 


@Override 
protected void onStart() { 
    super.onStart(); 
    if(playIntent==null){ 
     playIntent = new Intent(this, MusicService.class); 
     bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE); 
     startService(playIntent); 
    } 
} 
@Override 
protected void onResume(){ 
    super.onResume(); 

} 
@Override 
protected void onPause(){ 
    super.onPause(); 
} 
@Override 
protected void onStop() { 
    super.onStop(); 
} 
@Override 
protected void onDestroy() { 
    stopService(playIntent); 
    musicSrv=null; 
    super.onDestroy(); 
} 

//connect to the service 
private ServiceConnection musicConnection = new ServiceConnection(){ 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     MusicService.MusicBinder binder = (MusicService.MusicBinder)service; 
     //get service 
     musicSrv = binder.getService(); 
     //pass list 
     musicSrv.setList(songList); 
     musicBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     musicBound = false; 
    } 
}; 

public void getSongList() { 
    ContentResolver musicResolver = getContentResolver(); 
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null); 
    if(musicCursor!=null && musicCursor.moveToFirst()){ 
     //get columns 
     int titleColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.TITLE); 
     int idColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media._ID); 
     int artistColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.ARTIST); 
     //add songs to list 
     do { 
      long thisId = musicCursor.getLong(idColumn); 
      String thisTitle = musicCursor.getString(titleColumn); 
      String thisArtist = musicCursor.getString(artistColumn); 
      songList.add(new Song(thisId, thisTitle, thisArtist)); 
     } 
     while (musicCursor.moveToNext()); 
    } 
} 





//when user clicks on a song 
public void songPicked(View view){ 
    musicSrv.setSong(Integer.parseInt(view.getTag().toString())); 
    musicSrv.playSong(); 
    Intent intent = new Intent(this, AndroidBuildingMusicPlayerActivity.class); 
    startActivity(intent); 

} 

Ошибки, которые я нашел:

Attempt to call getDuration without a valid mediaplayer 
E/MediaPlayer: error (-38, 0). 

Так что теперь я удалил SeekBar от AndroidBuildingMusicPlayerActivity которая решила проблему, но как реализовать панели поиска тогда?

ответ

1

Наконец, я нашел его

В моем случае проблема была с SeekBar. В моем классе обслуживания я изменил:

@Override 
public void onPrepared(MediaPlayer mp) { 
mp.start();} 

public getDur() { return mediaPalyer.getDuration} 

в

int dr; //at the top inside Service class 

@Override 
public void onPrepared(MediaPlayer mp) { 
mp.start(); 
dr = player.getDuration();} 

public getDur() { return dr} 

Это помогло мне: https://stackoverflow.com/a/5711274/6737655

1

getDuration должен быть внутри onPrepared. Также старайтесь не выполнять тяжелые работы на onPrepared

 Смежные вопросы

  • Нет связанных вопросов^_^