This commit is contained in:
David Development 2016-01-26 15:36:08 +01:00
parent 5f86a9db85
commit 1542f98f5c
3 changed files with 162 additions and 31 deletions

View file

@ -17,6 +17,8 @@
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<uses-sdk tools:overrideLibrary="android.support.customtabs"/>
@ -96,7 +98,13 @@
<activity android:name="DirectoryChooserActivity" />
<receiver android:name=".events.podcast.broadcastreceiver.PodcastNotificationToggle" />
<receiver android:name=".events.podcast.broadcastreceiver.PodcastNotificationToggle">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
<!--
**********************************************************************

View file

@ -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");
}
};
}

View file

@ -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());
}
}
}