BasicMediaRouter / src / com.example.android.basicmediarouter /

MainActivity.java

1
/*
2
 * Copyright 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
 
17
package com.example.android.basicmediarouter;
18
 
19
import android.app.Activity;
20
import android.app.MediaRouteActionProvider;
21
import android.content.Context;
22
import android.content.DialogInterface;
23
import android.media.MediaRouter;
24
import android.media.MediaRouter.RouteInfo;
25
import android.os.Bundle;
26
import android.view.Display;
27
import android.view.Menu;
28
import android.view.MenuItem;
29
import android.view.View;
30
import android.view.WindowManager;
31
import android.widget.Button;
32
import android.widget.TextView;
33
 
34
/**
35
 * <p>
36
 * This sample demonstrates the use of the MediaRouter API to show content on a
37
 * secondary display using a {@link android.app.Presentation}.
38
 * </p>
39
 * <p>
40
 * The activity uses the {@link android.media.MediaRouter} API to automatically detect when a
41
 * presentation display is available and to allow the user to control the media
42
 * routes using a menu item provided by the {@link android.app.MediaRouteActionProvider}.
43
 * When a presentation display is available a {@link android.app.Presentation} (implemented
44
 * as a {@link SamplePresentation}) is shown on the preferred display. A button
45
 * toggles the background color of the secondary screen to show the interaction
46
 * between the primary and secondary screens.
47
 * </p>
48
 * <p>
49
 * This sample requires an HDMI or Wifi display. Alternatively, the
50
 * "Simulate secondary displays" feature in Development Settings can be enabled
51
 * to simulate secondary displays.
52
 * </p>
53
 *
54
 * @see android.app.Presentation
55
 * @see android.media.MediaRouter
56
 */
57
public class MainActivity extends Activity {
58
 
59
    private MediaRouter mMediaRouter;
60
 
61
    // Active Presentation, set to null if no secondary screen is enabled
62
    private SamplePresentation mPresentation;
63
 
64
    @Override
65
    protected void onCreate(Bundle savedInstanceState) {
66
        super.onCreate(savedInstanceState);
67
 
68
        setContentView(R.layout.sample_main);
69
        mTextStatus = (TextView) findViewById(R.id.textStatus);
70
 
71
        // get the list of background colors
72
        mColors = getResources().getIntArray(R.array.androidcolors);
73
 
74
        // Enable clicks on the 'change color' button
75
        mButton = (Button) findViewById(R.id.button1);
76
        mButton.setOnClickListener(new View.OnClickListener() {
77
 
78
            @Override
79
            public void onClick(View v) {
80
                showNextColor();
81
            }
82
        });
83
 
85
        // Get the MediaRouter service
86
        mMediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
88
    }
89
 
90
    /**
91
     * Implementing a {@link android.media.MediaRouter.Callback} to update the displayed
92
     * {@link android.app.Presentation} when a route is selected, unselected or the
93
     * presentation display has changed. The provided stub implementation
94
     * {@link android.media.MediaRouter.SimpleCallback} is extended and only
95
     * {@link android.media.MediaRouter.SimpleCallback#onRouteSelected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo)}
96
     * ,
97
     * {@link android.media.MediaRouter.SimpleCallback#onRouteUnselected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo)}
98
     * and
99
     * {@link android.media.MediaRouter.SimpleCallback#onRoutePresentationDisplayChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo)}
100
     * are overridden to update the displayed {@link android.app.Presentation} in
101
     * {@link #updatePresentation()}. These callbacks enable or disable the
102
     * second screen presentation based on the routing provided by the
103
     * {@link android.media.MediaRouter} for {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO}
104
     * streams. @
105
     */
106
    private final MediaRouter.SimpleCallback mMediaRouterCallback =
107
            new MediaRouter.SimpleCallback() {
108
 
110
                /**
111
                 * A new route has been selected as active. Disable the current
112
                 * route and enable the new one.
113
                 */
114
                @Override
115
                public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
116
                    updatePresentation();
117
                }
118
 
119
                /**
120
                 * The route has been unselected.
121
                 */
122
                @Override
123
                public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
124
                    updatePresentation();
125
 
126
                }
127
 
128
                /**
129
                 * The route's presentation display has changed. This callback
130
                 * is called when the presentation has been activated, removed
131
                 * or its properties have changed.
132
                 */
133
                @Override
134
                public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
135
                    updatePresentation();
136
                }
138
            };
139
 
140
    /**
141
     * Updates the displayed presentation to enable a secondary screen if it has
142
     * been selected in the {@link android.media.MediaRouter} for the
143
     * {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO} type. If no screen has been
144
     * selected by the {@link android.media.MediaRouter}, the current screen is disabled.
145
     * Otherwise a new {@link SamplePresentation} is initialized and shown on
146
     * the secondary screen.
147
     */
