Skip to content

Commit d5dc729

Browse files
author
Chris Bellew
committed
Finished fixing playing of all songs by an artist. Fixed triggering new playback from mic button on now playing screen with Chromecast.
1 parent 6630e28 commit d5dc729

File tree

15 files changed

+420
-235
lines changed

15 files changed

+420
-235
lines changed

mobile/src/main/AndroidManifest.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools"
44
package="com.atomjack.vcfp"
5-
android:versionCode="51"
6-
android:versionName="2.0.5b2" >
5+
android:versionCode="52"
6+
android:versionName="2.0.5b3" >
77

88
<uses-permission android:name="com.mohammadag.googlesearchapi.permission.ACCESS_GGOGLE_SEARCH_API" />
99
<uses-permission android:name="android.permission.INTERNET" />
@@ -59,6 +59,7 @@
5959
</activity>
6060
<activity
6161
android:name=".activities.CastActivity"
62+
android:launchMode="singleTask"
6263
android:configChanges="orientation|screenSize"
6364
android:label="@string/app_name" >
6465
<intent-filter>

mobile/src/main/java/com/atomjack/vcfp/CastPlayerManager.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,13 @@ public void setContext(Context context) {
103103
mContext = context;
104104
}
105105

106+
107+
106108
public void subscribe(final PlexClient _client) {
109+
subscribe(_client, null);
110+
}
111+
112+
public void subscribe(final PlexClient _client, final Runnable onFinished) {
107113
if(castManager == null) {
108114
Logger.d("creating castManager");
109115
castManager = getCastManager(mContext);
@@ -148,6 +154,9 @@ public void run() {
148154
listener.onCastConnected(_client);
149155
else
150156
Logger.d("[CastPlayerManager] listener is null");
157+
158+
if(onFinished != null)
159+
onFinished.run();
151160
}
152161
});
153162
}
@@ -241,12 +250,13 @@ public void onSuccess(Connection connection) {
241250
try {
242251
obj.put(PARAMS.ACTION, PARAMS.ACTION_SEEK);
243252
obj.put(PARAMS.OFFSET, seconds);
244-
if(nowPlayingMedia instanceof PlexVideo)
253+
if (nowPlayingMedia instanceof PlexVideo)
245254
obj.put(PARAMS.SRC, getTranscodeUrl(nowPlayingMedia, connection, seconds));
246255
obj.put(PARAMS.RESUME, VoiceControlForPlexApplication.getInstance().prefs.get(Preferences.RESUME, false));
247256
sendMessage(obj);
248257
listener.onCastSeek();
249-
} catch (Exception ex) {}
258+
} catch (Exception ex) {
259+
}
250260
}
251261

