Skip to content

Commit 4e7b337

Browse files
author
Chris Bellew
committed
Added Wear Support when using a Chromecast.
1 parent 7b2d196 commit 4e7b337

File tree

16 files changed

+119
-111
lines changed

16 files changed

+119
-111
lines changed

mobile/src/main/AndroidManifest.xml

Lines changed: 2 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="34"
6-
android:versionName="2.0b3" >
5+
android:versionCode="36"
6+
android:versionName="2.0b5" >
77

88
<uses-permission android:name="com.mohammadag.googlesearchapi.permission.ACCESS_GGOGLE_SEARCH_API" />
99
<uses-permission android:name="android.permission.INTERNET" />

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,18 @@ public void setListener(CastListener _listener) {
135135
// notificationListener = _listener;
136136
}
137137

138+
public CastListener getListener() {
139+
return listener;
140+
}
141+
138142
public interface CastListener {
139143
void onCastConnected(PlexClient client);
140144
void onCastDisconnected();
141145
void onCastPlayerStateChanged(PlayerState state);
142146
void onCastPlayerTimeUpdate(int seconds);
143147
void onCastPlayerPlaylistAdvance(PlexMedia media);
144148
void onCastPlayerState(PlayerState state, PlexMedia media);
149+
PlexMedia getNowPlayingMedia();
145150
};
146151

