Skip to content

Commit 42f5e87

Browse files
author
Chris Bellew
committed
Fixed Wear support. Fixed resume playback when using voice query.
1 parent b6f0212 commit 42f5e87

File tree

13 files changed

+91
-115
lines changed

13 files changed

+91
-115
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ public void onDataMessageReceived(String message) {
391391
else
392392
nowPlayingMedia = VoiceControlForPlexApplication.gsonRead.fromJson(obj.getString("media"), PlexTrack.class);
393393
if(listener != null)
394-
listener.onMediaChanged(nowPlayingMedia);
394+
listener.onMediaChanged(nowPlayingMedia, PlayerState.PLAYING);
395395
} else if(obj.has("event") && obj.getString("event").equals(RECEIVER_EVENTS.GET_PLAYBACK_STATE) && obj.has("state")) {
396396
Logger.d("Got playback state back: %s", obj.getString("state"));
397397
PlayerState oldState = currentState;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ public void onFinish(PlexMedia media) {
446446
Logger.d("media: %s, listener: %s, state: %s", media.getTitle(), listener, currentState);
447447
if(listener != null && currentState != PlayerState.STOPPED)
448448
if(nowPlayingMedia != null)
449-
listener.onMediaChanged(media);
449+
listener.onMediaChanged(media, PlayerState.getState(timeline));
450450
else
451451
listener.onPlayStarted(media, PlayerState.getState(timeline));
452452
nowPlayingMedia = media;
@@ -534,4 +534,8 @@ public Timeline getCurrentTimeline() {
534534
public int getCommandId() {
535535
return commandId;
536536
}
537+
538+
public PlexMedia getNowPlayingMedia() {
539+
return nowPlayingMedia;
540+
}
537541
}

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

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import com.atomjack.vcfp.fragments.PlexPlayerFragment;
8282
import com.atomjack.vcfp.fragments.SetupFragment;
8383
import com.atomjack.vcfp.interfaces.ActivityListener;
84+
import com.atomjack.vcfp.interfaces.BitmapHandler;
8485
import com.atomjack.vcfp.interfaces.PlexSubscriptionListener;
8586
import com.atomjack.vcfp.interfaces.ScanHandler;
8687
import com.atomjack.vcfp.model.Pin;
@@ -335,9 +336,10 @@ public void onTimeUpdate(PlayerState state, int seconds) {
335336
}
336337

337338
@Override
338-
public void onMediaChanged(PlexMedia media) {
339-
Logger.d("[MainActivity] onMediaChanged: %s", media.getTitle());
339+
public void onMediaChanged(PlexMedia media, PlayerState state) {
340+
Logger.d("[MainActivity] onMediaChanged: %s %s", media.getTitle(), state);
340341
playerFragment.mediaChanged(media);
342+
sendWearPlaybackChange(state, media);
341343
}
342344

343345
@Override
@@ -349,6 +351,7 @@ public void onPlayStarted(PlexMedia media, PlayerState state) {
349351
playerFragment.init(layout, client, media, plexSubscriptionListener);
350352
switchToFragment(playerFragment);
351353
}
354+
sendWearPlaybackChange(state, media);
352355
}
353356

354357
@Override
@@ -364,7 +367,7 @@ public void onStateChanged(PlexMedia media, PlayerState state) {
364367
} else {
365368
Logger.d("Got state change to %s, but for some reason playerFragment is null", state);
366369
}
367-
370+
sendWearPlaybackChange(state, media);
368371
}
369372

370373
@Override
@@ -381,8 +384,9 @@ public void onUnsubscribed() {
381384
setCastIconInactive();
382385
VoiceControlForPlexApplication.getInstance().prefs.remove(Preferences.SUBSCRIBED_CLIENT);
383386
switchToFragment(getMainFragment());
384-
// TODO: Implement
385-
// sendWearPlaybackChange();
387+
if(VoiceControlForPlexApplication.getInstance().hasWear()) {
388+
new SendToDataLayerThread(WearConstants.DISCONNECTED, MainActivity.this).start();
389+
}
386390
feedback.m(R.string.disconnected);
387391
}
388392
};
@@ -940,8 +944,7 @@ private void handleShowNowPlayingIntent(Intent intent) {
940944
boolean fromWear = intent.getBooleanExtra(WearConstants.FROM_WEAR, false);
941945
PlayerState state;
942946
if(client.isCastClient) {
943-
// TODO: Get current state from CastPlayerManager
944-
state = PlayerState.STOPPED;
947+
state = castPlayerManager.getCurrentState();
945948
} else {
946949
state = plexSubscription.getCurrentState();
947950
plexSubscription.subscribe(client);
@@ -950,7 +953,10 @@ private void handleShowNowPlayingIntent(Intent intent) {
950953
Logger.d("Layout: %d", layout);
951954
if(layout != -1) {
952955
playerFragment.init(layout, client, media, plexSubscriptionListener);
953-
switchToFragment(playerFragment);
956+
if(playerFragment.isVisible())
957+
playerFragment.mediaChanged(media);
958+
else
959+
switchToFragment(playerFragment);
954960
int seconds = intent.getBooleanExtra(com.atomjack.shared.Intent.EXTRA_STARTING_PLAYBACK, false) ? 10 : 3;
955961
Logger.d("Setting auto disconnect for %d seconds", seconds);
956962
handler.postDelayed(autoDisconnectPlayerTimer, seconds*1000);
@@ -2152,4 +2158,37 @@ public boolean dispatchKeyEvent(KeyEvent event) {
21522158
}
21532159
return super.dispatchKeyEvent(event);
21542160
}
2161+
2162+
public void sendWearPlaybackChange(final PlayerState state, PlexMedia media) {
2163+
if(VoiceControlForPlexApplication.getInstance().hasWear()) {
2164+
Logger.d("[PlayerFragment] Sending Wear Notification: %s", state);
2165+
final DataMap data = new DataMap();
2166+
String msg = null;
2167+
if (state == PlayerState.PLAYING) {
2168+
data.putString(WearConstants.MEDIA_TYPE, media.getType());
2169+
VoiceControlForPlexApplication.SetWearMediaTitles(data, media);
2170+
msg = WearConstants.MEDIA_PLAYING;
2171+
} else if (state == PlayerState.STOPPED) {
2172+
msg = WearConstants.MEDIA_STOPPED;
2173+
} else if (state == PlayerState.PAUSED) {
2174+
msg = WearConstants.MEDIA_PAUSED;
2175+
VoiceControlForPlexApplication.SetWearMediaTitles(data, media);
2176+
}
2177+
if (msg != null) {
2178+
if (msg.equals(WearConstants.MEDIA_PLAYING)) {
2179+
VoiceControlForPlexApplication.getWearMediaImage(media, new BitmapHandler() {
2180+
@Override
2181+
public void onSuccess(Bitmap bitmap) {
2182+
DataMap binaryDataMap = new DataMap();
2183+
binaryDataMap.putAll(data);
2184+
binaryDataMap.putAsset(WearConstants.IMAGE, VoiceControlForPlexApplication.createAssetFromBitmap(bitmap));
2185+
binaryDataMap.putString(WearConstants.PLAYBACK_STATE, state.name());
2186+
new SendToDataLayerThread(WearConstants.RECEIVE_MEDIA_IMAGE, binaryDataMap, MainActivity.this).sendDataItem();
2187+
}
2188+
});
2189+
}
2190+
new SendToDataLayerThread(msg, data, this).start();
2191+
}
2192+
}
2193+
}
21552194
}

mobile/src/main/java/com/atomjack/vcfp/fragments/PlayerFragment.java

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,20 @@
3232
import com.atomjack.shared.Logger;
3333
import com.atomjack.shared.PlayerState;
3434
import com.atomjack.shared.Preferences;
35+
import com.atomjack.shared.SendToDataLayerThread;
36+
import com.atomjack.shared.WearConstants;
3537
import com.atomjack.shared.model.Timeline;
3638
import com.atomjack.vcfp.Feedback;
3739
import com.atomjack.vcfp.PlexHeaders;
3840
import com.atomjack.vcfp.R;
3941
import com.atomjack.vcfp.Utils;
4042
import com.atomjack.vcfp.VoiceControlForPlexApplication;
4143
import com.atomjack.vcfp.activities.MainActivity;
44+
import com.atomjack.vcfp.activities.VCFPActivity;
4245
import com.atomjack.vcfp.adapters.StreamAdapter;
4346
import com.atomjack.vcfp.interfaces.ActiveConnectionHandler;
4447
import com.atomjack.vcfp.interfaces.ActivityListener;
48+
import com.atomjack.vcfp.interfaces.BitmapHandler;
4549
import com.atomjack.vcfp.interfaces.InputStreamHandler;
4650
import com.atomjack.vcfp.interfaces.PlayerFragmentListener;
4751
import com.atomjack.vcfp.interfaces.PlexSubscriptionListener;
@@ -56,6 +60,7 @@
5660
import com.atomjack.vcfp.net.PlexHttpClient;
5761
import com.atomjack.vcfp.net.PlexHttpMediaContainerHandler;
5862
import com.atomjack.vcfp.services.PlexSearchService;
63+
import com.google.android.gms.wearable.DataMap;
5964

6065
import org.apache.commons.io.IOUtils;
6166

@@ -159,7 +164,6 @@ public void init(int layout, PlexClient client, PlexMedia media, PlexSubscriptio
159164
}
160165

161166
public void mediaChanged(PlexMedia media) {
162-
163167
nowPlayingMedia = media;
164168
setCurrentTimeDisplay(getOffset(nowPlayingMedia));
165169
seekBar.setMax(nowPlayingMedia.duration / 1000);
@@ -216,44 +220,6 @@ public void cycleStreams(final int streamType) {
216220
}
217221
}
218222

219-
protected void getPlayingMedia(final PlexServer server, final Timeline timeline) {
220-
Logger.d("[PlayerFragment] getPlayingMedia: %s", timeline.key);
221-
// TODO: Find out why server can sometimes be null
222-
PlexHttpClient.get(server, timeline.key, new PlexHttpMediaContainerHandler() {
223-
@Override
224-
public void onSuccess(MediaContainer mediaContainer) {
225-
if(timeline.type.equals("video"))
226-
nowPlayingMedia = mediaContainer.videos.get(0);
227-
else if(timeline.type.equals("music"))
228-
nowPlayingMedia = mediaContainer.tracks.get(0);
229-
else {
230-
// TODO: Handle failure
231-
Logger.d("Failed to get media with type %s", timeline.type);
232-
}
233-
234-
if(nowPlayingMedia != null) {
235-
nowPlayingMedia.server = server;
236-
237-
VoiceControlForPlexApplication.getInstance().setNotification(client, currentState, nowPlayingMedia);
238-
if (timeline.continuing != null && timeline.continuing.equals("1"))
239-
continuing = true;
240-
onMediaChange();
241-
sendWearPlaybackChange();
242-
}
243-
}
244-
245-
@Override
246-
public void onFailure(Throwable error) {
247-
// TODO: Handle failure
248-
}
249-
});
250-
}
251-
252-
// TODO: Implement
253-
protected void sendWearPlaybackChange() {
254-
255-
}
256-
257223
protected void onMediaChange() {
258224

259225
}

mobile/src/main/java/com/atomjack/vcfp/interfaces/PlexSubscriptionListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public interface PlexSubscriptionListener {
88
void onSubscribed(PlexClient client);
99
void onUnsubscribed();
1010
void onTimeUpdate(PlayerState state, int seconds);
11-
void onMediaChanged(PlexMedia media);
11+
void onMediaChanged(PlexMedia media, PlayerState state);
1212
void onStateChanged(PlexMedia media, PlayerState state);
1313
void onPlayStarted(PlexMedia media, PlayerState state);
1414
void onSubscribeError(String message);

mobile/src/main/java/com/atomjack/vcfp/services/PlexSearchService.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -419,13 +419,13 @@ public void run() {
419419
}
420420
}
421421

422-
// Check for a sentence starting with "resume watching"
422+
// Check for a sentence starting with "resume watching/playing"
423423
p = Pattern.compile(getString(R.string.pattern_resume_watching));
424424
matcher = p.matcher(queryText);
425425
if(matcher.find()) {
426426
resumePlayback = true;
427-
// Replace "resume watching" with just "watch" so the pattern matching below works
428-
queryText = matcher.replaceAll(getString(R.string.pattern_watch));
427+
// Replace "resume watching/playing" with just "watch" so the pattern matching below works
428+
queryText = matcher.replaceAll(getString(R.string.pattern_watch));
429429
}
430430

431431
// Check for a sentence ending with "on shuffle"
@@ -810,17 +810,7 @@ public void run() {
810810
public void run() {
811811
Logger.d("PlexSearchService Subscribing to %s", theClient.name);
812812
// TODO: Check this
813-
// if(VoiceControlForPlexApplication.getInstance().plexSubscription.getListener() != null)
814813
VoiceControlForPlexApplication.getInstance().plexSubscription.subscribe(theClient);
815-
// else {
816-
// Intent sendIntent = new Intent(PlexSearchService.this, SubscriptionActivity.class);
817-
// sendIntent.setAction(SubscriptionActivity.ACTION_SUBSCRIBE);
818-
// sendIntent.putExtra(SubscriptionActivity.CLIENT, theClient);
819-
// sendIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
820-
// sendIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
821-
// sendIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
822-
// startActivity(sendIntent);
823-
// }
824814
}
825815
};
826816
}
@@ -833,16 +823,7 @@ public void run() {
833823
@Override
834824
public void run() {
835825
// TODO: Check this
836-
// if(VoiceControlForPlexApplication.getInstance().plexSubscription.getListener() != null)
837826
VoiceControlForPlexApplication.getInstance().plexSubscription.unsubscribe();
838-
// else {
839-
// Intent sendIntent = new Intent(PlexSearchService.this, SubscriptionActivity.class);
840-
// sendIntent.setAction(SubscriptionActivity.ACTION_UNSUBSCRIBE);
841-
// sendIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
842-
// sendIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
843-
// sendIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
844-
// startActivity(sendIntent);
845-
// }
846827
}
847828
};
848829
}

