Android - screen listing for chrome plating via custom app

I need to do the same in the Chromecast app (com.google.android.apps.chromecast.app) "Mirror Screen":

pressing a custom button the app will ask you to select a chrome plating device to stream and then start screen mirroring to the selected chrome plating device.

This feature is not actually documented anywhere. Am I using a presentation class?

Reading the Chromecast app logs I found the following target app IDs:

app id E8C28D3C
app name Backdrop

app id 674A0243
app name Screen Mirroring

      

How can i do this?

This is my code:

    public class MainActivity extends ActionBarActivity
{

    private MediaRouter mMediaRouter;
    private MediaRouteSelector mMediaRouteSelector;
    private android.support.v7.media.MediaRouter.Callback mMediaRouterCallback;
    private CastDevice mSelectedDevice;
    private GoogleApiClient mApiClient;
    private Cast.Listener mCastClientListener;
    private ConnectionCallbacks mConnectionCallbacks;
    private ConnectionFailedListener mConnectionFailedListener;
    private boolean mWaitingForReconnect;
    private boolean mApplicationStarted;
    private String mSessionId;
    private DemoPresentation mPresentation;

    private final static String TAG = "CAST-APP";
    private String mAppID = "AE85BA70";
    private String mirroringAppID="674A0243";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMediaRouter = MediaRouter.getInstance(getApplicationContext());
        mMediaRouteSelector = new MediaRouteSelector.Builder()
                //.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
                //.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
                //.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
                //.addControlCategory(CastMediaControlIntent.categoryForCast(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID))
                .addControlCategory(CastMediaControlIntent.categoryForCast(mirroringAppID))
                .build();

        mMediaRouterCallback = new MyMediaRouterCallback();

        /*MediaRouteButton btn = (MediaRouteButton) findViewById(R.id.mediabutton);
        btn.setRouteSelector(mMediaRouteSelector);*/
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        super.onCreateOptionsMenu(menu);

        getMenuInflater().inflate(R.menu.menu_main, menu);

        MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);

        MediaRouteActionProvider mediaRouteActionProvider =
                (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);

        mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        int id = item.getItemId();
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
                                 MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
    }

    @Override
    protected void onPause() {
        if (isFinishing()) {
            mMediaRouter.removeCallback(mMediaRouterCallback);
        }
        super.onPause();
    }
/*
    @Override
    protected void onStart() {
        super.onStart();
        mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
                                 MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
    }

    @Override
    protected void onStop() {
        mMediaRouter.removeCallback(mMediaRouterCallback);
        super.onStop();
    }
*/

    private class MyMediaRouterCallback extends MediaRouter.Callback {

        @Override
        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
            try
            {
                mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
                String routeId = info.getId();

                mCastClientListener = new Cast.Listener()
                {
                    @Override
                    public void onApplicationStatusChanged()
                    {
                        if (mApiClient != null)
                        {
                            Log.d(TAG, "onApplicationStatusChanged: "
                                    + Cast.CastApi.getApplicationStatus(mApiClient));

                            //updatePresentation();

                        }
                    }

                    @Override
                    public void onVolumeChanged()
                    {
                        if (mApiClient != null)
                        {
                            Log.d(TAG, "onVolumeChanged: " + Cast.CastApi.getVolume(mApiClient));
                        }
                    }

                    @Override
                    public void onApplicationDisconnected(int errorCode)
                    {
                        teardown();
                    }
                };

                mConnectionCallbacks = new ConnectionCallbacks();
                mConnectionFailedListener = new ConnectionFailedListener();

                Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions
                        .builder(mSelectedDevice, mCastClientListener);

                mApiClient = new GoogleApiClient.Builder(getApplication())
                        .addApi(Cast.API, apiOptionsBuilder.build())
                        .addConnectionCallbacks(mConnectionCallbacks)
                        .addOnConnectionFailedListener(mConnectionFailedListener)
                        .build();

                mApiClient.connect();

            } catch (Exception e) {
                Log.d(TAG, "onRouteSelected " + e.getMessage());
            }

        }

        @Override
        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) {
            Log.d(TAG, "onRouteUnselected: info=" + info);
            teardown();
            //updatePresentation();
            mSelectedDevice = null;
        }

        @Override
        public void onRoutePresentationDisplayChanged(MediaRouter router, MediaRouter.RouteInfo info) {

            //updatePresentation();
        }
    }

    private void showPresentation()
    {
        DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
        Display[] presentationDisplays = displayManager.getDisplays();

        Log.d("showPresentation", "Displays: " + String.valueOf(presentationDisplays.length));

        if (presentationDisplays.length > 0) {

            Log.d("showPresentation", "Display : " + presentationDisplays[0].getName());

            Display display = presentationDisplays[0];
            mPresentation = new DemoPresentation(this, display);
            mPresentation.show();
        }



        //updatePresentation();
    }

    private class ConnectionCallbacks implements
            GoogleApiClient.ConnectionCallbacks {
        @Override
        public void onConnected(Bundle connectionHint) {
            if (mWaitingForReconnect) {
                mWaitingForReconnect = false;
                //reconnectChannels();
                if ((connectionHint != null)
                        && connectionHint
                        .getBoolean(Cast.EXTRA_APP_NO_LONGER_RUNNING)) {
                    Log.d(TAG, "App  is no longer running");
                    teardown();
                }
            } else {
                try {
                    Cast.CastApi.launchApplication(mApiClient, mirroringAppID, false)
                            .setResultCallback(
                                    new ResultCallback<Cast.ApplicationConnectionResult>() {
                                        @Override
                                        public void onResult(Cast.ApplicationConnectionResult result) {
                                            Status status = result.getStatus();
                                            if (status.isSuccess()) {
                                                ApplicationMetadata applicationMetadata =
                                                        result.getApplicationMetadata();
                                                mSessionId = result.getSessionId();
                                                String applicationStatus = result.getApplicationStatus();
                                                boolean wasLaunched = result.getWasLaunched();

                                                mApplicationStarted = true;

                                            } else {
                                                teardown();
                                            }
                                        }
                                    });

                } catch (Exception e) {
                    Log.e(TAG, "Failed to launch application", e);
                }
            }
        }

        @Override
        public void onConnectionSuspended(int cause) {
            mWaitingForReconnect = true;
        }
    }

    private class ConnectionFailedListener implements
            GoogleApiClient.OnConnectionFailedListener {
        @Override
        public void onConnectionFailed(ConnectionResult result) {
            teardown();
        }
    }

    private void teardown() {
        Log.d(TAG, "teardown");
        if (mApiClient != null) {
            if (mApplicationStarted) {
                if (mApiClient.isConnected()  || mApiClient.isConnecting()) {
                    try {
                        Cast.CastApi.stopApplication(mApiClient, mSessionId);

                    } catch (Exception e) {
                        Log.e(TAG, "Exception while removing channel", e);
                    }
                    mApiClient.disconnect();
                }
                mApplicationStarted = false;
            }
            mApiClient = null;
        }
        mSelectedDevice = null;
        mWaitingForReconnect = false;
        mSessionId = null;
    }
}

      

+3


source to share


2 answers


You cannot do this from your own application, there are currently no APIs available to developers to trigger cast mirroring from their applications and this must be done manually by the user; this may change in the future, but this is the current status.



+1


source


You don't seem to need to set up any custom presentation screen and mirroring will be done by default:



https://developer.android.com/reference/android/media/MediaRouter.html#ROUTE_TYPE_LIVE_VIDEO

+1


source







All Articles