Start PlaybackService lazily to allow using ForegroundService

This commit is contained in:
ByteHamster 2018-04-22 22:21:46 +02:00
parent 7ad176ce29
commit 3e98ab61ea
20 changed files with 234 additions and 75 deletions

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.activity;
import android.content.Intent;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewCompat;
import android.text.TextUtils;
import android.util.Log;
@ -41,7 +42,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
true);
startService(launchIntent);
ContextCompat.startForegroundService(this, launchIntent);
} else if (PlaybackService.isCasting()) {
Intent intent = PlaybackService.getPlayerActivityIntent(this);
if (intent.getComponent() != null &&

View File

@ -30,6 +30,7 @@ import android.widget.ListView;
import com.bumptech.glide.Glide;
import de.danoeh.antennapod.core.event.ServiceEvent;
import de.danoeh.antennapod.core.util.NotificationUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
@ -741,6 +742,15 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
loadData();
}
public void onEventMainThread(ServiceEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
switch(event.action) {
case SERVICE_STARTED:
externalPlayerFragment.connectToPlaybackService();
break;
}
}
public void onEventMainThread(ProgressEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
switch(event.action) {

View File

@ -34,6 +34,7 @@ import com.joanzapata.iconify.fonts.FontAwesomeIcons;
import java.util.Locale;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.ServiceEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
@ -270,6 +271,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
controller.release();
}
controller = newPlaybackController();
setupGUI();
loadMediaInfo();
onPositionObserverUpdate();
}
@Override
@ -608,8 +612,23 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
super.onResume();
Log.d(TAG, "onResume()");
StorageUtils.checkStorageAvailability(this);
if(controller != null) {
controller.init();
if (controller != null) {
if (PlaybackService.isRunning) {
controller.init();
} else {
controller.resumeServiceNotRunning();
}
}
}
public void onEventMainThread(ServiceEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
switch(event.action) {
case SERVICE_STARTED:
if (controller != null) {
controller.init();
}
break;
}
}
@ -853,6 +872,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
if(controller == null) {
return;
}
controller.init();
controller.playPause();
}

View File

