Fix #434
This commit is contained in:
parent
5f86a9db85
commit
1542f98f5c
3 changed files with 162 additions and 31 deletions
|
@ -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>
|
||||
|
||||
|
||||
<!--
|
||||
**********************************************************************
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue