add cast disconnect buttons
|
@ -103,6 +103,9 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
|
|||
return;
|
||||
}
|
||||
super.setupGUI();
|
||||
if(butCastDisconnect != null) {
|
||||
butCastDisconnect.setVisibility(View.GONE);
|
||||
}
|
||||
if(butPlaybackSpeed != null) {
|
||||
butPlaybackSpeed.setOnClickListener(v -> {
|
||||
if (controller == null) {
|
||||
|
|
|
@ -49,5 +49,9 @@ public class CastplayerActivity extends MediaplayerInfoActivity {
|
|||
if (butPlaybackSpeed != null) {
|
||||
butPlaybackSpeed.setVisibility(View.GONE);
|
||||
}
|
||||
if (butCastDisconnect != null) {
|
||||
butCastDisconnect.setOnClickListener(v -> castManager.disconnect());
|
||||
butCastDisconnect.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.viewpagerindicator.CirclePageIndicator;
|
||||
|
@ -85,6 +86,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||
};
|
||||
|
||||
protected Button butPlaybackSpeed;
|
||||
protected ImageButton butCastDisconnect;
|
||||
private DrawerLayout drawerLayout;
|
||||
private NavListAdapter navAdapter;
|
||||
private ListView navList;
|
||||
|
@ -250,6 +252,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||
});
|
||||
|
||||
butPlaybackSpeed = (Button) findViewById(R.id.butPlaybackSpeed);
|
||||
butCastDisconnect = (ImageButton) findViewById(R.id.butCastDisconnect);
|
||||
|
||||
pager = (ViewPager) findViewById(R.id.pager);
|
||||
pagerAdapter = new MediaplayerInfoPagerAdapter(getSupportFragmentManager(), media);
|
||||
|
|
|
@ -152,6 +152,21 @@
|
|||
android:src="?attr/av_fast_forward"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:textAllCaps="false"
|
||||
tools:visibility="gone"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/butCastDisconnect"
|
||||
android:layout_width="@dimen/audioplayer_playercontrols_length"
|
||||
android:layout_height="@dimen/audioplayer_playercontrols_length"
|
||||
android:layout_toLeftOf="@id/butRev"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:contentDescription="@string/cast_disconnect_label"
|
||||
android:src="?attr/ic_cast_disconnect"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:src="@drawable/ic_cast_disconnect_white_36dp"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<ImageButton
|
||||
|
|
|
@ -47,8 +47,8 @@ import java.util.List;
|
|||
import de.danoeh.antennapod.core.ClientConfig;
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.cast.CastConsumer;
|
||||
import de.danoeh.antennapod.core.cast.DefaultCastConsumer;
|
||||
import de.danoeh.antennapod.core.cast.CastManager;
|
||||
import de.danoeh.antennapod.core.cast.DefaultCastConsumer;
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
|
@ -84,6 +84,10 @@ public class PlaybackService extends Service {
|
|||
* Parcelable of type Playable.
|
||||
*/
|
||||
public static final String EXTRA_PLAYABLE = "PlaybackService.PlayableExtra";
|
||||
/**
|
||||
* True if cast session should disconnect.
|
||||
*/
|
||||
public static final String EXTRA_CAST_DISCONNECT = "extra.de.danoeh.antennapod.core.service.castDisconnect";
|
||||
/**
|
||||
* True if media should be streamed.
|
||||
*/
|
||||
|
@ -361,8 +365,9 @@ public class PlaybackService extends Service {
|
|||
|
||||
Log.d(TAG, "OnStartCommand called");
|
||||
final int keycode = intent.getIntExtra(MediaButtonReceiver.EXTRA_KEYCODE, -1);
|
||||
final boolean castDisconnect = intent.getBooleanExtra(EXTRA_CAST_DISCONNECT, false);
|
||||
final Playable playable = intent.getParcelableExtra(EXTRA_PLAYABLE);
|
||||
if (keycode == -1 && playable == null) {
|
||||
if (keycode == -1 && playable == null && !castDisconnect) {
|
||||
Log.e(TAG, "PlaybackService was started with no arguments");
|
||||
stopSelf();
|
||||
return Service.START_REDELIVER_INTENT;
|
||||
|
@ -377,6 +382,8 @@ public class PlaybackService extends Service {
|
|||
Log.d(TAG, "Received media button event");
|
||||
handleKeycode(keycode, intent.getIntExtra(MediaButtonReceiver.EXTRA_SOURCE,
|
||||
InputDevice.SOURCE_CLASS_NONE));
|
||||
} else if (castDisconnect) {
|
||||
castManager.disconnect();
|
||||
} else {
|
||||
started = true;
|
||||
boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM,
|
||||
|
@ -556,12 +563,13 @@ public class PlaybackService extends Service {
|
|||
taskManager.cancelPositionSaver();
|
||||
saveCurrentPosition(false, 0);
|
||||
taskManager.cancelWidgetUpdater();
|
||||
if (UserPreferences.isPersistNotify() && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if ((UserPreferences.isPersistNotify() || isCasting) &&
|
||||
android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
// do not remove notification on pause based on user pref and whether android version supports expanded notifications
|
||||
// Change [Play] button to [Pause]
|
||||
setupNotification(newInfo);
|
||||
} else if (!UserPreferences.isPersistNotify()) {
|
||||
// remove notifcation on pause
|
||||
} else if (!UserPreferences.isPersistNotify() && !isCasting) {
|
||||
// remove notification on pause
|
||||
stopForeground(true);
|
||||
}
|
||||
writePlayerStatusPlaybackPreferences();
|
||||
|
@ -1052,6 +1060,17 @@ public class PlaybackService extends Service {
|
|||
|
||||
int numActions = 0; // we start and 0 and then increment by 1 for each call to addAction
|
||||
|
||||
if (isCasting) {
|
||||
Intent stopCastingIntent = new Intent(PlaybackService.this, PlaybackService.class);
|
||||
stopCastingIntent.putExtra(EXTRA_CAST_DISCONNECT, true);
|
||||
PendingIntent stopCastingPendingIntent = PendingIntent.getService(PlaybackService.this,
|
||||
numActions, stopCastingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
notificationBuilder.addAction(R.drawable.ic_media_cast_disconnect,
|
||||
getString(R.string.cast_disconnect_label),
|
||||
stopCastingPendingIntent);
|
||||
numActions++;
|
||||
}
|
||||
|
||||
// always let them rewind
|
||||
PendingIntent rewindButtonPendingIntent = getPendingIntentForMediaAction(
|
||||
KeyEvent.KEYCODE_MEDIA_REWIND, numActions);
|
||||
|
@ -1116,7 +1135,8 @@ public class PlaybackService extends Service {
|
|||
|
||||
if (playerStatus == PlayerStatus.PLAYING ||
|
||||
playerStatus == PlayerStatus.PREPARING ||
|
||||
playerStatus == PlayerStatus.SEEKING) {
|
||||
playerStatus == PlayerStatus.SEEKING ||
|
||||
isCasting) {
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
} else {
|
||||
stopForeground(false);
|
||||
|
@ -1531,6 +1551,16 @@ public class PlaybackService extends Service {
|
|||
// hardware volume buttons control the local device volume
|
||||
mediaRouter.setMediaSessionCompat(null);
|
||||
unregisterWifiBroadcastReceiver();
|
||||
PlayerStatus status = info.playerStatus;
|
||||
if ((status == PlayerStatus.PLAYING ||
|
||||
status == PlayerStatus.SEEKING ||
|
||||
status == PlayerStatus.PREPARING ||
|
||||
UserPreferences.isPersistNotify()) &&
|
||||
android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
setupNotification(info);
|
||||
} else if (!UserPreferences.isPersistNotify()){
|
||||
stopForeground(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1632,14 +1662,17 @@ public class PlaybackService extends Service {
|
|||
saveCurrentPosition(false, 0);
|
||||
}
|
||||
}
|
||||
if (info == null) {
|
||||
info = new PlaybackServiceMediaPlayer.PSMPInfo(PlayerStatus.STOPPED, null);
|
||||
}
|
||||
sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, EXTRA_CODE_CAST);
|
||||
switchMediaPlayer(new RemotePSMP(PlaybackService.this, mediaPlayerCallback),
|
||||
(info != null) ? info :
|
||||
new PlaybackServiceMediaPlayer.PSMPInfo(PlayerStatus.STOPPED, null),
|
||||
info,
|
||||
wasLaunched);
|
||||
// hardware volume buttons control the remote device volume
|
||||
mediaRouter.setMediaSessionCompat(mediaSession);
|
||||
registerWifiBroadcastReceiver();
|
||||
setupNotification(info);
|
||||
}
|
||||
|
||||
private void switchMediaPlayer(@NonNull PlaybackServiceMediaPlayer newPlayer,
|
||||
|
|
|
@ -20,13 +20,12 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import de.danoeh.antennapod.core.cast.CastConsumer;
|
||||
import de.danoeh.antennapod.core.cast.DefaultCastConsumer;
|
||||
import de.danoeh.antennapod.core.cast.CastManager;
|
||||
import de.danoeh.antennapod.core.cast.CastUtils;
|
||||
import de.danoeh.antennapod.core.cast.DefaultCastConsumer;
|
||||
import de.danoeh.antennapod.core.cast.RemoteMedia;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.MediaType;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.cast.CastUtils;
|
||||
import de.danoeh.antennapod.core.util.RewindAfterPauseUtils;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
|
||||
|
@ -150,6 +149,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
setBuffering(false);
|
||||
setPlayerStatus(PlayerStatus.INDETERMINATE, null);
|
||||
return;
|
||||
} else {
|
||||
Log.d(TAG, "Received remote status/media update. New state=" + status.getPlayerState());
|
||||
}
|
||||
Playable currentMedia = localVersion(status.getMediaInfo());
|
||||
if (currentMedia != null) {
|
||||
|
@ -196,6 +197,10 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
case MediaStatus.PLAYER_STATE_UNKNOWN:
|
||||
//is this right?
|
||||
setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Remote media state undetermined!");
|
||||
setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +270,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
@Override
|
||||
public void resume() {
|
||||
try {
|
||||
setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
|
||||
// TODO see comment on prepare()
|
||||
// setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
|
||||
if (playerStatus == PlayerStatus.PREPARED && media.getPosition() > 0) {
|
||||
int newPosition = RewindAfterPauseUtils.calculatePositionWithRewind(
|
||||
media.getPosition(),
|
||||
|
@ -306,7 +312,9 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
position,
|
||||
media.getLastPlayedTime());
|
||||
}
|
||||
setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
|
||||
// TODO We're not supporting user set stream volume yet, as we need to make a UI
|
||||
// that doesn't allow changing playback speed or have different values for left/right
|
||||
//setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
|
||||
castMgr.loadMedia(remoteMedia, startWhenPrepared.get(), position);
|
||||
} catch (TransientNetworkDisconnectionException | NoConnectionException e) {
|
||||
Log.e(TAG, "Error loading media", e);
|
||||
|
|
After Width: | Height: | Size: 417 B |
After Width: | Height: | Size: 770 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 975 B |
After Width: | Height: | Size: 867 B |
After Width: | Height: | Size: 961 B |
After Width: | Height: | Size: 979 B |
After Width: | Height: | Size: 976 B |
After Width: | Height: | Size: 982 B |
After Width: | Height: | Size: 493 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 562 B |
After Width: | Height: | Size: 333 B |
After Width: | Height: | Size: 536 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 808 B |
After Width: | Height: | Size: 693 B |
After Width: | Height: | Size: 635 B |
After Width: | Height: | Size: 684 B |
After Width: | Height: | Size: 696 B |
After Width: | Height: | Size: 690 B |
After Width: | Height: | Size: 694 B |
After Width: | Height: | Size: 379 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 280 B |
After Width: | Height: | Size: 447 B |
After Width: | Height: | Size: 447 B |
After Width: | Height: | Size: 976 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 526 B |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 221 B |
After Width: | Height: | Size: 678 B |
After Width: | Height: | Size: 584 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 317 B |
After Width: | Height: | Size: 955 B |
After Width: | Height: | Size: 805 B |
After Width: | Height: | Size: 400 B |
After Width: | Height: | Size: 1.2 KiB |
|
@ -50,6 +50,7 @@
|
|||
<attr name="ic_sort" format="reference"/>
|
||||
<attr name="ic_sd_storage" format="reference"/>
|
||||
<attr name="ic_create_new_folder" format="reference"/>
|
||||
<attr name="ic_cast_disconnect" format="reference"/>
|
||||
|
||||
<!-- Used in itemdescription -->
|
||||
<attr name="non_transparent_background" format="reference"/>
|
||||
|
|
|
@ -618,6 +618,7 @@
|
|||
|
||||
<!-- Casting -->
|
||||
<string name="cast_media_route_menu_title">Play on…</string>
|
||||
<string name="cast_disconnect_label">Disconnect the cast session</string>
|
||||
<string name="cast_failed_to_play">Failed to start the playback of media</string>
|
||||
<string name="cast_failed_to_stop">Failed to stop the playback of media</string>
|
||||
<string name="cast_failed_to_pause">Failed to pause the playback of media</string>
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
<item name="attr/ic_sort">@drawable/ic_sort_grey600_24dp</item>
|
||||
<item name="attr/ic_sd_storage">@drawable/ic_sd_storage_grey600_36dp</item>
|
||||
<item name="attr/ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item>
|
||||
<item name="attr/ic_cast_disconnect">@drawable/ic_cast_disconnect_grey600_36dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.Dark" parent="Theme.AppCompat">
|
||||
|
@ -115,6 +116,7 @@
|
|||
<item name="attr/ic_sort">@drawable/ic_sort_white_24dp</item>
|
||||
<item name="attr/ic_sd_storage">@drawable/ic_sd_storage_white_36dp</item>
|
||||
<item name="attr/ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item>
|
||||
<item name="attr/ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
|
@ -174,6 +176,7 @@
|
|||
<item name="attr/ic_sort">@drawable/ic_sort_grey600_24dp</item>
|
||||
<item name="attr/ic_sd_storage">@drawable/ic_sd_storage_grey600_36dp</item>
|
||||
<item name="attr/ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item>
|
||||
<item name="attr/ic_cast_disconnect">@drawable/ic_cast_disconnect_grey600_36dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.Dark.NoTitle" parent="Theme.AppCompat.NoActionBar">
|
||||
|
@ -233,6 +236,7 @@
|
|||
<item name="attr/ic_sort">@drawable/ic_sort_white_24dp</item>
|
||||
<item name="attr/ic_sd_storage">@drawable/ic_sd_storage_white_36dp</item>
|
||||
<item name="attr/ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item>
|
||||
<item name="attr/ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.VideoPlayer" parent="@style/Theme.AntennaPod.Dark">
|
||||
|
|