@ -6,6 +6,7 @@ import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.WindowCompat;
import android.support.v7.app.ActionBar;
import android.util.Log;
@ -30,6 +31,7 @@ import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.service.PlayerWidgetService;
import de.danoeh.antennapod.view.AspectRatioVideoView;
import java.lang.ref.WeakReference;
@ -89,7 +91,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
true);
startService(launchIntent);
ContextCompat.startForegroundService(this, launchIntent);
} else if (PlaybackService.isCasting()) {
Intent intent = PlaybackService.getPlayerActivityIntent(this);
if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) {

View File

@ -81,9 +81,15 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
}
} else { // media is downloaded
if (item.hasMedia() && item.getMedia().isCurrentlyPlaying()) {
if (!PlaybackService.isRunning) {
PlaybackService.startService(context, media, true, false);
}
context.sendBroadcast(new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
}
else if (item.hasMedia() && item.getMedia().isCurrentlyPaused()) {
if (!PlaybackService.isRunning) {
PlaybackService.startService(context, media, true, false);
}
context.sendBroadcast(new Intent(PlaybackService.ACTION_RESUME_PLAY_CURRENT_EPISODE));
}
else {

View File

@ -37,7 +37,6 @@ public class ExternalPlayerFragment extends Fragment {
private ImageButton butPlay;
private TextView mFeedName;
private ProgressBar mProgressBar;
private PlaybackController controller;
public ExternalPlayerFragment() {
@ -83,6 +82,11 @@ public class ExternalPlayerFragment extends Fragment {
controller.playPause();
}
});
loadMediaInfo();
}
public void connectToPlaybackService() {
controller.init();
}
private PlaybackController setupPlaybackController() {
@ -123,7 +127,11 @@ public class ExternalPlayerFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
controller.init();
if (PlaybackService.isRunning) {
controller.init();
} else {
controller.resumeServiceNotRunning();
}
onPositionObserverUpdate();
}
@ -164,13 +172,12 @@ public class ExternalPlayerFragment extends Fragment {
private boolean loadMediaInfo() {
Log.d(TAG, "Loading media info");
if (controller != null && controller.serviceAvailable()) {
if (controller != null) {
Playable media = controller.getMedia();
if (media != null) {
txtvTitle.setText(media.getEpisodeTitle());
mFeedName.setText(media.getFeedTitle());
mProgressBar.setProgress((int)
((double) controller.getPosition() / controller.getDuration() * 100));
onPositionObserverUpdate();
Glide.with(getActivity())
.load(media.getImageLocation())

View File

@ -34,6 +34,7 @@ import com.bumptech.glide.Glide;
import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.widget.IconButton;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.NetworkUtils;
import org.apache.commons.lang3.ArrayUtils;
@ -243,6 +244,9 @@ public class ItemFragment extends Fragment implements OnSwipeGesture {
if (item.hasMedia()) {
FeedMedia media = item.getMedia();
if (!media.isDownloaded()) {
if (!PlaybackService.isRunning) {
PlaybackService.startService(getActivity(), media, true, false);
}
DBTasks.playMedia(getActivity(), media, true, true, true);
((MainActivity) getActivity()).dismissChildFragment();
} else {

View File

@ -5,6 +5,7 @@ import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
@ -60,7 +61,7 @@ public class PlayerWidget extends AppWidgetProvider {
private void startUpdate(Context context) {
Log.d(TAG, "startUpdate() called with: " + "context = [" + context + "]");
context.startService(new Intent(context, PlayerWidgetService.class));
ContextCompat.startForegroundService(context, new Intent(context, PlayerWidgetService.class));
}
private void stopUpdate(Context context) {

View File

@ -44,6 +44,7 @@
android:layout_centerVertical="true"
android:contentDescription="@string/pause_label"
android:background="?attr/selectableItemBackground"
android:src="?attr/av_play_big"
tools:src="@drawable/ic_play_arrow_white_36dp"/>
<TextView

View File

@ -110,9 +110,9 @@
android:layout_centerHorizontal="true"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/pause_label"
android:src="?attr/av_pause"
android:src="?attr/av_play"
android:scaleType="fitCenter"
tools:src="@drawable/ic_pause_white_36dp"
tools:src="@drawable/ic_play_arrow_white_24dp"
tools:background="@android:color/holo_green_dark" />
<ImageButton

View File

@ -0,0 +1,13 @@
package de.danoeh.antennapod.core.event;
public class ServiceEvent {
public enum Action {
SERVICE_STARTED
}
public final Action action;
public ServiceEvent(Action action) {
this.action = action;
}
}

View File

@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.KeyEvent;
@ -29,7 +30,7 @@ public class MediaButtonReceiver extends BroadcastReceiver {
Intent serviceIntent = new Intent(context, PlaybackService.class);
serviceIntent.putExtra(EXTRA_KEYCODE, event.getKeyCode());
serviceIntent.putExtra(EXTRA_SOURCE, event.getSource());
context.startService(serviceIntent);
ContextCompat.startForegroundService(context, serviceIntent);
}
}

View File

@ -8,6 +8,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
@ -58,6 +59,18 @@ public class GpodnetSyncService extends Service {
private boolean syncSubscriptions = false;
private boolean syncActions = false;
private static final int NOTIFICATION_ID = 2;
@Override
public void onCreate() {
super.onCreate();
startForeground(NOTIFICATION_ID,
new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_GPODNET)
.setSmallIcon(R.drawable.stat_notify_sync)
.setContentTitle(getString(R.string.gpodnet_main_label))
.setContentText(getString(R.string.synchronizing))
.build());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
@ -110,6 +123,7 @@ public class GpodnetSyncService extends Service {
private synchronized void sync() {
if (!GpodnetPreferences.loggedIn() || !NetworkUtils.networkAvailable()) {
stopForeground(true);
stopSelf();
return;
}
@ -126,6 +140,7 @@ public class GpodnetSyncService extends Service {
}
syncActions = false;
}
stopForeground(true);
stopSelf();
}
@ -394,7 +409,7 @@ public class GpodnetSyncService extends Service {
if (GpodnetPreferences.loggedIn()) {
Intent intent = new Intent(context, GpodnetSyncService.class);
intent.putExtra(ARG_ACTION, ACTION_SYNC);
context.startService(intent);
ContextCompat.startForegroundService(context, intent);
}
}
@ -402,7 +417,7 @@ public class GpodnetSyncService extends Service {
if (GpodnetPreferences.loggedIn()) {
Intent intent = new Intent(context, GpodnetSyncService.class);
intent.putExtra(ARG_ACTION, ACTION_SYNC_SUBSCRIPTIONS);
context.startService(intent);
ContextCompat.startForegroundService(context, intent);
}
}
@ -410,7 +425,7 @@ public class GpodnetSyncService extends Service {
if (GpodnetPreferences.loggedIn()) {
Intent intent = new Intent(context, GpodnetSyncService.class);
intent.putExtra(ARG_ACTION, ACTION_SYNC_ACTIONS);
context.startService(intent);
ContextCompat.startForegroundService(context, intent);
}
}
}

View File

@ -296,6 +296,7 @@ public class DownloadService extends Service {
setupNotificationBuilders();
requester = DownloadRequester.getInstance();
startForeground(NOTIFICATION_ID, updateNotifications());
}
@Override
@ -353,7 +354,7 @@ public class DownloadService extends Service {
/**
* Updates the contents of the service's notifications. Should be called
* before setupNotificationBuilders.
* after setupNotificationBuilders.
*/
private Notification updateNotifications() {
if (notificationCompatBuilder == null) {

View File

@ -24,6 +24,7 @@ import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat;
import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaBrowserServiceCompat;
import android.support.v4.media.MediaDescriptionCompat;
@ -49,6 +50,7 @@ import java.util.List;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.event.ServiceEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
@ -314,6 +316,34 @@ public class PlaybackService extends MediaBrowserServiceCompat {
flavorHelper.initializeMediaPlayer(PlaybackService.this);
mediaSession.setActive(true);
NotificationCompat.Builder notificationBuilder = createBasicNotification();
startForeground(NOTIFICATION_ID, notificationBuilder.build());
EventBus.getDefault().post(new ServiceEvent(ServiceEvent.Action.SERVICE_STARTED));
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia();
Playable lastPlayable = Playable.PlayableUtils.createInstanceFromPreferences(
getApplicationContext(), (int) currentlyPlayingMedia, prefs);
setupNotification(lastPlayable);
}
private NotificationCompat.Builder createBasicNotification() {
final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext());
final PendingIntent pIntent = PendingIntent.getActivity(this, 0,
PlaybackService.getPlayerActivityIntent(this),
PendingIntent.FLAG_UPDATE_CURRENT);
return new NotificationCompat.Builder(
this, NotificationUtils.CHANNEL_ID_PLAYING)
.setContentTitle(getString(R.string.app_name))
.setContentText("Service is running") // Just in case the notification is not updated (should not occur)
.setOngoing(false)
.setContentIntent(pIntent)
.setWhen(0) // we don't need the time
.setSmallIcon(smallIcon)
.setPriority(NotificationCompat.PRIORITY_MIN);
}
@Override
@ -568,8 +598,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
public void notifyVideoSurfaceAbandoned() {
stopForeground(!UserPreferences.isPersistNotify());
mediaPlayer.pause(true, false);
mediaPlayer.resetVideoSurface();
setupNotification(getPlayable());
stopForeground(!UserPreferences.isPersistNotify());
}
private final PlaybackServiceTaskManager.PSTMCallback taskManagerCallback = new PlaybackServiceTaskManager.PSTMCallback() {
@ -763,6 +795,15 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
};
public static void startService(final Context context, final Playable media, boolean startWhenPrepared, boolean shouldStream) {
Intent launchIntent = new Intent(context, PlaybackService.class);
launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, startWhenPrepared);
launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream);
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true);
ContextCompat.startForegroundService(context, launchIntent);
}
private Playable getNextInQueue(final Playable currentMedia) {
if (!(currentMedia instanceof FeedMedia)) {
Log.d(TAG, "getNextInQueue(), but playable not an instance of FeedMedia, so not proceeding");
@ -1172,10 +1213,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
* Prepares notification and starts the service in the foreground.
*/
private void setupNotification(final PlaybackServiceMediaPlayer.PSMPInfo info) {
final PendingIntent pIntent = PendingIntent.getActivity(this, 0,
PlaybackService.getPlayerActivityIntent(this),
PendingIntent.FLAG_UPDATE_CURRENT);
setupNotification(info.playable);
}
private synchronized void setupNotification(final Playable playable) {
if (notificationSetupThread != null) {
notificationSetupThread.interrupt();
}
@ -1185,12 +1226,12 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public void run() {
Log.d(TAG, "Starting background work");
if (info.playable != null) {
if (playable != null) {
int iconSize = getResources().getDimensionPixelSize(
android.R.dimen.notification_large_icon_width);
try {
icon = Glide.with(PlaybackService.this)
.load(info.playable.getImageLocation())
.load(playable.getImageLocation())
.asBitmap()
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
.centerCrop()
@ -1209,24 +1250,18 @@ public class PlaybackService extends MediaBrowserServiceCompat {
return;
}
PlayerStatus playerStatus = mediaPlayer.getPlayerStatus();
final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext());
if (!Thread.currentThread().isInterrupted() && started && info.playable != null) {
String contentText = info.playable.getEpisodeTitle();
String contentTitle = info.playable.getFeedTitle();
if (!Thread.currentThread().isInterrupted() && started && playable != null) {
String contentText = playable.getEpisodeTitle();
String contentTitle = playable.getFeedTitle();
Notification notification;
// Builder is v7, even if some not overwritten methods return its parent's v4 interface
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
PlaybackService.this, NotificationUtils.CHANNEL_ID_PLAYING)
.setContentTitle(contentTitle)
NotificationCompat.Builder notificationBuilder = createBasicNotification();
notificationBuilder.setContentTitle(contentTitle)
.setContentText(contentText)
.setOngoing(false)
.setContentIntent(pIntent)
.setLargeIcon(icon)
.setSmallIcon(smallIcon)
.setWhen(0) // we don't need the time
.setPriority(UserPreferences.getNotifyPriority()); // set notification priority
.setPriority(UserPreferences.getNotifyPriority())
.setLargeIcon(icon); // set notification priority
IntList compactActionList = new IntList();
int numActions = 0; // we start and 0 and then increment by 1 for each call to addAction

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import java.util.ArrayList;
@ -123,16 +124,7 @@ public final class DBTasks {
media);
}
}
// Start playback Service
Intent launchIntent = new Intent(context, PlaybackService.class);
launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
startWhenPrepared);
launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM,
shouldStream);
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
true);
context.startService(launchIntent);
PlaybackService.startService(context, media, startWhenPrepared, shouldStream);
if (showPlayer) {
// Launch media player
context.startActivity(PlaybackService.getPlayerActivityIntent(

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.URLUtil;
@ -81,7 +82,7 @@ public class DownloadRequester {
Intent launchIntent = new Intent(context, DownloadService.class);
launchIntent.putExtra(DownloadService.EXTRA_REQUEST, request);
context.startService(launchIntent);
ContextCompat.startForegroundService(context, launchIntent);
return true;
}

View File

@ -13,6 +13,7 @@ public class NotificationUtils {
public static final String CHANNEL_ID_DOWNLOADING = "downloading";
public static final String CHANNEL_ID_PLAYING = "playing";
public static final String CHANNEL_ID_ERROR = "error";
public static final String CHANNEL_ID_GPODNET = "gpodnet";
public static void createChannels(Context context) {
if (android.os.Build.VERSION.SDK_INT < 26) {
@ -25,6 +26,7 @@ public class NotificationUtils {
mNotificationManager.createNotificationChannel(createChannelDownloading(context));
mNotificationManager.createNotificationChannel(createChannelPlaying(context));
mNotificationManager.createNotificationChannel(createChannelError(context));
mNotificationManager.createNotificationChannel(createChannelGpodnet(context));
}
}
@ -59,4 +61,12 @@ public class NotificationUtils {
mChannel.setDescription(c.getString(R.string.notification_channel_error_description));
return mChannel;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private static NotificationChannel createChannelGpodnet(Context c) {
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_GPODNET,
c.getString(R.string.notification_channel_gpodnet), NotificationManager.IMPORTANCE_MIN);
mChannel.setDescription(c.getString(R.string.notification_channel_gpodnet_description));
return mChannel;
}
}

View File

@ -14,6 +14,7 @@ import android.os.Build;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@ -59,7 +60,7 @@ public abstract class PlaybackController {
private PlaybackService playbackService;
private Playable media;
private PlayerStatus status;
private PlayerStatus status = PlayerStatus.STOPPED;
private final ScheduledThreadPoolExecutor schedExecutor;
private static final int SCHED_EX_POOLSIZE = 1;
@ -69,6 +70,7 @@ public abstract class PlaybackController {
private boolean mediaInfoLoaded = false;
private boolean released = false;
private boolean initialized = false;
private Subscription serviceBinder;
@ -92,10 +94,14 @@ public abstract class PlaybackController {
}
/**
* Creates a new connection to the playbackService. Should be called in the
* activity's onResume() method.
* Creates a new connection to the playbackService.
*/
public void init() {
public synchronized void init() {
if (initialized) {
return;
}
initialized = true;
activity.registerReceiver(statusUpdate, new IntentFilter(
PlaybackService.ACTION_PLAYER_STATUS_CHANGED));
@ -167,7 +173,7 @@ public abstract class PlaybackController {
*/
private void bindToService() {
Log.d(TAG, "Trying to connect to service");
if(serviceBinder != null) {
if (serviceBinder != null) {
serviceBinder.unsubscribe();
}
serviceBinder = Observable.fromCallable(this::getPlayLastPlayedMediaIntent)
@ -178,7 +184,7 @@ public abstract class PlaybackController {
if (!PlaybackService.started) {
if (intent != null) {
Log.d(TAG, "Calling start service");
activity.startService(intent);
ContextCompat.startForegroundService(activity, intent);
bound = activity.bindService(intent, mConnection, 0);
} else {
status = PlayerStatus.STOPPED;
@ -194,32 +200,37 @@ public abstract class PlaybackController {
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
private Playable getMediaFromPreferences() {
long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia();
if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
activity.getApplicationContext());
return PlayableUtils.createInstanceFromPreferences(activity,
(int) currentlyPlayingMedia, prefs);
}
return null;
}
/**
* Returns an intent that starts the PlaybackService and plays the last
* played media or null if no last played media could be found.
*/
private Intent getPlayLastPlayedMediaIntent() {
Log.d(TAG, "Trying to restore last played media");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
activity.getApplicationContext());
long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia();
if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) {
Playable media = PlayableUtils.createInstanceFromPreferences(activity,
(int) currentlyPlayingMedia, prefs);
if (media != null) {
Intent serviceIntent = new Intent(activity, PlaybackService.class);
serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false);
serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true);
boolean fileExists = media.localFileAvailable();
boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream();
if (!fileExists && !lastIsStream && media instanceof FeedMedia) {
DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media);
}
serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM,
lastIsStream || !fileExists);
return serviceIntent;
Playable media = getMediaFromPreferences();
if (media != null) {
Intent serviceIntent = new Intent(activity, PlaybackService.class);
serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false);
serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true);
boolean fileExists = media.localFileAvailable();
boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream();
if (!fileExists && !lastIsStream && media instanceof FeedMedia) {
DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media);
}
serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM,
lastIsStream || !fileExists);
return serviceIntent;
}
Log.d(TAG, "No last played media found");
return null;
@ -511,7 +522,7 @@ public abstract class PlaybackController {
"PlaybackService has no media object. Trying to restore last played media.");
Intent serviceIntent = getPlayLastPlayedMediaIntent();
if (serviceIntent != null) {
activity.startService(serviceIntent);
ContextCompat.startForegroundService(activity, serviceIntent);
}
}
*/
@ -576,6 +587,7 @@ public abstract class PlaybackController {
public void playPause() {
if (playbackService == null) {
PlaybackService.startService(activity, media, true, false);
Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!");
return;
}
@ -609,6 +621,8 @@ public abstract class PlaybackController {
public int getPosition() {
if (playbackService != null) {
return playbackService.getCurrentPosition();
} else if (media != null) {
return media.getPosition();
} else {
return PlaybackService.INVALID_TIME;
}
@ -617,12 +631,17 @@ public abstract class PlaybackController {
public int getDuration() {
if (playbackService != null) {
return playbackService.getDuration();
} else if (media != null) {
return media.getDuration();
} else {
return PlaybackService.INVALID_TIME;
}
}
public Playable getMedia() {
if (media == null) {
media = getMediaFromPreferences();
}
return media;
}
@ -714,8 +733,13 @@ public abstract class PlaybackController {
}
public boolean isPlayingVideoLocally() {
return playbackService != null && PlaybackService.getCurrentMediaType() == MediaType.VIDEO
&& !PlaybackService.isCasting();
if (PlaybackService.isCasting()) {
return false;
} else if (playbackService != null) {
return PlaybackService.getCurrentMediaType() == MediaType.VIDEO;
} else {
return getMedia() != null && getMedia().getMediaType() == MediaType.VIDEO;
}
}
public Pair<Integer, Integer> getVideoSize() {
@ -755,6 +779,18 @@ public abstract class PlaybackController {
}
}
public void resumeServiceNotRunning() {
if (getMedia().getMediaType() == MediaType.AUDIO) {
TypedArray res = activity.obtainStyledAttributes(new int[]{
de.danoeh.antennapod.core.R.attr.av_play_big});
getPlayButton().setImageResource(
res.getResourceId(0, de.danoeh.antennapod.core.R.drawable.ic_play_arrow_grey600_36dp));
res.recycle();
} else {
getPlayButton().setImageResource(R.drawable.ic_av_play_circle_outline_80dp);
}
}
/**
* Refreshes the current position of the media file that is playing.
*/

View File

@ -29,6 +29,7 @@
<string name="free_space_label">%1$s free</string>
<string name="episode_cache_full_title">Episode cache full</string>
<string name="episode_cache_full_message">The episode cache limit has been reached. You can increase the cache size in the Settings.</string>
<string name="synchronizing">Synchronizing…</string>
<!-- Statistics fragment -->
<string name="total_time_listened_to_podcasts">Total time of podcasts played:</string>
@ -719,4 +720,6 @@
<string name="notification_channel_playing_description">Allows to control playback</string>
<string name="notification_channel_error">Errors</string>
<string name="notification_channel_error_description">Shown if something went wrong</string>
<string name="notification_channel_gpodnet">gpodder.net</string>
<string name="notification_channel_gpodnet_description">Shown while currently synchronizing</string>
</resources>