252262
@Override
@@ -326,17 +336,20 @@ public void onDataMessageReceived(String message) {
326336
if(obj.getString("event").equals(RECEIVER_EVENTS.PLAYER_STATUS_CHANGED)) {
327337
Logger.d("playerStatusChanged: %s", obj.getString("status"));
328338
currentState = PlayerState.getState(obj.getString("status"));
329-
listener.onCastPlayerStateChanged(currentState);
339+
if(listener != null)
340+
listener.onCastPlayerStateChanged(currentState);
330341
}
331342
} else if(obj.has("event") && obj.getString("event").equals(RECEIVER_EVENTS.TIME_UPDATE) && obj.has("currentTime")) {
332-
listener.onCastPlayerTimeUpdate(obj.getInt("currentTime"));
343+
if(listener != null)
344+
listener.onCastPlayerTimeUpdate(obj.getInt("currentTime"));
333345
} else if(obj.has("event") && obj.getString("event").equals(RECEIVER_EVENTS.PLAYLIST_ADVANCE) && obj.has("media") && obj.has("type")) {
334346
Logger.d("[CastPlayerManager] playlistAdvance");
335347
if(obj.getString("type").equals(PARAMS.MEDIA_TYPE_VIDEO))
336348
nowPlayingMedia = VoiceControlForPlexApplication.gsonRead.fromJson(obj.getString("media"), PlexVideo.class);
337349
else
338350
nowPlayingMedia = VoiceControlForPlexApplication.gsonRead.fromJson(obj.getString("media"), PlexTrack.class);
339-
listener.onCastPlayerPlaylistAdvance(nowPlayingMedia);
351+
if(listener != null)
352+
listener.onCastPlayerPlaylistAdvance(nowPlayingMedia);
340353
} else if(obj.has("event") && obj.getString("event").equals(RECEIVER_EVENTS.GET_PLAYBACK_STATE) && obj.has("state")) {
341354
currentState = PlayerState.getState(obj.getString("state"));
342355
PlexMedia media = null;
@@ -347,10 +360,12 @@ public void onDataMessageReceived(String message) {
347360
media = VoiceControlForPlexApplication.gsonRead.fromJson(obj.getString("media"), PlexTrack.class);
348361
mClient = VoiceControlForPlexApplication.gsonRead.fromJson(obj.getString("client"), PlexClient.class);
349362
}
350-
listener.onCastPlayerState(PlayerState.getState(obj.getString("state")), media);
363+
if(listener != null)
364+
listener.onCastPlayerState(PlayerState.getState(obj.getString("state")), media);
351365
} else if(obj.has("event") && obj.getString("event").equals(RECEIVER_EVENTS.DEVICE_CAPABILITIES) && obj.has("capabilities")) {
352366
Capabilities capabilities = VoiceControlForPlexApplication.gsonRead.fromJson(obj.getString("capabilities"), Capabilities.class);
353-
listener.onGetDeviceCapabilities(capabilities);
367+
if(listener != null)
368+
listener.onGetDeviceCapabilities(capabilities);
354369
}
355370
} catch (Exception ex) {
356371
ex.printStackTrace();
@@ -479,8 +494,8 @@ public JSONObject buildMedia(Connection connection, int offset) {
479494
data.put(PARAMS.RESUME, VoiceControlForPlexApplication.getInstance().prefs.get(Preferences.RESUME, false));
480495
data.put(PARAMS.CLIENT, VoiceControlForPlexApplication.gsonWrite.toJson(mClient));
481496
data.put(PARAMS.SRC, getTranscodeUrl(nowPlayingMedia, connection, offset));
497+
Logger.d("[CastPlayerManager] setting src to %s", getTranscodeUrl(nowPlayingMedia, connection, offset));
482498
data.put(PARAMS.ACCESS_TOKEN, nowPlayingMedia.server.accessToken);
483-
Logger.d("token: %s", nowPlayingMedia.server.accessToken);
484499
data.put(PARAMS.PLAYLIST, getPlaylistJson());
485500
} catch (Exception ex) {
486501
ex.printStackTrace();
@@ -504,6 +519,10 @@ public PlexMedia getNowPlayingMedia() {
504519
return nowPlayingMedia;
505520
}
506521

522+
public List<PlexMedia> getNowPlayingAlbum() {
523+
return nowPlayingAlbum;
524+
}
525+
507526
public String getSessionId() {
508527
return mSessionId;
509528
}

mobile/src/main/java/com/atomjack/vcfp/activities/CastActivity.java

Lines changed: 128 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import android.app.Dialog;
44
import android.os.Bundle;
5+
import android.os.Handler;
56
import android.view.Menu;
67
import android.view.View;
78
import android.widget.SeekBar;
89

10+
import com.atomjack.shared.Intent;
911
import com.atomjack.shared.SendToDataLayerThread;
1012
import com.atomjack.shared.WearConstants;
1113
import com.atomjack.vcfp.interfaces.AfterTransientTokenRequest;
@@ -19,7 +21,7 @@
1921
import com.atomjack.vcfp.model.PlexMedia;
2022
import com.google.android.libraries.cast.companionlibrary.cast.VideoCastManager;
2123

22-
import java.util.Arrays;
24+
import java.util.ArrayList;
2325
import java.util.List;
2426

2527
public class CastActivity extends PlayerActivity {
@@ -28,54 +30,151 @@ public class CastActivity extends PlayerActivity {
2830

2931
private PlayerState currentState = PlayerState.STOPPED;
3032

31-
private List<PlexMedia> nowPlayingAlbum;
33+
private List<PlexMedia> nowPlayingAlbum = new ArrayList<>();
3234

3335
private Dialog infoDialog;
3436

35-
@Override
37+
final Handler handler = new Handler();
38+
39+
private boolean uiShowing = false;
40+
41+
private void start(final boolean setView) {
42+
mClient = getIntent().getParcelableExtra(Intent.EXTRA_CLIENT);
43+
Logger.d("[CastActivity] set mClient: %s", mClient);
44+
45+
if(getIntent().getBooleanExtra(WearConstants.FROM_WEAR, false)) {
46+
new SendToDataLayerThread(WearConstants.FINISH, this).start();
47+
}
48+
49+
if(getIntent().getAction() != null && getIntent().getAction().equals(Intent.CAST_MEDIA)) {
50+
Logger.d("[CastActivity] checking subscribed: %s", castPlayerManager.isSubscribed());
51+
if(castPlayerManager.isSubscribed()) {
52+
nowPlayingMedia = castPlayerManager.getNowPlayingMedia();
53+
nowPlayingAlbum = castPlayerManager.getNowPlayingAlbum();
54+
if(!castPlayerManager.getCurrentState().equals(PlayerState.STOPPED)) {
55+
// Media is playing, so show ui
56+
showNowPlaying(setView);
57+
} else {
58+
handler.postDelayed(new Runnable() {
59+
@Override
60+
public void run() {
61+
Logger.d("Checking for playback state: %s", castPlayerManager.getCurrentState());
62+
if(!castPlayerManager.getCurrentState().equals(PlayerState.STOPPED)) {
63+
showNowPlaying(setView);
64+
} else {
65+
handler.postDelayed(this, 1000);
66+
}
67+
}
68+
}, 1000);
69+
}
70+
} else {
71+
if(getIntent().getParcelableExtra(Intent.EXTRA_MEDIA) != null) {
72+
nowPlayingMedia = getIntent().getParcelableExtra(Intent.EXTRA_MEDIA);
73+
nowPlayingAlbum = getIntent().getParcelableExtra(Intent.EXTRA_ALBUM);
74+
showNowPlaying(setView);
75+
}
76+
castPlayerManager.subscribe(mClient, new Runnable() {
77+
@Override
78+
public void run() {
79+
// TODO: this
80+
nowPlayingMedia = castPlayerManager.getNowPlayingMedia();
81+
nowPlayingAlbum = castPlayerManager.getNowPlayingAlbum();
82+
}
83+
});
84+
}
85+
} else {
86+
// We're coming here expecting to already be connected and have media playing.
87+
if(!castPlayerManager.isSubscribed() || castPlayerManager.getCurrentState().equals(PlayerState.STOPPED))
88+
finish();
89+
else {
90+
nowPlayingMedia = castPlayerManager.getNowPlayingMedia();
91+
nowPlayingAlbum = castPlayerManager.getNowPlayingAlbum();
92+
showNowPlaying(setView);
93+
}
94+
}
95+
}
96+
97+
@Override
3698
protected void onCreate(Bundle savedInstanceState) {
3799
super.onCreate(savedInstanceState);
38100

39-
mClient = getIntent().getParcelableExtra(com.atomjack.shared.Intent.EXTRA_CLIENT);
40-
Logger.d("[CastActivity] set mClient: %s", mClient);
41-
nowPlayingMedia = getIntent().getParcelableExtra(com.atomjack.shared.Intent.EXTRA_MEDIA);
42-
nowPlayingAlbum = getIntent().getParcelableArrayListExtra(com.atomjack.shared.Intent.EXTRA_ALBUM);
101+
start(true);
102+
103+
/*
104+
105+
boolean mediaChange = false;
106+
PlexMedia newMedia = getIntent().getParcelableExtra(Intent.EXTRA_MEDIA);
107+
if(castPlayerManager.isSubscribed()) {
108+
if(newMedia != null && castPlayerManager.getNowPlayingMedia() != null && !newMedia.key.equals(castPlayerManager.getNowPlayingMedia().key))
109+
mediaChange = true;
110+
}
111+
112+
113+
nowPlayingMedia = newMedia;
114+
nowPlayingAlbum = getIntent().getParcelableArrayListExtra(Intent.EXTRA_ALBUM);
43115
resumePlayback = getIntent().getBooleanExtra("resume", false);
44116
castManager = castPlayerManager.getCastManager();
45117
46118
if(getIntent().getBooleanExtra(WearConstants.FROM_WEAR, false)) {
47119
new SendToDataLayerThread(WearConstants.FINISH, this).start();
48120
}
49121
// If just playing a single track, put the media into an array
50-
if(nowPlayingAlbum == null)
51-
nowPlayingAlbum = Arrays.asList(nowPlayingMedia);
122+
if(nowPlayingAlbum == null) {
123+
nowPlayingAlbum = new ArrayList<>();
124+
nowPlayingAlbum.add(nowPlayingMedia);
125+
}
52126
53127
Logger.d("[CastActivity] starting up, action: %s, current state: %s", getIntent().getAction(), castPlayerManager.getCurrentState());
54128
Logger.d("client: %s", mClient);
55-
if(getIntent().getAction() != null && getIntent().getAction().equals(com.atomjack.shared.Intent.CAST_MEDIA)) {
129+
if(getIntent().getAction() != null && getIntent().getAction().equals(Intent.CAST_MEDIA)) {
56130
131+
/*
57132
Logger.d("Casting %s (%s)", nowPlayingMedia.title, nowPlayingMedia.viewOffset);
58133
59-
showNowPlaying();
60-
if(castPlayerManager.isSubscribed()) {
61-
init();
134+
// TODO: only show now playing if stopped?
135+
// if(castPlayerManager.getCurrentState().equals(PlayerState.STOPPED))
136+
137+
if(mediaChange) {
138+
Logger.d("[CastActivity] MEDIA CHANGED!");
139+
140+
init(true); // tell the chromecast to load the new media. The cast player activity will receive a notification of the new media and will update accordingly
62141
} else {
63-
showInfoDialog(getResources().getString(R.string.connecting));
64-
castPlayerManager.subscribe(mClient);
142+
143+
showNowPlaying(castPlayerManager.getCurrentState().equals(PlayerState.STOPPED) || !mediaChange ? true : false);
144+
if (castPlayerManager.isSubscribed()) {
145+
init();
146+
} else {
147+
showInfoDialog(getResources().getString(R.string.connecting));
148+
castPlayerManager.subscribe(mClient);
149+
}
65150
}
66151
} else {
67152
Logger.d("[CastActivity] No action found.");
68153
if(castPlayerManager.getCurrentState().equals(PlayerState.STOPPED))
69154
finish();
70155
else {
71-
showNowPlaying();
156+
showNowPlaying(true);
72157
}
73158
}
159+
*/
74160
}
75161

162+
@Override
163+
protected void onNewIntent(android.content.Intent intent) {
164+
super.onNewIntent(intent);
165+
// If the currently playing media is of a different type than the one being received, make sure to set the view
166+
PlexMedia newMedia = intent.getParcelableExtra(Intent.EXTRA_MEDIA);
167+
start(newMedia != null && nowPlayingMedia != null && !newMedia.getType().equals(nowPlayingMedia.getType()));
168+
}
169+
76170
@Override
77171
public void showNowPlaying() {
78-
super.showNowPlaying();
172+
showNowPlaying(true);
173+
}
174+
175+
@Override
176+
public void showNowPlaying(boolean setView) {
177+
super.showNowPlaying(setView);
79178
setupUI();
80179
}
81180

@@ -91,17 +190,22 @@ private void setupUI() {
91190
seekBar = (SeekBar)findViewById(R.id.seekBar);
92191
seekBar.setOnSeekBarChangeListener(this);
93192
seekBar.setMax(nowPlayingMedia.duration);
94-
seekBar.setProgress(getOffset(nowPlayingMedia)*1000);
193+
seekBar.setProgress(getOffset(nowPlayingMedia) * 1000);
95194

96195
Logger.d("setupUI, setting time display to %d", getOffset(nowPlayingMedia));
97196
setCurrentTimeDisplay(getOffset(nowPlayingMedia));
98197
durationDisplay.setText(VoiceControlForPlexApplication.secondsToTimecode(nowPlayingMedia.duration / 1000));
198+
uiShowing = true;
99199
}
100200

101201
private void init() {
202+
init(false);
203+
}
204+
205+
private void init(boolean forceLoad) {
102206
currentState = castPlayerManager.getCurrentState();
103207
Logger.d("castPlayerManager.getCurrentState(): %s", castPlayerManager.getCurrentState());
104-
if(castPlayerManager.getCurrentState() != PlayerState.STOPPED)
208+
if(castPlayerManager.getCurrentState() != PlayerState.STOPPED && !forceLoad)
105209
return;
106210
if (VoiceControlForPlexApplication.getInstance().prefs.getString(Preferences.PLEX_USERNAME) != null) {
107211
nowPlayingMedia.server.requestTransientAccessToken(new AfterTransientTokenRequest() {
@@ -271,16 +375,19 @@ public boolean onCreateOptionsMenu(Menu _menu) {
271375
public void onCastPlayerStateChanged(PlayerState state) {
272376
super.onCastPlayerStateChanged(state);
273377
Logger.d("[CastActivity] onCastPlayerStateChanged: %s", state);
378+
274379
if(isSeeking) {
275380
isSeeking = false;
276381
}
277-
hideInfoDialog();
278382
if(state == PlayerState.STOPPED) {
279383
Logger.d("[CastActivity] media player is idle, finishing");
280384
VoiceControlForPlexApplication.getInstance().cancelNotification();
281385
finish();
282-
} else
386+
} else if(uiShowing) {
283387
setState(state);
388+
}
389+
if(uiShowing)
390+
hideInfoDialog();
284391
}
285392

286393
@Override

mobile/src/main/java/com/atomjack/vcfp/activities/PlayerActivity.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.atomjack.vcfp.model.PlexVideo;
2323
import com.atomjack.vcfp.services.PlexSearchService;
2424
import com.google.android.gms.wearable.DataMap;
25-
import com.google.gson.Gson;
2625

2726
import java.math.BigInteger;
2827
import java.security.SecureRandom;
@@ -42,16 +41,17 @@ protected void onCreate(Bundle savedInstanceState) {
4241
}
4342

4443
public void doMic(View v) {
45-
Intent serviceIntent = new Intent(getApplicationContext(), PlexSearchService.class);
4644

47-
PlexServer server = nowPlayingMedia.server;
45+
PlexServer server = nowPlayingMedia.server;
4846

49-
Logger.d("server: %s", server);
50-
if(server != null) {
47+
Logger.d("server: %s", server);
48+
if(server != null) {
49+
Intent serviceIntent = new Intent(getApplicationContext(), PlexSearchService.class);
5150

52-
serviceIntent.putExtra(com.atomjack.shared.Intent.EXTRA_SERVER, gsonWrite.toJson(server));
51+
serviceIntent.putExtra(com.atomjack.shared.Intent.EXTRA_SERVER, gsonWrite.toJson(server));
5352
serviceIntent.putExtra(com.atomjack.shared.Intent.EXTRA_CLIENT, gsonWrite.toJson(mClient));
5453
serviceIntent.putExtra(com.atomjack.shared.Intent.EXTRA_RESUME, resumePlayback);
54+
serviceIntent.putExtra(com.atomjack.shared.Intent.EXTRA_FROM_MIC, true);
5555

5656
SecureRandom random = new SecureRandom();
5757
serviceIntent.setData(Uri.parse(new BigInteger(130, random).toString(32)));
@@ -129,6 +129,7 @@ public void showNowPlaying(boolean setView) {
129129
setContentView(R.layout.now_playing_music);
130130

131131
TextView artist = (TextView)findViewById(R.id.nowPlayingArtist);
132+
Logger.d("Setting artist to %s", track.grandparentTitle);
132133
artist.setText(track.grandparentTitle);
133134
TextView album = (TextView)findViewById(R.id.nowPlayingAlbum);
134135
album.setText(track.parentTitle);

0 commit comments

Comments
 (0)