SampleMediaRouterActivity.java revision 55e47d370890d3cbdab82857090c42df734ba276
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.android.supportv7.media;
18
19import com.example.android.supportv7.R;
20
21import android.content.Intent;
22import android.net.Uri;
23import android.os.Bundle;
24import android.support.v4.view.MenuItemCompat;
25import android.support.v7.app.ActionBarActivity;
26import android.support.v7.app.MediaRouteActionProvider;
27import android.support.v7.media.MediaControlIntent;
28import android.support.v7.media.MediaRouter;
29import android.support.v7.media.MediaRouter.RouteInfo;
30import android.support.v7.media.MediaRouter.ProviderInfo;
31import android.support.v7.media.MediaRouteSelector;
32import android.util.Log;
33import android.view.Menu;
34import android.view.MenuItem;
35import android.view.View;
36import android.view.View.OnClickListener;
37import android.widget.AdapterView.OnItemClickListener;
38import android.widget.AdapterView;
39import android.widget.ArrayAdapter;
40import android.widget.Button;
41import android.widget.ListView;
42import android.widget.TextView;
43import android.widget.Toast;
44
45/**
46 * <h3>Media Router Support Activity</h3>
47 *
48 * <p>
49 * This demonstrates how to use the {@link MediaRouter} API to build an
50 * application that allows the user to send content to various rendering
51 * targets.
52 * </p>
53 */
54public class SampleMediaRouterActivity extends ActionBarActivity {
55    private final String TAG = "MediaRouterSupport";
56
57    private MediaRouter mMediaRouter;
58    private MediaRouteSelector mSelector;
59    private ArrayAdapter<MediaItem> mMediaItems;
60    private TextView mInfoTextView;
61    private ListView mMediaListView;
62    private Button mPlayButton;
63    private Button mStatisticsButton;
64
65    @Override
66    protected void onCreate(Bundle savedInstanceState) {
67        // Be sure to call the super class.
68        super.onCreate(savedInstanceState);
69
70        // Get the media router service.
71        mMediaRouter = MediaRouter.getInstance(this);
72
73        // Create a route selector for the type of routes that we care about.
74        mSelector = new MediaRouteSelector.Builder()
75                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
76                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
77                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
78                .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE)
79                .build();
80
81        // Populate an array adapter with fake media items.
82        String[] mediaNames = getResources().getStringArray(R.array.media_names);
83        String[] mediaUris = getResources().getStringArray(R.array.media_uris);
84        mMediaItems = new ArrayAdapter<MediaItem>(this,
85                android.R.layout.simple_list_item_single_choice, android.R.id.text1);
86        for (int i = 0; i < mediaNames.length; i++) {
87            mMediaItems.add(new MediaItem(mediaNames[i], Uri.parse(mediaUris[i])));
88        }
89
90        // Initialize the layout.
91        setContentView(R.layout.sample_media_router);
92
93        mInfoTextView = (TextView)findViewById(R.id.info);
94
95        mMediaListView = (ListView)findViewById(R.id.media);
96        mMediaListView.setAdapter(mMediaItems);
97        mMediaListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
98        mMediaListView.setOnItemClickListener(new OnItemClickListener() {
99            @Override
100            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
101                updateButtons();
102            }
103        });
104
105        mPlayButton = (Button)findViewById(R.id.play_button);
106        mPlayButton.setOnClickListener(new OnClickListener() {
107            @Override
108            public void onClick(View v) {
109                play();
110            }
111        });
112
113        mStatisticsButton = (Button)findViewById(R.id.statistics_button);
114        mStatisticsButton.setOnClickListener(new OnClickListener() {
115            @Override
116            public void onClick(View v) {
117                showStatistics();
118            }
119        });
120    }
121
122    @Override
123    protected void onResume() {
124        // Be sure to call the super class.
125        super.onResume();
126
127        // Listen for changes to media routes.
128        mMediaRouter.addCallback(mSelector, mCallback,
129                MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
130        updateRouteStatus();
131    }
132
133    @Override
134    protected void onPause() {
135        // Be sure to call the super class.
136        super.onPause();
137
138        // Stop listening for changes to media routes.
139        mMediaRouter.removeCallback(mCallback);
140    }
141
142    @Override
143    public boolean onCreateOptionsMenu(Menu menu) {
144        // Be sure to call the super class.
145        super.onCreateOptionsMenu(menu);
146
147        // Inflate the menu and configure the media router action provider.
148        getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
149
150        MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
151        MediaRouteActionProvider mediaRouteActionProvider =
152                (MediaRouteActionProvider)MenuItemCompat.getActionProvider(mediaRouteMenuItem);
153        mediaRouteActionProvider.setRouteSelector(mSelector);
154
155        // Return true to show the menu.
156        return true;
157    }
158
159    private void updateRouteStatus() {
160        RouteInfo route = mMediaRouter.getSelectedRoute();
161        mInfoTextView.setText("Currently selected route: " + route.getName()
162                + " from provider " + route.getProvider().getPackageName()
163                + ", status: " + route.getStatus());
164        updateButtons();
165    }
166
167    private void updateButtons() {
168        MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
169
170        MediaItem item = getCheckedMediaItem();
171        if (item != null) {
172            mPlayButton.setEnabled(route.supportsControlRequest(makePlayIntent(item)));
173        } else {
174            mPlayButton.setEnabled(false);
175        }
176
177        mStatisticsButton.setEnabled(route.supportsControlRequest(makeStatisticsIntent()));
178    }
179
180    private void play() {
181        final MediaItem item = getCheckedMediaItem();
182        if (item == null) {
183            return;
184        }
185
186        MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
187        Intent intent = makePlayIntent(item);
188        if (route.supportsControlRequest(intent)) {
189            MediaRouter.ControlRequestCallback callback =
190                    new MediaRouter.ControlRequestCallback() {
191                @Override
192                public void onResult(int result, Bundle data) {
193                    switch (result) {
194                        case REQUEST_SUCCEEDED: {
195                            String streamId = data != null ? data.getString(
196                                    MediaControlIntent.EXTRA_ITEM_ID) : null;
197
198                            Log.d(TAG, "Play request succeeded: streamId=" + streamId);
199                            Toast.makeText(SampleMediaRouterActivity.this,
200                                    "Now playing " + item.mName,
201                                    Toast.LENGTH_LONG).show();
202                            break;
203                        }
204
205                        case REQUEST_FAILED:
206                            Log.d(TAG, "Play request failed.");
207                            Toast.makeText(SampleMediaRouterActivity.this,
208                                    "Unable to play " + item.mName,
209                                    Toast.LENGTH_LONG).show();
210                            break;
211                    }
212                }
213            };
214
215            Log.d(TAG, "Sending play request: intent=" + intent);
216            route.sendControlRequest(intent, callback);
217        } else {
218            Log.d(TAG, "Play request not supported: intent=" + intent);
219            Toast.makeText(SampleMediaRouterActivity.this,
220                    "Play not supported for " + item.mName, Toast.LENGTH_LONG).show();
221        }
222    }
223
224    private void showStatistics() {
225        MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
226        Intent intent = makeStatisticsIntent();
227        if (route.supportsControlRequest(intent)) {
228            MediaRouter.ControlRequestCallback callback = new MediaRouter.ControlRequestCallback() {
229                @Override
230                public void onResult(int result, Bundle data) {
231                    switch (result) {
232                        case REQUEST_SUCCEEDED:
233                            Log.d(TAG, "Statistics request succeeded: data=" + data);
234                            if (data != null) {
235                                int playbackCount = data.getInt(
236                                        SampleMediaRouteProvider.DATA_PLAYBACK_COUNT, -1);
237                                Toast.makeText(SampleMediaRouterActivity.this,
238                                        "Total playback count: " + playbackCount,
239                                        Toast.LENGTH_LONG).show();
240                            } else {
241                                Toast.makeText(SampleMediaRouterActivity.this,
242                                        "Statistics query did not return any data",
243                                        Toast.LENGTH_LONG).show();
244                            }
245                            break;
246
247                        case REQUEST_FAILED:
248                            Log.d(TAG, "Statistics request failed: data=" + data);
249                            Toast.makeText(SampleMediaRouterActivity.this,
250                                    "Unable to query statistics.",
251                                    Toast.LENGTH_LONG).show();
252                            break;
253                    }
254                }
255            };
256
257            Log.d(TAG, "Sent statistics request: intent=" + intent);
258            route.sendControlRequest(intent, callback);
259        } else {
260            Log.d(TAG, "Statistics request not supported: intent=" + intent);
261            Toast.makeText(SampleMediaRouterActivity.this,
262                    "Statistics not supported.", Toast.LENGTH_LONG).show();
263        }
264    }
265
266    private Intent makePlayIntent(MediaItem item) {
267        Intent intent = new Intent(MediaControlIntent.ACTION_PLAY);
268        intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
269        intent.setDataAndType(item.mUri, "video/mp4");
270        return intent;
271    }
272
273    private Intent makeStatisticsIntent() {
274        Intent intent = new Intent(SampleMediaRouteProvider.ACTION_GET_STATISTICS);
275        intent.addCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE);
276        return intent;
277    }
278
279    private MediaItem getCheckedMediaItem() {
280        int index = mMediaListView.getCheckedItemPosition();
281        if (index >= 0 && index < mMediaItems.getCount()) {
282            return mMediaItems.getItem(index);
283        }
284        return null;
285    }
286
287    private final MediaRouter.Callback mCallback = new MediaRouter.Callback() {
288        @Override
289        public void onRouteAdded(MediaRouter router, RouteInfo route) {
290            Log.d(TAG, "onRouteAdded: route=" + route);
291        }
292
293        @Override
294        public void onRouteChanged(MediaRouter router, RouteInfo route) {
295            Log.d(TAG, "onRouteChanged: route=" + route);
296            updateRouteStatus();
297        }
298
299        @Override
300        public void onRouteRemoved(MediaRouter router, RouteInfo route) {
301            Log.d(TAG, "onRouteRemoved: route=" + route);
302        }
303
304        @Override
305        public void onRouteSelected(MediaRouter router, RouteInfo route) {
306            Log.d(TAG, "onRouteSelected: route=" + route);
307            updateRouteStatus();
308        }
309
310        @Override
311        public void onRouteUnselected(MediaRouter router, RouteInfo route) {
312            Log.d(TAG, "onRouteUnselected: route=" + route);
313            updateRouteStatus();
314        }
315
316        @Override
317        public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
318            Log.d(TAG, "onRouteVolumeChanged: route=" + route);
319        }
320
321        @Override
322        public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo route) {
323            Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
324        }
325
326        @Override
327        public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
328            Log.d(TAG, "onRouteProviderAdded: provider=" + provider);
329        }
330
331        @Override
332        public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
333            Log.d(TAG, "onRouteProviderRemoved: provider=" + provider);
334        }
335
336        @Override
337        public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
338            Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
339        }
340    };
341
342    private static final class MediaItem {
343        public final String mName;
344        public final Uri mUri;
345
346        public MediaItem(String name, Uri uri) {
347            mName = name;
348            mUri = uri;
349        }
350
351        @Override
352        public String toString() {
353            return mName;
354        }
355    }
356
357    /**
358     * Trivial subclass of this activity used to provide another copy of the
359     * same activity using a light theme instead of the dark theme.
360     */
361    public static class Light extends SampleMediaRouterActivity {
362    }
363
364    /**
365     * Trivial subclass of this activity used to provide another copy of the
366     * same activity using a light theme with dark action bar instead of the dark theme.
367     */
368    public static class LightWithDarkActionBar extends SampleMediaRouterActivity {
369    }
370}
371