package com.ptrprograms.androidautomedia.service;
import android.graphics.BitmapFactory;
import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.MediaPlayer;
import android.media.browse.MediaBrowser;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.service.media.MediaBrowserService;
import android.text.TextUtils;
import com.ptrprograms.androidautomedia.R;
import com.ptrprograms.androidautomedia.model.Song;
import com.ptrprograms.androidautomedia.util.SongGenerator;
import java.util.ArrayList;
import java.util.List;
/**
* Created by paulruiz on 2/13/15.
*/
public class AutoMediaBrowserService extends MediaBrowserService {
private static final String BROWSEABLE_ROOT = "root";
private static final String BROWSEABLE_ROCK = "Rock";
private static final String BROWSEABLE_JAZZ = "Jazz";
private static final String BROWSEABLE_CAJUN = "Cajun";
private static final String CURRENT_MEDIA_POSITION = "current_media_position";
private MediaSession mMediaSession;
private MediaSession.Token mMediaSessionToken;
private List<Song> mSongs;
private MediaPlayer mMediaPlayer;
private MediaSession.Callback mMediaSessionCallback = new MediaSession.Callback() {
@Override
public void onPlay() {
super.onPlay();
toggleMediaPlaybackState( true );
playMedia( PreferenceManager.getDefaultSharedPreferences( getApplicationContext() ).getInt( CURRENT_MEDIA_POSITION, 0 ), null );
}
//This is called when the pause button is pressed, or when onPlayFromMediaId is called in
//order to pause any currently playing media
@Override
public void onPause() {
super.onPause();
toggleMediaPlaybackState( false );
pauseMedia();
}
@Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
super.onPlayFromMediaId(mediaId, extras);
initMediaMetaData( mediaId );
toggleMediaPlaybackState( true );
playMedia( 0, mediaId );
}
@Override
public void onCustomAction(String action, Bundle extras) {
super.onCustomAction(action, extras);
}
};
@Override
public void onCreate() {
super.onCreate();
mSongs = SongGenerator.generateSongs();
initMediaSession();
}
private void initMediaSession() {
mMediaSession = new MediaSession( this, "Android Auto Audio Demo" );
mMediaSession.setActive( true );
mMediaSession.setCallback( mMediaSessionCallback );
mMediaSessionToken = mMediaSession.getSessionToken();
setSessionToken( mMediaSessionToken );
}
private void initMediaMetaData( String id ) {
for( Song song : mSongs ) {
if( !TextUtils.isEmpty( song.getuId() ) && song.getuId().equalsIgnoreCase( id ) ) {
MediaMetadata.Builder builder = new MediaMetadata.Builder();
if( !TextUtils.isEmpty( song.getTitle() ) )
builder.putText( MediaMetadata.METADATA_KEY_TITLE, song.getTitle() );
if( !TextUtils.isEmpty( song.getArtist() ) )
builder.putText( MediaMetadata.METADATA_KEY_ARTIST, song.getArtist() );
if( !TextUtils.isEmpty( song.getGenre() ) )
builder.putText( MediaMetadata.METADATA_KEY_GENRE, song.getGenre() );
if( !TextUtils.isEmpty( song.getAlbum() ) )
builder.putText( MediaMetadata.METADATA_KEY_ALBUM, song.getAlbum() );
if( !TextUtils.isEmpty( song.getAlbumUrl() ) )
builder.putText( MediaMetadata.METADATA_KEY_ALBUM_ART_URI, song.getAlbumUrl() );
mMediaSession.setMetadata( builder.build() );
}
}
}
private void toggleMediaPlaybackState( boolean playing ) {
PlaybackState playbackState;
if( playing ) {
playbackState = new PlaybackState.Builder()
.setActions( PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS )
.setState( PlaybackState.STATE_PLAYING, 0, 1 )
.build();
} else {
playbackState = new PlaybackState.Builder()
.setActions( PlaybackState.ACTION_PLAY_PAUSE )
.setState(PlaybackState.STATE_PAUSED, 0, 1)
.build();
}
mMediaSession.setPlaybackState( playbackState );
}
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
//Can do package and other validation to determine if calling app has access to media items
//in this service. If not, return null.
return new BrowserRoot(BROWSEABLE_ROOT, null);
}
@Override
public void onLoadChildren(String parentId, Result<List<MediaBrowser.MediaItem>> result) {
List<MediaBrowser.MediaItem> items = getMediaItemsById( parentId );
if( items != null ) {
result.sendResult( items );
}
}
private List<MediaBrowser.MediaItem> getMediaItemsById( String id ) {
List<MediaBrowser.MediaItem> mediaItems = new ArrayList<MediaBrowser.MediaItem>();
if( BROWSEABLE_ROOT.equalsIgnoreCase( id ) ) {
mediaItems.add( generateBrowseableMediaItemByGenre(BROWSEABLE_CAJUN) );
mediaItems.add( generateBrowseableMediaItemByGenre(BROWSEABLE_JAZZ) );
mediaItems.add( generateBrowseableMediaItemByGenre(BROWSEABLE_ROCK) );
} else if( !TextUtils.isEmpty( id ) ) {
return getPlayableMediaItemsByGenre( id );
}
return mediaItems;
}
private List<MediaBrowser.MediaItem> getPlayableMediaItemsByGenre( String genre ) {
if( TextUtils.isEmpty( genre ) )
return null;
List<MediaBrowser.MediaItem> mediaItems = new ArrayList();
for( Song song : mSongs ) {
if( !TextUtils.isEmpty( song.getGenre() ) && genre.equalsIgnoreCase( song.getGenre() ) ) {
mediaItems.add( generatePlayableMediaItem( song ) );
}
}
return mediaItems;
}
private MediaBrowser.MediaItem generateBrowseableMediaItemByGenre( String genre ) {
MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
mediaDescriptionBuilder.setMediaId( genre );
mediaDescriptionBuilder.setTitle( genre );
mediaDescriptionBuilder.setIconBitmap( BitmapFactory.decodeResource( getResources(), R.drawable.folder ) );
return new MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE );
}
private MediaBrowser.MediaItem generatePlayableMediaItem( Song song ) {
if( song == null )
return null;
MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
mediaDescriptionBuilder.setMediaId( song.getuId() );
if( !TextUtils.isEmpty( song.getTitle() ) )
mediaDescriptionBuilder.setTitle( song.getTitle() );
if( !TextUtils.isEmpty( song.getArtist() ) )
mediaDescriptionBuilder.setSubtitle( song.getArtist() );
if( !TextUtils.isEmpty( song.getThumbnailUrl() ) )
mediaDescriptionBuilder.setIconUri( Uri.parse( song.getThumbnailUrl() ) );
return new MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_PLAYABLE );
}
private void playMedia( int position, String id ) {
if( mMediaPlayer != null )
mMediaPlayer.reset();
//Should check id to determine what to play in a real app
int songId = getApplicationContext().getResources().getIdentifier("geoff_ledak_dust_array_preview", "raw", getApplicationContext().getPackageName());
mMediaPlayer = MediaPlayer.create(getApplicationContext(), songId);
if( position > 0 )
mMediaPlayer.seekTo( position );
mMediaPlayer.start();
}
private void pauseMedia() {
if( mMediaPlayer != null ) {
mMediaPlayer.pause();
PreferenceManager.getDefaultSharedPreferences( this ).edit().putInt( CURRENT_MEDIA_POSITION,
mMediaPlayer.getCurrentPosition() ).commit();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if( mMediaPlayer != null ) {
pauseMedia();
mMediaPlayer.release();
PreferenceManager.getDefaultSharedPreferences( this ).edit().putInt( CURRENT_MEDIA_POSITION,
0 ).commit();
}
}
}