2014-08-28 25 views
1

我正在研究Android的音樂播放器,並且我被困在這個問題上。Android回到MusicService通知的主要活動

現在我可以用musicservice播放歌曲並將其發送到背景,我還會顯示當前播放歌曲的通知。

我需要的是重新打開歌曲通知中的主要活動並繼續播放歌曲,它實際上啓動了期望的活動,但音樂服務被重新創建並停止當前播放歌曲。

這是我的代碼。

MusicService.java

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

private final IBinder musicBind = new MusicBinder(); 

//media player 
private MediaPlayer player; 

//song list 
private ArrayList<SongModel> songs; 

//current position 
private int songPosition; 

public MusicService() { 
} 

public void onCreate() { 
    //create the service 
    super.onCreate(); 

    //initialize position 
    songPosition = 0; 

    //create player 
    player = new MediaPlayer(); 

    initMusicPlayer(); 
} 

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<SongModel> theSongs) { 
    songs = theSongs; 
} 

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

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

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

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

public int getCurrenListPosition() { 
    return songPosition; 
} 

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

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

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

public void stopPlayer() { 
    player.stop(); 
} 

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

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

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

     SongModel playSong = songs.get(songPosition); 
     String trackUrl = playSong.getFileUrl(); 

     player.setDataSource(trackUrl); 
     player.prepareAsync(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

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

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

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

    SongModel playingSong = songs.get(songPosition); 

    Intent intent = new Intent(this, NavDrawerMainActivity.class); 
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 
      PendingIntent.FLAG_UPDATE_CURRENT); 

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

    builder.setContentIntent(pendingIntent) 
      .setSmallIcon(R.drawable.ic_action_playing) 
      .setTicker(playingSong.getTitle()) 
      .setOngoing(true) 
      .setContentTitle(playingSong.getTitle()) 
      .setContentText(playingSong.getArtistName()); 

    Notification notification = builder.build(); 
    startForeground((int) playingSong.getSongId(), notification); 
} 

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

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

}

DiscoverSongsFragment.java

public class DiscoverSongsFragment extends Fragment 
    implements MediaController.MediaPlayerControl { 

JazzyGridView songsContainer; 
SongsHelper songsHelper; 
SongsAdapter songsAdapter; 
ArrayList<SongModel> songsArrayList; 
ConnectionState connectionState; 

Context mContext; 
private static View rootView; 

SongModel currentSong; 
SeekBar nowPlayingSeekBar; 
final Handler handler = new Handler(); 

// this value contains the song duration in milliseconds. 
// Look at getDuration() method in MediaPlayer class 
int mediaFileLengthInMilliseconds; 

View nowPlayingLayout; 
boolean nowPlayingLayoutVisible; 

TextView nowPlayingTitle; 
TextView nowPlayingArtist; 
ImageButton nowPlayingCover; 
ImageButton nowPlayingStop; 

private MusicService musicService; 
private Intent playIntent; 
private boolean musicBound = false; 
private boolean playbackPaused = false; 

private int mCurrentTransitionEffect = JazzyHelper.SLIDE_IN; 

public static DiscoverSongsFragment newInstance() { 
    return new DiscoverSongsFragment(); 
} 

public DiscoverSongsFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

    rootView = inflater.inflate(R.layout.fragment_discover_songs, container, false); 
    mContext = rootView.getContext(); 
    setupViews(rootView); 

    return rootView; 
} 

@Override 
public void onStart() { 
    super.onStart(); 

    if (playIntent == null) { 
     playIntent = new Intent(mContext, MusicService.class); 
     mContext.bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE); 
     mContext.startService(playIntent); 
    } 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    if (isPlaying()) { 
     showNowPlayingLayout(); 
     primarySeekBarProgressUpdater(); 
    } 
} 

@Override 
public void onDestroy() { 
    mContext.stopService(playIntent); 
    musicService = null; 
    super.onDestroy(); 
} 