147152
public VideoCastManager getCastManager() {
@@ -376,7 +381,6 @@ public String getTranscodeUrl(PlexMedia media, int offset) {
376381
} catch (Exception ex) {
377382
ex.printStackTrace();
378383
}
379-
// TODO: Fix this
380384
if(VoiceControlForPlexApplication.getInstance().prefs.getString(Preferences.PLEX_USERNAME) != null)
381385
qs.add(PlexHeaders.XPlexUsername, VoiceControlForPlexApplication.getInstance().prefs.getString(Preferences.PLEX_USERNAME));
382386
return url + qs.toString();

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import android.view.View;
77
import android.widget.SeekBar;
88

9+
import com.atomjack.shared.SendToDataLayerThread;
10+
import com.atomjack.shared.WearConstants;
911
import com.atomjack.vcfp.interfaces.AfterTransientTokenRequest;
1012
import com.atomjack.shared.Logger;
1113
import com.atomjack.shared.PlayerState;
@@ -46,6 +48,9 @@ protected void onCreate(Bundle savedInstanceState) {
4648
resumePlayback = getIntent().getBooleanExtra("resume", false);
4749
castManager = castPlayerManager.getCastManager();
4850

51+
if(getIntent().getBooleanExtra(WearConstants.FROM_WEAR, false)) {
52+
new SendToDataLayerThread(WearConstants.FINISH, this).start();
53+
}
4954
// If just playing a single track, put the media into an array
5055
if(nowPlayingMedia.isMusic() && nowPlayingAlbum == null)
5156
nowPlayingAlbum = Arrays.asList(nowPlayingMedia);

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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,13 @@ protected void onCreate(Bundle savedInstanceState) {
5454
nowPlayingMedia = getIntent().getParcelableExtra(com.atomjack.shared.Intent.EXTRA_MEDIA);
5555
mClient = getIntent().getParcelableExtra(com.atomjack.shared.Intent.EXTRA_CLIENT);
5656
fromWear = getIntent().getBooleanExtra(WearConstants.FROM_WEAR, false);
57-
if(fromWear) {
58-
new SendToDataLayerThread(WearConstants.FINISH, this).start();
59-
}
6057
Logger.d("[NowPlayingActivity] 2 set client: %s", mClient);
6158
}
6259

60+
if(fromWear) {
61+
new SendToDataLayerThread(WearConstants.FINISH, this).start();
62+
}
63+
6364
if(mClient == null || nowPlayingMedia == null)
6465
finish();
6566

@@ -250,16 +251,6 @@ protected void onSaveInstanceState(Bundle outState) {
250251
@Override
251252
protected void onNewIntent(Intent intent)
252253
{
253-
if(intent.getAction() != null) {
254-
String action = intent.getAction();
255-
if(action.equals(com.atomjack.shared.Intent.GET_PLAYING_MEDIA) && nowPlayingMedia != null) {
256-
// Send information on the currently playing media to the wear device
257-
DataMap data = new DataMap();
258-
data.putString(WearConstants.MEDIA_TITLE, nowPlayingMedia.title);
259-
data.putString(WearConstants.IMAGE, nowPlayingMedia.art);
260-
new SendToDataLayerThread(WearConstants.GET_PLAYING_MEDIA, data, this).start();
261-
}
262-
}
263254
super.onNewIntent(intent);
264255
if(intent.getExtras() != null && intent.getExtras().getBoolean("finish") == true)
265256
finish();

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212

1313
import com.atomjack.shared.Logger;
1414
import com.atomjack.shared.Preferences;
15+
import com.atomjack.shared.SendToDataLayerThread;
16+
import com.atomjack.shared.WearConstants;
1517
import com.atomjack.vcfp.R;
1618
import com.atomjack.vcfp.VoiceControlForPlexApplication;
1719
import com.atomjack.vcfp.model.PlexMedia;
1820
import com.atomjack.vcfp.model.PlexServer;
1921
import com.atomjack.vcfp.model.PlexTrack;
2022
import com.atomjack.vcfp.model.PlexVideo;
2123
import com.atomjack.vcfp.services.PlexSearchService;
24+
import com.google.android.gms.wearable.DataMap;
2225
import com.google.gson.Gson;
2326

2427
import java.math.BigInteger;
@@ -155,4 +158,19 @@ public void onStopTrackingTouch(SeekBar seekBar) {
155158
}
156159

157160
public abstract void doStop(View v);
161+
162+
@Override
163+
protected void onNewIntent(Intent intent) {
164+
super.onNewIntent(intent);
165+
if(intent.getAction() != null) {
166+
String action = intent.getAction();
167+
if(action.equals(com.atomjack.shared.Intent.GET_PLAYING_MEDIA) && nowPlayingMedia != null) {
168+
// Send information on the currently playing media to the wear device
169+
DataMap data = new DataMap();
170+
data.putString(WearConstants.MEDIA_TITLE, nowPlayingMedia.title);
171+
data.putString(WearConstants.IMAGE, nowPlayingMedia.art);
172+
new SendToDataLayerThread(WearConstants.GET_PLAYING_MEDIA, data, this).start();
173+
}
174+
}
175+
}
158176
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,9 @@ public void onCastPlayerState(PlayerState state, PlexMedia media) {
501501
if(!mCurrentState.equals(PlayerState.STOPPED) && media != null) {
502502
nowPlayingMedia = media;
503503
mClient = castPlayerManager.mClient;
504-
// TODO: only set notification here if it's already on?
505504
VoiceControlForPlexApplication.getInstance().setNotification(mClient, mCurrentState, nowPlayingMedia);
506505
}
506+
sendWearPlaybackChange();
507507
}
508508

509509
@Override
@@ -524,6 +524,7 @@ public void onCastPlayerStateChanged(PlayerState state) {
524524
// TODO: only set notification here if it's already on?
525525
VoiceControlForPlexApplication.getInstance().setNotification(mClient, mCurrentState, nowPlayingMedia);
526526
}
527+
sendWearPlaybackChange();
527528
}
528529
}
529530

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,7 @@ private void playMedia(final PlexMedia media, PlexDirectory album, String transi
10091009
Logger.d("active connection: %s", media.server.activeConnection);
10101010
Intent sendIntent = new Intent(this, CastActivity.class);
10111011
sendIntent.setAction(com.atomjack.shared.Intent.CAST_MEDIA);
1012+
sendIntent.putExtra(WearConstants.FROM_WEAR, fromWear);
10121013
sendIntent.putExtra(com.atomjack.shared.Intent.EXTRA_MEDIA, media);
10131014
sendIntent.putExtra(com.atomjack.shared.Intent.EXTRA_CLIENT, client);
10141015
sendIntent.putExtra("resume", resumePlayback);

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

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void onCreate() {
4747
public void onMessageReceived(MessageEvent messageEvent) {
4848
String message = messageEvent.getPath() == null ? "" : messageEvent.getPath();
4949
Logger.d("[WearListenerService] onMessageReceived: %s", message);
50-
if(!VoiceControlForPlexApplication.getInstance().getInventoryQueried() && message.equals(WearConstants.GET_PLAYBACK_STATE)) {
50+
if(!VoiceControlForPlexApplication.getInstance().getInventoryQueried() && !VoiceControlForPlexApplication.getInstance().hasWear() && message.equals(WearConstants.GET_PLAYBACK_STATE)) {
5151
// This message was received before we've had a chance to check with Google on whether or not Wear support
5252
// has been purchased. After a delay of 500ms, send a message back to the Wearable to get playback state again.
5353
// By then, it should have had time to see if Wear Support has been purchased.
@@ -84,12 +84,13 @@ public void run() {
8484
PlexSubscription plexSubscription = VoiceControlForPlexApplication.getInstance().plexSubscription;
8585
CastPlayerManager castPlayerManager = VoiceControlForPlexApplication.getInstance().castPlayerManager;
8686
VCFPActivity listener = plexSubscription.getListener();
87+
CastPlayerManager.CastListener castListener = castPlayerManager.getListener();
8788
PlexClient client = new PlexClient();
8889
if (plexSubscription.isSubscribed()) {
8990
client = plexSubscription.mClient;
9091

9192
} else if (castPlayerManager.isSubscribed()) {
92-
// TODO: Handle chromecast clients
93+
client = castPlayerManager.mClient;
9394
}
9495

9596

@@ -114,12 +115,9 @@ public void run() {
114115
PlayerState currentState = plexSubscription.getCurrentState();
115116
Logger.d("[WearListenerService] current State: %s", currentState);
116117

117-
118118
dataMap.putString(WearConstants.CLIENT_NAME, client.name);
119119
dataMap.putString(WearConstants.PLAYBACK_STATE, currentState.name());
120120

121-
122-
123121
if(listener != null && listener.getNowPlayingMedia() != null) {
124122
Logger.d("now playing: %s", listener.getNowPlayingMedia().title);
125123
VoiceControlForPlexApplication.SetWearMediaTitles(dataMap, listener.getNowPlayingMedia());
@@ -142,8 +140,34 @@ public void onSuccess(Bitmap bitmap) {
142140
new SendToDataLayerThread(WearConstants.GET_PLAYBACK_STATE, dataMap, this).start();
143141
}
144142
} else if (castPlayerManager.isSubscribed()) {
145-
// TODO: Handle chromecast clients
143+
PlayerState currentState = castPlayerManager.getCurrentState();
144+
dataMap.putString(WearConstants.CLIENT_NAME, client.name);
145+
dataMap.putString(WearConstants.PLAYBACK_STATE, currentState.name());
146+
147+
if(castListener != null && castListener.getNowPlayingMedia() != null) {
148+
Logger.d("now playing: %s", castListener.getNowPlayingMedia().title);
149+
VoiceControlForPlexApplication.SetWearMediaTitles(dataMap, castListener.getNowPlayingMedia());
150+
dataMap.putString(WearConstants.MEDIA_TYPE, castListener.getNowPlayingMedia().getType());
151+
final PlexMedia media = castPlayerManager.getListener().getNowPlayingMedia();
152+
VoiceControlForPlexApplication.getWearMediaImage(media, new BitmapHandler() {
153+
@Override
154+
public void onSuccess(Bitmap bitmap) {
155+
DataMap binaryDataMap = new DataMap();
156+
binaryDataMap.putAll(dataMap);
157+
binaryDataMap.putAsset(WearConstants.IMAGE, VoiceControlForPlexApplication.createAssetFromBitmap(bitmap));
158+
binaryDataMap.putString(WearConstants.PLAYBACK_STATE, dataMap.getString(WearConstants.PLAYBACK_STATE));
159+
new SendToDataLayerThread(WearConstants.RECEIVE_MEDIA_IMAGE, binaryDataMap, WearListenerService.this).sendDataItem();
160+
new SendToDataLayerThread(WearConstants.GET_PLAYBACK_STATE, dataMap, WearListenerService.this).start();
161+
Logger.d("[WearListenerService] sent is playing status (%s) to wearable.", dataMap.getString(WearConstants.PLAYBACK_STATE));
162+
}
163+
});
164+
} else {
165+
dataMap.putString(WearConstants.PLAYBACK_STATE, PlayerState.STOPPED.name());
166+
new SendToDataLayerThread(WearConstants.GET_PLAYBACK_STATE, dataMap, this).start();
167+
}
168+
146169
} else {
170+
// Not subscribed to a client
147171
dataMap.putString(WearConstants.PLAYBACK_STATE, PlayerState.STOPPED.name());
148172
new SendToDataLayerThread(WearConstants.GET_PLAYBACK_STATE, dataMap, this).start();
149173
}
@@ -172,12 +196,19 @@ public void onSuccess(Bitmap bitmap) {
172196
startActivity(intent);
173197
}
174198
} else if(message.equals(WearConstants.ACTION_PAUSE) || message.equals(WearConstants.ACTION_PLAY) || message.equals(WearConstants.ACTION_STOP)) {
175-
Intent intent = new android.content.Intent(this, PlexControlService.class);
176-
intent.setAction(message);
177-
intent.putExtra(PlexControlService.CLIENT, client);
178-
intent.putExtra(PlexControlService.MEDIA, listener.getNowPlayingMedia());
179-
startService(intent);
180-
Logger.d("[WearListenerService] Sent %s to %s", message, client.name);
199+
PlexMedia media = null;
200+
if(castPlayerManager.isSubscribed())
201+
media = castPlayerManager.getListener().getNowPlayingMedia();
202+
else if(plexSubscription.isSubscribed())
203+
media = plexSubscription.getListener().getNowPlayingMedia();
204+
if(media != null) {
205+
Intent intent = new android.content.Intent(this, PlexControlService.class);
206+
intent.setAction(message);
207+
intent.putExtra(PlexControlService.CLIENT, client);
208+
intent.putExtra(PlexControlService.MEDIA, media);
209+
startService(intent);
210+
Logger.d("[WearListenerService] Sent %s to %s", message, client.name);
211+
}
181212
}
182213
}
183214
}

shared/src/main/java/com/atomjack/shared/PlayerState.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ else if (state.equals("buffering"))
2121
return STOPPED;
2222
}
2323

24+
public String getWearConstant() {
25+
String con = WearConstants.MEDIA_STOPPED;
26+
if(this == PAUSED)
27+
con = WearConstants.MEDIA_PAUSED;
28+
else if(this == PLAYING)
29+
con = WearConstants.MEDIA_PLAYING;
30+
return con;
31+
}
32+
2433
public static PlayerState getState(Timeline t) {
2534
if(t == null)
2635
return STOPPED;

shared/src/main/java/com/atomjack/shared/SendToDataLayerThread.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ public void run() {
5656
for (Node node : nodes.getNodes()) {
5757
// Construct a DataRequest and send over the data layer
5858
PutDataMapRequest putDMR = PutDataMapRequest.create(path);
59-
// TODO: Remove this?
6059
dataMap.putString("timestamp", new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date()));
6160
putDMR.getDataMap().putAll(dataMap);
6261
PutDataRequest request = putDMR.asPutDataRequest();

0 commit comments

Comments
 (0)