0

J'ai eu 2 Activités (à savoir MainActivity qui montre la liste des chansons et un contrôleur multimédia par défaut en bas, et un AndroidBuildingMusicPlayerActivity avec une mise en page personnalisée pour la lecture) et un Bound Un service. Le problème est lié aux fonctions playNext et playPrevios (de la classe MusicService) qui fonctionnaient correctement à partir du contrôleur MainActivity alors qu'il fonctionnait mal (sorte de mélange) de l'autre activité. J'ai ensuite retiré le contrôleur MainActivity (puisque je ne le veux pas). J'ai travaillé sur la correction du playNext et du playPrevios de l'AndroidBuildingMusicPlayerActivity, mais le problème persiste. Comment résoudre ce problème? Merci d'avance.Musique Lecture Suivant et Lecture Précédent ne fonctionnent pas dans le studio Android

Ce sont les codes:

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

} 

erreurs que j'ai trouvé:

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

Alors je viens juste retiré de la barre de recherche AndroidBuildingMusicPlayerActivity qui a résolu le problème, mais comment puis-je mettre en œuvre la barre de recherche alors?

Répondre

1

Enfin je l'ai trouvé

Dans mon cas, la question était la seekbar. Dans ma classe de service j'ai changé:

@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} 

Cela m'a aidé: https://stackoverflow.com/a/5711274/6737655

1

getDuration doit être à l'intérieur onPrepared. Également essayer de ne pas faire de gros travaux sur onPréparé