mobile/src/main/java/com/atomjack/vcfp/services/WearListenerService.java

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ public void run() {
8484

8585
PlexSubscription plexSubscription = VoiceControlForPlexApplication.getInstance().plexSubscription;
8686
CastPlayerManager castPlayerManager = VoiceControlForPlexApplication.getInstance().castPlayerManager;
87-
// TODO: FIX
88-
PlexPlayerFragment listener = null; //plexSubscription.getListener();
89-
CastPlayerManager.CastListener castListener = null; //castPlayerManager.getListener();
9087
PlexClient client = new PlexClient();
9188
if (plexSubscription.isSubscribed()) {
9289
client = plexSubscription.mClient;
@@ -109,24 +106,18 @@ public void run() {
109106
} else if(message.equals(WearConstants.GET_PLAYBACK_STATE)) {
110107
Logger.d("[WearListenerService] get playback state");
111108
dataMap.putBoolean(WearConstants.LAUNCHED, receivedDataMap.getBoolean(WearConstants.LAUNCHED, false));
112-
// PlexSubscription plexSubscription = VoiceControlForPlexApplication.getInstance().plexSubscription;
113-
// CastPlayerManager castPlayerManager = VoiceControlForPlexApplication.getInstance().castPlayerManager;
114109
if (plexSubscription.isSubscribed()) {
115-
// PlexClient client = plexSubscription.mClient;
116-
117110
PlayerState currentState = plexSubscription.getCurrentState();
118111
Logger.d("[WearListenerService] current State: %s", currentState);
119112

120113
dataMap.putString(WearConstants.CLIENT_NAME, client.name);
121114
dataMap.putString(WearConstants.PLAYBACK_STATE, currentState.name());
122115

123-
if(listener != null && listener.getNowPlayingMedia() != null) {
124-
Logger.d("now playing: %s", listener.getNowPlayingMedia().title);
125-
VoiceControlForPlexApplication.SetWearMediaTitles(dataMap, listener.getNowPlayingMedia());
126-
dataMap.putString(WearConstants.MEDIA_TYPE, listener.getNowPlayingMedia().getType());
127-
// TODO: Fix
128-
/*
129-
final PlexMedia media = plexSubscription.getListener().getNowPlayingMedia();
116+
if(plexSubscription.getNowPlayingMedia() != null) {
117+
PlexMedia media = plexSubscription.getNowPlayingMedia();
118+
Logger.d("now playing: %s", plexSubscription.getNowPlayingMedia().title);
119+
VoiceControlForPlexApplication.SetWearMediaTitles(dataMap, media);
120+
dataMap.putString(WearConstants.MEDIA_TYPE, media.getType());
130121
VoiceControlForPlexApplication.getWearMediaImage(media, new BitmapHandler() {
131122
@Override
132123
public void onSuccess(Bitmap bitmap) {
@@ -139,7 +130,6 @@ public void onSuccess(Bitmap bitmap) {
139130
Logger.d("[WearListenerService] sent is playing status (%s) to wearable.", dataMap.getString(WearConstants.PLAYBACK_STATE));
140131
}
141132
});
142-
*/
143133
} else {
144134
dataMap.putString(WearConstants.PLAYBACK_STATE, PlayerState.STOPPED.name());
145135
new SendToDataLayerThread(WearConstants.GET_PLAYBACK_STATE, dataMap, this).start();
@@ -149,13 +139,11 @@ public void onSuccess(Bitmap bitmap) {
149139
dataMap.putString(WearConstants.CLIENT_NAME, client.name);
150140
dataMap.putString(WearConstants.PLAYBACK_STATE, currentState.name());
151141

152-
if(castListener != null && castListener.getNowPlayingMedia() != null) {
153-
Logger.d("now playing: %s", castListener.getNowPlayingMedia().title);
154-
VoiceControlForPlexApplication.SetWearMediaTitles(dataMap, castListener.getNowPlayingMedia());
155-
dataMap.putString(WearConstants.MEDIA_TYPE, castListener.getNowPlayingMedia().getType());
156-
// TODO: Fix
157-
final PlexMedia media = null; //castPlayerManager.getListener().getNowPlayingMedia();
158-
VoiceControlForPlexApplication.getWearMediaImage(media, new BitmapHandler() {
142+
if(castPlayerManager.getNowPlayingMedia() != null) {
143+
Logger.d("now playing: %s", castPlayerManager.getNowPlayingMedia().title);
144+
VoiceControlForPlexApplication.SetWearMediaTitles(dataMap, castPlayerManager.getNowPlayingMedia());
145+
dataMap.putString(WearConstants.MEDIA_TYPE, castPlayerManager.getNowPlayingMedia().getType());
146+
VoiceControlForPlexApplication.getWearMediaImage(castPlayerManager.getNowPlayingMedia(), new BitmapHandler() {
159147
@Override
160148
public void onSuccess(Bitmap bitmap) {
161149
DataMap binaryDataMap = new DataMap();
@@ -203,12 +191,10 @@ public void onSuccess(Bitmap bitmap) {
203191
}
204192
} else if(message.equals(WearConstants.ACTION_PAUSE) || message.equals(WearConstants.ACTION_PLAY) || message.equals(WearConstants.ACTION_STOP)) {
205193
PlexMedia media = null;
206-
// TODO: Fix
207-
// if(castPlayerManager.isSubscribed()) {
208-
// media = castPlayerManager.getListener().getNowPlayingMedia();
209-
// }
210-
// else if(plexSubscription.isSubscribed())
211-
// media = plexSubscription.getListener().getNowPlayingMedia();
194+
if(castPlayerManager.isSubscribed())
195+
media = castPlayerManager.getNowPlayingMedia();
196+
else if(plexSubscription.isSubscribed())
197+
media = plexSubscription.getNowPlayingMedia();
212198
if(media != null) {
213199
Intent intent = new android.content.Intent(this, PlexControlService.class);
214200
intent.setAction(message);

mobile/src/main/res/values-de/patterns.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Wenn du eine Übersetzung hinzufügst bitte modifiziere nicht die Muster (.*), $
1212
<item name="pattern_recognition" type="string">^(((schaue|spiele|weiterschauen|höre|schaue film|spiele film) (.+)( auf (.+))?( mit zufallswiedergabe)?)|((springe) (.+)( auf (.+))?)|((forward|rewind|back) (.+)( on (.+))?)|(( wiedergabe)?(pausieren|anhalten|fortsetzen)( auf (.+))?))|(verbinde mit (.+)|trenne)|(cycle (subtitles|audio))|(.*subtitle.*(off|on))$</item>
1313

1414
<item name="pattern_on_client" type="string">(.+) auf (.+)$</item>
15-
<item name="pattern_resume_watching" type="string">^weiterschauen (.+)</item>
15+
<item name="pattern_resume_watching" type="string">^schaue|weiterschauen (.+)</item>
1616
<item name="pattern_on_shuffle" type="string"> mit zufallswiedergabe$</item>
17-
<item name="pattern_watch" type="string">(schaue|spiele) $1</item>
17+
<item name="pattern_watch" type="string">schaue $1</item>
1818
<item name="pattern_watch_movie" type="string">(schaue|spiele) film (.+)</item>
1919
<item name="pattern_watch_season_episode_of_show" type="string">(schaue|spiele) staffel ([0-9]+) episode ([0-9]+) von (.+)</item>
2020
<item name="pattern_watch_show_season_episode" type="string">(schaue|spiele) (.+) staffel ([0-9]+) episode ([0-9]+)</item>

mobile/src/main/res/values-es/patterns.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ adding translations, please do not modify (.*), $1, ([0-9]+), etc.
1212
<item name="pattern_recognition" type="string">^(((ver|continuar viendo|escuchar|ver película) (.+)( en (.+))?( en modo aleatorio)?)|((posición) (.+)( en (.+))?)|((forward|rewind|back) (.+)( on (.+))?)|((pausar|detener|continuar)( reproducción)?( en (.+))?))|(conectar a (.+)|desconectar)|(cycle (subtitles|audio))|(.*subtitle.*(off|on))$</item>
1313

1414
<item name="pattern_on_client" type="string">(.+) en (.+)$</item>
15-
<item name="pattern_resume_watching" type="string">^continuar (viendo) (.+)</item>
15+
<item name="pattern_resume_watching" type="string">^ver|(continuar viendo) (.+)</item>
1616
<item name="pattern_on_shuffle" type="string"> en modo aleatorio$</item>
17-
<item name="pattern_watch" type="string">(ver) $1</item>
17+
<item name="pattern_watch" type="string">ver $2</item>
1818
<item name="pattern_watch_movie" type="string">(ver) película (.+)</item>
1919
<item name="pattern_watch_season_episode_of_show" type="string">(ver) temporada ([0-9]+) episodio ([0-9]+) de (.+)</item>
2020
<item name="pattern_watch_show_season_episode" type="string">(ver) (.+) temporada ([0-9]+) episodio ([0-9]+)</item>

0 commit comments

Comments
 (0)