16
16
package com .example .android .mediacontroller ;
17
17
18
18
import android .app .Activity ;
19
+ import android .content .ComponentName ;
19
20
import android .content .Context ;
20
21
import android .content .Intent ;
22
+ import android .content .pm .PackageManager ;
23
+ import android .content .pm .ResolveInfo ;
21
24
import android .graphics .Bitmap ;
22
25
import android .graphics .drawable .BitmapDrawable ;
26
+ import android .graphics .drawable .Drawable ;
27
+ import android .net .Uri ;
23
28
import android .os .Bundle ;
24
29
import android .os .RemoteException ;
25
30
import android .support .annotation .Nullable ;
26
31
import android .support .annotation .StringRes ;
27
32
import android .support .design .widget .Snackbar ;
28
33
import android .support .design .widget .TabLayout ;
29
34
import android .support .v4 .media .MediaBrowserCompat ;
35
+ import android .support .v4 .media .MediaBrowserServiceCompat ;
30
36
import android .support .v4 .media .MediaMetadataCompat ;
31
37
import android .support .v4 .media .session .MediaControllerCompat ;
32
38
import android .support .v4 .media .session .PlaybackStateCompat ;
37
43
import android .support .v7 .widget .Toolbar ;
38
44
import android .text .TextUtils ;
39
45
import android .util .Log ;
40
- import android .util .SparseArray ;
41
46
import android .view .View ;
42
47
import android .view .ViewGroup ;
43
48
import android .widget .EditText ;
44
49
import android .widget .ImageView ;
45
50
import android .widget .Spinner ;
46
51
import android .widget .TextView ;
52
+ import android .widget .Toast ;
47
53
48
54
import java .util .HashMap ;
49
55
import java .util .List ;
50
56
import java .util .Map ;
57
+ import java .util .Set ;
51
58
52
59
/**
53
60
* This class connects to a {@link android.support.v4.media.MediaBrowserServiceCompat}
@@ -68,10 +75,30 @@ public class MediaAppControllerActivity extends AppCompatActivity {
68
75
private static final String STATE_URI_KEY =
69
76
"com.example.android.mediacontroller.STATE_URI_KEY" ;
70
77
78
+ // Key names for external extras.
79
+ private static final String PACKAGE_NAME_EXTRA =
80
+ "com.example.android.mediacontroller.PACKAGE_NAME" ;
81
+ private static final String SEARCH_EXTRA = "com.example.android.mediacontroller.SEARCH" ;
82
+ private static final String URI_EXTRA ="com.example.android.mediacontroller.URI" ;
83
+ private static final String MEDIA_ID_EXTRA = "com.example.android.mediacontroller.MEDIA_ID" ;
84
+
85
+ // Hint to use the currently loaded app rather than specifying a package.
86
+ private static final String CURRENT_PACKAGE = "current" ;
87
+
88
+ // Parameters for deep link URI.
89
+ private static final String SEARCH_PARAM = "search" ;
90
+ private static final String MEDIA_ID_PARAM = "id" ;
91
+ private static final String URI_PARAM = "uri" ;
92
+
71
93
// Key name for Intent extras.
72
94
private static final String APP_DETAILS_EXTRA =
73
95
"com.example.android.mediacontroller.APP_DETAILS_EXTRA" ;
74
96
97
+ // Index values for spinner.
98
+ private static final int SEARCH_INDEX = 0 ;
99
+ private static final int MEDIA_ID_INDEX = 1 ;
100
+ private static final int URI_INDEX = 2 ;
101
+
75
102
private MediaAppDetails mMediaAppDetails ;
76
103
private MediaControllerCompat mController ;
77
104
private MediaBrowserCompat mBrowser ;
@@ -94,7 +121,7 @@ public class MediaAppControllerActivity extends AppCompatActivity {
94
121
* @return An Intent that can be used to start the Activity.
95
122
*/
96
123
public static Intent buildIntent (final Activity activity ,
97
- final MediaAppDetails appDetails ) {
124
+ final MediaAppDetails appDetails ) {
98
125
final Intent intent = new Intent (activity , MediaAppControllerActivity .class );
99
126
intent .putExtra (APP_DETAILS_EXTRA , appDetails );
100
127
return intent ;
@@ -172,14 +199,65 @@ private void handleIntent(Intent intent) {
172
199
return ;
173
200
}
174
201
175
- if (intent .getData () != null ) {
176
- String uri = intent .getData ().toString ();
177
- mUriInput .setText (uri );
202
+ final Uri data = intent .getData ();
203
+ final String appPackageName ;
204
+ if (data != null ) {
205
+ appPackageName = data .getHost ();
206
+
207
+ final Set <String > params = data .getQueryParameterNames ();
208
+ if (params .contains (SEARCH_PARAM )) {
209
+ mInputTypeView .setSelection (SEARCH_INDEX );
210
+ mUriInput .setText (data .getQueryParameter (SEARCH_PARAM ));
211
+ } else if (params .contains (MEDIA_ID_PARAM )) {
212
+ mInputTypeView .setSelection (MEDIA_ID_INDEX );
213
+ mUriInput .setText (data .getQueryParameter (MEDIA_ID_PARAM ));
214
+ } else if (params .contains (URI_PARAM )) {
215
+ mInputTypeView .setSelection (URI_INDEX );
216
+ mUriInput .setText (data .getQueryParameter (URI_PARAM ));
217
+ }
218
+ } else if (intent .hasExtra (PACKAGE_NAME_EXTRA )) {
219
+ appPackageName = intent .getStringExtra (PACKAGE_NAME_EXTRA );
220
+ } else {
221
+ appPackageName = null ;
222
+ }
223
+
224
+ // Create app details from URI, if one was present.
225
+ if (appPackageName != null ) {
226
+ if (mMediaAppDetails == null || !appPackageName .equals (CURRENT_PACKAGE )) {
227
+ final MediaAppDetails appDetails = buildMediaDetailsFromPackage (appPackageName );
228
+
229
+ if (appDetails == null ) {
230
+ // Couldn't build the media app details so alert the user and exit.
231
+ Toast .makeText (this ,
232
+ getString (R .string .no_app_for_package , appPackageName ),
233
+ Toast .LENGTH_LONG )
234
+ .show ();
235
+ finish ();
236
+ return ;
237
+ } else {
238
+ mMediaAppDetails = appDetails ;
239
+ }
240
+ }
178
241
}
179
242
180
243
final Bundle extras = intent .getExtras ();
181
- if (extras != null && extras .containsKey (APP_DETAILS_EXTRA )) {
182
- mMediaAppDetails = extras .getParcelable (APP_DETAILS_EXTRA );
244
+ if (extras != null ) {
245
+ // Pull data out of the extras, if they're there.
246
+ if (extras .containsKey (SEARCH_EXTRA )) {
247
+ mInputTypeView .setSelection (SEARCH_INDEX );
248
+ mUriInput .setText (extras .getString (SEARCH_EXTRA ));
249
+ } else if (extras .containsKey (MEDIA_ID_EXTRA )) {
250
+ mInputTypeView .setSelection (MEDIA_ID_INDEX );
251
+ mUriInput .setText (extras .getString (MEDIA_ID_EXTRA ));
252
+ } else if (extras .containsKey (URI_EXTRA )) {
253
+ mInputTypeView .setSelection (URI_INDEX );
254
+ mUriInput .setText (extras .getString (URI_EXTRA ));
255
+ }
256
+
257
+ // It's also possible we're here from LaunchActivity, which did all this work for us.
258
+ if (extras .containsKey (APP_DETAILS_EXTRA )) {
259
+ mMediaAppDetails = extras .getParcelable (APP_DETAILS_EXTRA );
260
+ }
183
261
}
184
262
}
185
263
@@ -211,6 +289,31 @@ private void setupMediaController() {
211
289
mBrowser .connect ();
212
290
}
213
291
292
+ private MediaAppDetails buildMediaDetailsFromPackage (final String packageName ) {
293
+ final PackageManager packageManager = getPackageManager ();
294
+
295
+ final Intent mediaBrowserIntent = new Intent (MediaBrowserServiceCompat .SERVICE_INTERFACE );
296
+ final List <ResolveInfo > services =
297
+ packageManager .queryIntentServices (mediaBrowserIntent ,
298
+ PackageManager .GET_RESOLVED_FILTER );
299
+ for (ResolveInfo info : services ) {
300
+ if (info .serviceInfo .packageName .equals (packageName )) {
301
+ final Drawable icon = info .loadIcon (packageManager );
302
+ final String name = info .loadLabel (packageManager ).toString ();
303
+ final String serviceName = info .serviceInfo .name ;
304
+ final ComponentName serviceComponentName =
305
+ new ComponentName (packageName , serviceName );
306
+ return new MediaAppDetails (
307
+ name ,
308
+ serviceComponentName ,
309
+ BitmapUtils .convertDrawable (getResources (), icon ));
310
+ }
311
+ }
312
+
313
+ // Failed to find package.
314
+ return null ;
315
+ }
316
+
214
317
private void setupButtons () {
215
318
216
319
final PreparePlayHandler preparePlayHandler = new PreparePlayHandler (this );
0 commit comments