From 1542f98f5c5fd053b97b95700e9733a39aff7436 Mon Sep 17 00:00:00 2001 From: David Development Date: Tue, 26 Jan 2016 15:36:08 +0100 Subject: Fix #434 --- .../services/PodcastPlaybackService.java | 46 +++---- .../view/PodcastNotification.java | 137 +++++++++++++++++++-- 2 files changed, 153 insertions(+), 30 deletions(-) (limited to 'News-Android-App/src/main/java') diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java index e3701228..503cb356 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java @@ -65,6 +65,9 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn Log.v(TAG, "Stopping PodcastPlaybackService because of inactivity"); stopSelf(); } + + podcastNotification.unbind(); + return super.onUnbind(intent); } @@ -80,6 +83,8 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn private EventBus eventBus; private Handler mHandler; private MediaPlayer mMediaPlayer; + + private TextToSpeech ttsController; private String mediaTitle; private PlaybackType mPlaybackType; @@ -91,7 +96,6 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn public void onCreate() { Log.v(TAG, "onCreate PodcastPlaybackService"); - podcastNotification = new PodcastNotification(this); mediaTitle = getString(R.string.no_podcast_selected); TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); @@ -99,25 +103,8 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); } - super.onCreate(); - } - - @Override - public void onDestroy() { - Log.v(TAG, "onDestroy PodcastPlaybackService"); - - TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); - if(mgr != null) { - mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); - } - - podcastNotification.cancel(); - - super.onDestroy(); - } - - public PodcastPlaybackService() { mMediaPlayer = new MediaPlayer(); + podcastNotification = new PodcastNotification(this); mHandler = new Handler(); eventBus = EventBus.getDefault(); @@ -153,6 +140,22 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn eventBus.post(new PodcastPlaybackServiceStarted()); mHandler.postDelayed(mUpdateTimeTask, 0); + + super.onCreate(); + } + + @Override + public void onDestroy() { + Log.v(TAG, "onDestroy PodcastPlaybackService"); + + TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); + if (mgr != null) { + mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); + } + + podcastNotification.cancel(); + + super.onDestroy(); } @@ -165,6 +168,7 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn openTtsFeed((TTSItem) intent.getSerializableExtra(TTS_ITEM)); } } + return Service.START_STICKY; } @@ -267,6 +271,8 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn e.printStackTrace(); isPreparing = false; } + + podcastNotification.podcastChanged(); } /** @@ -467,6 +473,4 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn Log.d(TAG, "surfaceDestroyed"); } }; - - } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java index 089831f8..d7aa2586 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java @@ -2,56 +2,88 @@ package de.luhmer.owncloudnewsreader.view; import android.app.NotificationManager; import android.app.PendingIntent; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; +import android.media.AudioManager; +import android.media.session.MediaSessionManager; +import android.os.Build; import android.support.v4.app.NotificationCompat; +import android.support.v4.media.MediaMetadataCompat; +import android.support.v4.media.session.MediaControllerCompat; +import android.support.v4.media.session.MediaSessionCompat; +import android.support.v4.media.session.PlaybackStateCompat; + +import com.nostra13.universalimageloader.core.DisplayImageOptions; +import com.nostra13.universalimageloader.core.ImageLoader; import de.greenrobot.event.EventBus; import de.luhmer.owncloudnewsreader.NewsReaderListActivity; import de.luhmer.owncloudnewsreader.R; +import de.luhmer.owncloudnewsreader.events.podcast.TogglePlayerStateEvent; import de.luhmer.owncloudnewsreader.events.podcast.UpdatePodcastStatusEvent; import de.luhmer.owncloudnewsreader.events.podcast.broadcastreceiver.PodcastNotificationToggle; +import de.luhmer.owncloudnewsreader.model.PodcastItem; +import de.luhmer.owncloudnewsreader.services.PodcastPlaybackService; public class PodcastNotification { - private Context context; + public static final String ACTION_PLAY = "action_play"; + public static final String ACTION_PAUSE = "action_pause"; + //public static final String ACTION_NEXT = "action_next"; + //public static final String ACTION_PREVIOUS = "action_previous"; + //public static final String ACTION_STOP = "action_stop"; + + private Context mContext; private NotificationManager notificationManager; private EventBus eventBus; private NotificationCompat.Builder notificationBuilder; private PendingIntent resultPendingIntent; + private MediaSessionManager mManager; + public MediaSessionCompat mSession; + private MediaControllerCompat mController; + private final static int NOTIFICATION_ID = 1111; public PodcastNotification(Context context) { - this.context = context; + this.mContext = context; this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); eventBus = EventBus.getDefault(); eventBus.register(this); } + public void unbind() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mSession.release(); + } + } + private void createNewNotificationBuilder() { // Creates an explicit intent for an ResultActivity to receive. - Intent resultIntent = new Intent(context, NewsReaderListActivity.class); + Intent resultIntent = new Intent(mContext, NewsReaderListActivity.class); // Because clicking the notification opens a new ("special") activity, there's // no need to create an artificial back stack. resultPendingIntent = PendingIntent.getActivity( - context, + mContext, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT ); // Create the final Notification object. - notificationBuilder = new NotificationCompat.Builder(context) + notificationBuilder = new NotificationCompat.Builder(mContext) .setSmallIcon(R.drawable.ic_notification) .setAutoCancel(true) + .setOngoing(true) .setContentIntent(resultPendingIntent); } - int lastDrawableId; + int lastDrawableId = -1; public void onEvent(UpdatePodcastStatusEvent podcast) { if(!podcast.isFileLoaded()) @@ -66,9 +98,27 @@ public class PodcastNotification { createNewNotificationBuilder(); notificationBuilder.setContentTitle(podcast.getTitle()); - notificationBuilder.addAction(drawableId, actionText, PendingIntent.getBroadcast(context, 0, new Intent(context, + notificationBuilder.addAction(drawableId, actionText, PendingIntent.getBroadcast(mContext, 0, new Intent(mContext, PodcastNotificationToggle.class), PendingIntent.FLAG_ONE_SHOT)); + + + //Lock screen notification + /* + mSession.setMetadata(new MediaMetadataCompat.Builder() + .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, podcast.getMax()) + .build()); + */ + + if(podcast.isPlaying()) { + mSession.setPlaybackState(new PlaybackStateCompat.Builder() + .setState(PlaybackStateCompat.STATE_PLAYING, podcast.getCurrent(), 1.0f) + .setActions(PlaybackStateCompat.ACTION_PAUSE).build()); + } else { + mSession.setPlaybackState(new PlaybackStateCompat.Builder() + .setState(PlaybackStateCompat.STATE_PAUSED, podcast.getCurrent(), 0.0f) + .setActions(PlaybackStateCompat.ACTION_PLAY).build()); + } } @@ -95,12 +145,81 @@ public class PodcastNotification { .setProgress(100, progress, podcast.isPreparingFile()); notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); - //.setLargeIcon(R.drawable.ic_launcher) - //.addAction(android.R.drawable.ic_media_pause, "More", resultPendingIntent) } public void cancel() { notificationManager.cancel(NOTIFICATION_ID); + + mSession.setActive(false); + } + + public void podcastChanged() { + initMediaSessions(); + } + + private void initMediaSessions() { + String packageName = PodcastNotificationToggle.class.getPackage().getName(); + ComponentName receiver = new ComponentName(packageName, PodcastNotificationToggle.class.getName()); + mSession = new MediaSessionCompat(mContext, "PlayerService", receiver, null); + mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | + MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); + mSession.setPlaybackState(new PlaybackStateCompat.Builder() + .setState(PlaybackStateCompat.STATE_PAUSED, 0, 0) + .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build()); + + + PodcastItem podcastItem = ((PodcastPlaybackService)mContext).getCurrentlyPlayingPodcast(); + + String favIconUrl = podcastItem.favIcon; + DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder(). + showImageOnLoading(R.drawable.default_feed_icon_light). + showImageForEmptyUri(R.drawable.default_feed_icon_light). + showImageOnFail(R.drawable.default_feed_icon_light). + build(); + Bitmap bmpAlbumArt = ImageLoader.getInstance().loadImageSync(favIconUrl, displayImageOptions); + + + + mSession.setMetadata(new MediaMetadataCompat.Builder() + .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Test") + .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, "Test") + .putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Test") + //.putString(MediaMetadataCompat.METADATA_KEY_TITLE, podcastItem.title) + .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 100) + .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bmpAlbumArt) + /* .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, + BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher)) */ + .build()); + + mSession.setCallback(new MediaSessionCallback()); + + + AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() { + @Override + public void onAudioFocusChange(int focusChange) { + // Ignore + } + }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); + + MediaControllerCompat controller = mSession.getController(); + + + mSession.setActive(true); + } + + + private final class MediaSessionCallback extends MediaSessionCompat.Callback { + @Override + public void onPlay() { + EventBus.getDefault().post(new TogglePlayerStateEvent()); + } + + @Override + public void onPause() { + EventBus.getDefault().post(new TogglePlayerStateEvent()); + } } + } -- cgit v1.2.3