private void hideNowPlayingLayout() { 
    nowPlayingLayoutVisible = false; 
    nowPlayingLayout.setVisibility(View.GONE); 

    Animation animationFadeIn = AnimationUtils.loadAnimation(mContext, R.anim.fade_out); 
    nowPlayingLayout.startAnimation(animationFadeIn); 
} 

private void showNowPlayingLayout() { 
    nowPlayingLayoutVisible = true; 
    nowPlayingLayout.setVisibility(View.VISIBLE); 

    Animation animationFadeIn = AnimationUtils.loadAnimation(mContext, R.anim.fade_in); 
    nowPlayingLayout.startAnimation(animationFadeIn); 
} 

private void setupViews(View rootView) { 
    songsHelper = new SongsHelper(); 
    songsArrayList = new ArrayList<SongModel>(); 
    connectionState = new ConnectionState(mContext); 
    songsAdapter = new SongsAdapter(mContext, songsArrayList); 

    nowPlayingLayout = rootView.findViewById(R.id.nowPlayingLayout); 
    nowPlayingLayout.setVisibility(View.GONE); 
    nowPlayingLayoutVisible = false; 

    songsContainer = (JazzyGridView) rootView.findViewById(R.id.songsContainerView); 
    songsContainer.setTransitionEffect(mCurrentTransitionEffect); 
    songsContainer.setAdapter(songsAdapter); 
    songsContainer.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 

      musicService.setSong(position); 
      musicService.playSong(); 

      if (playbackPaused) { 
       playbackPaused = false; 
      } 

      currentSong = songsArrayList.get(position); 

      // gets the song length in milliseconds from URL 
      mediaFileLengthInMilliseconds = getDuration(); 

      if (currentSong != null) { 
       nowPlayingTitle.setText(currentSong.getTitle()); 
       nowPlayingArtist.setText(currentSong.getArtistName()); 
       nowPlayingCover.setImageBitmap(currentSong.getCoverArt()); 
      } 

      primarySeekBarProgressUpdater(); 

      if (!nowPlayingLayoutVisible) { 
       showNowPlayingLayout(); 
      } 
     } 
    }); 

    nowPlayingSeekBar = (SeekBar) rootView.findViewById(R.id.nowPlayingSeekbar); 
    nowPlayingSeekBar.setMax(99); 

    nowPlayingTitle = (TextView) rootView.findViewById(R.id.nowPlayingTitle); 
    nowPlayingArtist = (TextView) rootView.findViewById(R.id.nowPlayingArtist); 
    nowPlayingStop = (ImageButton) rootView.findViewById(R.id.nowPlayingStop); 
    nowPlayingStop.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (isPlaying()) { 

       currentSong = null; 
       playbackPaused = false; 
       musicService.stopPlayer(); 
       mediaFileLengthInMilliseconds = 0; 
       nowPlayingSeekBar.setProgress(0); 
       hideNowPlayingLayout(); 

      } 
     } 
    }); 

    nowPlayingCover = (ImageButton) rootView.findViewById(R.id.nowPlayingCover); 
    nowPlayingCover.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      try { 
       Intent intent = new Intent(mContext, SongDetailsActivity.class); 
       intent.putExtra("Title", currentSong.getTitle()); 
       intent.putExtra("Artist", currentSong.getArtistName()); 
       intent.putExtra("Album", currentSong.getAlbumName()); 
       intent.putExtra("Genre", currentSong.getGenre()); 
       intent.putExtra("CoverUrl", currentSong.getCoverArtUrl()); 

       startActivity(intent); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

    getSongs(); 
    hideNowPlayingLayout(); 
} 

private void getSongs() { 

    if (!connectionState.isConnectedToInternet()) { 

    } 

    songsAdapter.clear(); 

    String songsUrl = Constants.getAPI_SONGS_URL(); 
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(songsUrl, new Response.Listener<JSONArray>() { 
     @Override 
     public void onResponse(JSONArray jsonArray) { 

      if (jsonArray != null) { 

       for (int i = 0; i < jsonArray.length(); i++) { 
        try { 

         JSONObject jsonObject = jsonArray.getJSONObject(i); 
         SongModel song = songsHelper.getSongFromJson(jsonObject); 
         songsAdapter.add(song); 

        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 

       } 
      } 
     } 
    }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError volleyError) { 
     } 
    }); 

    AppController.getInstance().addToRequestQueue(jsonArrayRequest); 
} 

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
} 

