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

MainActivity.java

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