148
    private void updatePresentation() {
149
 
151
        // Get the selected route for live video
152
        RouteInfo selectedRoute = mMediaRouter.getSelectedRoute(
153
                MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
154
 
155
        // Get its Display if a valid route has been selected
156
        Display selectedDisplay = null;
157
        if (selectedRoute != null) {
158
            selectedDisplay = selectedRoute.getPresentationDisplay();
159
        }
161
 
163
        /*
164
         * Dismiss the current presentation if the display has changed or no new
165
         * route has been selected
166
         */
167
        if (mPresentation != null && mPresentation.getDisplay() != selectedDisplay) {
168
            mPresentation.dismiss();
169
            mPresentation = null;
170
            mButton.setEnabled(false);
171
            mTextStatus.setText(R.string.secondary_notconnected);
172
        }
174
 
176
        /*
177
         * Show a new presentation if the previous one has been dismissed and a
178
         * route has been selected.
179
         */
180
        if (mPresentation == null && selectedDisplay != null) {
181
 
182
            // Initialise a new Presentation for the Display
183
            mPresentation = new SamplePresentation(this, selectedDisplay);
184
            mPresentation.setOnDismissListener(mOnDismissListener);
185
 
186
            // Try to show the presentation, this might fail if the display has
187
            // gone away in the mean time
188
            try {
189
                mPresentation.show();
190
                mTextStatus.setText(getResources().getString(R.string.secondary_connected,
191
                        selectedRoute.getName(MainActivity.this)));
192
                mButton.setEnabled(true);
193
                showNextColor();
194
            } catch (WindowManager.InvalidDisplayException ex) {
195
                // Couldn't show presentation - display was already removed
196
                mPresentation = null;
197
            }
198
        }
200
 
201
    }
202
 
203
    @Override
204
    protected void onResume() {
205
        super.onResume();
206
 
208
        // Register a callback for all events related to live video devices
209
        mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, mMediaRouterCallback);
211
 
212
        // Show the 'Not connected' status message
213
        mButton.setEnabled(false);
214
        mTextStatus.setText(R.string.secondary_notconnected);
215
 
216
        // Update the displays based on the currently active routes
217
        updatePresentation();
218
    }
219
 
220
    @Override
221
    protected void onPause() {
222
        super.onPause();
223
 
225
        // Stop listening for changes to media routes.
226
        mMediaRouter.removeCallback(mMediaRouterCallback);
228
    }
229
 
230
    @Override
231
    protected void onStop() {
232
        super.onStop();
233
 
235
        // Dismiss the presentation when the activity is not visible.
236
        if (mPresentation != null) {
237
            mPresentation.dismiss();
238
            mPresentation = null;
239
        }
241
    }
242
 
243
    /**
244
     * Inflates the ActionBar or options menu. The menu file defines an item for
245
     * the {@link android.app.MediaRouteActionProvider}, which is registered here for all
246
     * live video devices using {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO}.
247
     */
248
    @Override
249
    public boolean onCreateOptionsMenu(Menu menu) {
250
        super.onCreateOptionsMenu(menu);
251
 
252
        getMenuInflater().inflate(R.menu.main, menu);
253
 
255
        // Configure the media router action provider
256
        MenuItem mediaRouteMenuItem = menu.findItem(R.id.menu_media_route);
257
        MediaRouteActionProvider mediaRouteActionProvider =
258
                (MediaRouteActionProvider) mediaRouteMenuItem.getActionProvider();
259
        mediaRouteActionProvider.setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
261
 
262
        return true;
263
    }
264
 
265
    /**
266
     * Listens for dismissal of the {@link SamplePresentation} and removes its
267
     * reference.
268
     */
269
    private final DialogInterface.OnDismissListener mOnDismissListener =
270
            new DialogInterface.OnDismissListener() {
271
                @Override
272
                public void onDismiss(DialogInterface dialog) {
273
                    if (dialog == mPresentation) {
274
                        mPresentation = null;
275
                    }
276
                }
277
            };
278
 
279
    // Views used to display status information on the primary screen
280
    private TextView mTextStatus;
281
    private Button mButton;
282
 
283
    // selected color index
284
    private int mColor = 0;
285
 
286
    // background colors
287
    public int[] mColors;
288
 
289
    /**
290
     * Displays the next color on the secondary screen if it is activate.
291
     */
292
    private void showNextColor() {
293
        if (mPresentation != null) {
294
            // a second screen is active and initialized, show the next color
295
            mPresentation.setColor(mColors[mColor]);
296
            mColor = (mColor + 1) % mColors.length;
297
        }
298
    }
299
 
300
}