/** 
* Method which updates the SeekBar primary progress by current song playing position 
*/ 
private void primarySeekBarProgressUpdater() { 
    nowPlayingSeekBar.setProgress((int) (((float) getCurrentPosition()/getDuration()) * 100)); 

    //if (isPlaying()) { 
    Runnable runnable = new Runnable() { 
     public void run() { 
      primarySeekBarProgressUpdater(); 
     } 
    }; 
    handler.postDelayed(runnable, 1000); 
    //} 
} 

@Override 
public void start() { 
    musicService.start(); 
} 

@Override 
public void pause() { 
    playbackPaused = true; 
    musicService.pausePlayer(); 
} 

@Override 
public int getDuration() { 
    if (musicService != null && musicBound && musicService.isPlaying()) { 
     return musicService.getDuration(); 
    } 
    return 0; 
} 

@Override 
public int getCurrentPosition() { 
    if (musicService != null && musicBound && musicService.isPlaying()) { 
     return musicService.getPosition(); 
    } 
    return 0; 
} 

public int getCurrentListPosition() { 
    if (musicService != null && musicBound && musicService.isPlaying()) { 
     return musicService.getCurrenListPosition(); 
    } 
    return 0; 
} 

@Override 
public void seekTo(int pos) { 
    musicService.seekToPosition(pos); 
} 

@Override 
public boolean isPlaying() { 
    if (musicService != null && musicBound && musicService.isPlaying()) { 
     return musicService.isPlaying(); 
    } 
    return false; 
} 

@Override 
public int getBufferPercentage() { 
    return 0; 
} 

@Override 
public boolean canPause() { 
    return true; 
} 

@Override 
public boolean canSeekBackward() { 
    return true; 
} 

@Override 
public boolean canSeekForward() { 
    return true; 
} 

@Override 
public int getAudioSessionId() { 
    return 0; 
} 

//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 
     musicService = binder.getService(); 
     //pass list 
     musicService.setList(songsArrayList); 
     musicBound = true; 
    } 

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

}

(該片段還通過抽屜菜單項目中導航時重新創建本身)

我希望有人能幫助我實現這一點。當重新啓動MainActivity時,我不知道如何維護狀態(順便說一下,我使用navdrawer來保存片段)

回答

0

將當前正在播放的歌曲包含在您的通知意圖中。隨歌曲改變更新意圖。包含標記以清除頂部和標記以更新通知意圖中的當前內容。 :(對不起 IDK如果我有標誌適合您的情況,但你將有一個地方做更多的研究。

在您服務,您創建的通知的意圖。

 // link the notifications to the recorder activity 
     Intent resultIntent = new Intent(context, KmlReader.class); 
     resultIntent 
       .setAction(ServiceLocationRecorder.INTENT_COM_GOSYLVESTER_BESTRIDES_LOCATION_RECORDER); 
     resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     PendingIntent resultPendingIntent = PendingIntent 
       .getActivity(context, 0, resultIntent, 
         PendingIntent.FLAG_UPDATE_CURRENT); 
     mBuilder.setContentIntent(resultPendingIntent); 

     return mBuilder.build(); 
    } 

然後在主要onCreate檢查束爲當前播放歌曲的名稱,並顯示它。注意我是如何檢查捆綁鍵的存在,在使用它之前。

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Intent intent = getIntent(); 

    String intentaction = intent.getAction(); 

    // First Run checks 
    if (savedInstanceState == null) { 
     // first run init 

...

} else { 
     // get the saved_Instance state 
     // always get the default when key doesn't exist 
     // default is null for this example 
     currentCameraPosition = savedInstanceState 
       .containsKey(SAVED_INSTANCE_CAMERA_POSITION) ? (CameraPosition) savedInstanceState 
       .getParcelable(SAVED_INSTANCE_CAMERA_POSITION) : null; 

...