是否可以在活动之间传递Chromcast连接信息?

时间:2015-05-26 01:58:57

标签: android chromecast

我正在开发一个连接到Chromecast的应用程序,当我从一个活动中执行此操作时,一切正常,问题是,我希望该活动是全屏的,没有操作栏,也没有软按钮。我正在实现这一点,当用户连接到Chromecast时隐藏它们,但如果用户从第一个活动(使用操作栏)连接然后转到第二个活动并且那里发生魔术会更好。但我无法在活动之间通过会议。我已经按照this教程与chromecast进行了沟通,但尝试改变一点,以便进行2次活动。

当然,我已对其进行了测试,并返回NullPointerException

ConnectionFailedListener.java

public class ConnectionFailedListener  implements GoogleApiClient.OnConnectionFailedListener {
private String TAG;
private MyConnectionCallbacks myConnectionCB;

public ConnectionFailedListener(String _TAG)
{
    this.TAG=_TAG;
}
private void setMyConnectionCallBack(MyConnectionCallbacks _ConnectionCallbacks)
{
    this.myConnectionCB = _ConnectionCallbacks;
}
@Override
public void onConnectionFailed(ConnectionResult result)
{
    Log.e(TAG, "onConnectionFailed ");
    myConnectionCB.teardown();
}
}

Channel.java

public class EventChannel implements Cast.MessageReceivedCallback
{
    private Context myContext;
    private String TAG;
    /**
     * @return custom namespace
     */
    public EventChannel(Context _context, String _TAG)
    {
        this.myContext = _context;
        this.TAG = _TAG;
    }
    public String getNamespace()

    {
        return  myContext.getString(R.string.namespace);
    }

    /*
     * Receive message from the receiver app
     */

    @Override
    public void onMessageReceived(CastDevice castDevice, String namespace,String message)
    {
        Log.d(TAG, "onMessageReceived: " + message);
    }

}

ConnectionCallbacks.java

public class MyConnectionCallbacks implements   GoogleApiClient.ConnectionCallbacks
{
    private String TAG;
    private Context myContext;
    public CastDevice mSelectedDevice;
    private GoogleApiClient mApiClient;
    private boolean mWaitingForReconnect;
    private EventChannel mEventChannel;
    private String mSessionId;
    private boolean mApplicationStarted;
    private EventChannel myChannel;

    public MyConnectionCallbacks(Context _context, String _TAG)
    {
        this.myContext=_context;
        this.TAG = _TAG;
    }
    public void setApiClient(GoogleApiClient _newApiClient)
    {
        this.mApiClient = _newApiClient;
    }

    @Override
    public void onConnected(Bundle connectionHint)
    {
        Log.d(TAG, "onConnected");
        if (mApiClient == null)
        {
            // We got disconnected while this runnable was pending execution.
            return;
        }

        try
        {
            if (mWaitingForReconnect)
            {
                mWaitingForReconnect = false;
                // Check if the receiver app is still running
                if ((connectionHint != null) && connectionHint.getBoolean(Cast.EXTRA_APP_NO_LONGER_RUNNING))
                {
                    Log.d(TAG, "App  is no longer running");
                    teardown();
                }
                else
                {// Re-create the custom message channel
                    try
                    {
                        Cast.CastApi.setMessageReceivedCallbacks(mApiClient,mEventChannel.getNamespace(),mEventChannel);
                    }
                    catch (IOException e)
                    {
                        Log.e(TAG, "Exception while creating channel", e);
                    }
                }
            }
            else
            {// Launch the receiver app because is connected
                Cast.CastApi.launchApplication(mApiClient,myContext.getString(R.string.app_id), false).setResultCallback(
                        new ResultCallback<Cast.ApplicationConnectionResult>()
                        {
                            @Override
                            public void onResult(Cast.ApplicationConnectionResult result) {
                                Status status = result.getStatus();
                                Log.d(TAG,"ApplicationConnectionResultCallback.onResult: statusCode"+ status.getStatusCode());
                                if (status.isSuccess())
                                {
                                    ApplicationMetadata applicationMetadata = result.getApplicationMetadata();
                                    mSessionId = result.getSessionId();
                                    String applicationStatus = result.getApplicationStatus();
                                    boolean wasLaunched = result.getWasLaunched();

                                    Log.d(TAG,"application name: "+ applicationMetadata.getName()
                                            + ", status: "+ applicationStatus
                                            + ", sessionId: "+ mSessionId
                                            + ", wasLaunched: "+ wasLaunched);
                                    mApplicationStarted = true;
                                    // Create the custom message channel
                                    mEventChannel = new EventChannel(myContext,TAG);
                                    try
                                    {
                                        Cast.CastApi.setMessageReceivedCallbacks(mApiClient,mEventChannel.getNamespace(),mEventChannel);
                                    }
                                    catch (IOException e)
                                    {
                                        Log.e(TAG,"Exception while creating channel",e);
                                    }
                                    // set the initial instructions on the receiver
                                    sendMessage("starting from mobile");
                                }
                                else
                                {
                                    Log.e(TAG,"application could not launch");
                                    teardown();
                                }
                            }
                        });
            }
        }
        catch (Exception e)
        {
            Log.e(TAG, "Failed to launch application", e);
        }
    }

    @Override
    public void onConnectionSuspended(int cause)
    {
        Log.d(TAG, "onConnectionSuspended");
        mWaitingForReconnect = true;
    }

    public void sendMessage(String message)
    {
        if (mApiClient != null && mEventChannel != null)
        {
            try
            {
                Cast.CastApi.sendMessage(mApiClient,mEventChannel.getNamespace(), message)
                        .setResultCallback(new ResultCallback<Status>() {
                            @Override
                            public void onResult(Status result)
                            {
                                if (!result.isSuccess())
                                {
                                    Log.e(TAG, "Sending message failed");
                                }
                            }
                        });
            }
            catch (Exception e)
            {
                Log.e(TAG, "Exception while sending message", e);
            }
        }
        else
        {
            Toast.makeText(myContext, message, Toast.LENGTH_SHORT).show();
        }
    }

    public void teardown()
    {
        Log.d(TAG, "teardown");
        if (mApiClient != null)
        {
            if (mApplicationStarted)
            {
                if (mApiClient.isConnected() || mApiClient.isConnecting())
                {
                    try
                    {
                        Cast.CastApi.stopApplication(mApiClient, mSessionId);
                        if (myChannel != null)
                        {
                            Cast.CastApi.removeMessageReceivedCallbacks(mApiClient,myChannel.getNamespace());
                            myChannel = null;
                        }
                    }
                    catch (IOException e)
                    {
                        Log.e(TAG, "Exception while removing channel", e);
                    }
                    mApiClient.disconnect();
                }
                mApplicationStarted = false;
            }
            mApiClient = null;
        }
        mSelectedDevice = null;
        mWaitingForReconnect = false;
        mSessionId = null;
    }
}

MediaRouterCallback.java

public class MyMediaRouterCallback extends MediaRouter.Callback {

    private GoogleApiClient mApiClient;
    private Cast.Listener mCastListener;
    private Context myContext;
    private ConnectionFailedListener mConnectionFailedListener;
    public MyConnectionCallbacks mConnectionCallbacks;

    public String TAG;
    //private String mSessionId;

    public MyMediaRouterCallback(Context _context, String _TAG)
    {
        this.myContext = _context;
        this.TAG = _TAG;
        mConnectionCallbacks = new MyConnectionCallbacks(myContext,TAG);
    }

    @Override
    public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
        Log.d(TAG, "onRouteSelected");

        mConnectionCallbacks.mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
        launchReceiver();
    }

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

    private void launchReceiver()
    {
        try
        {
            mCastListener = new Cast.Listener() {
                @Override
                public void onApplicationDisconnected(int errorCode) {
                    Log.d(TAG, "application has stopped");
                    mConnectionCallbacks.teardown();
                }
            };
            //Constructors for Google Play Services Connection
            //mConnectionCallbacks = new MyConnectionCallbacks(myContext,TAG);
            mConnectionFailedListener = new ConnectionFailedListener(TAG);
            Cast.CastOptions.Builder apiOptionsBuilder =
            Cast.CastOptions.builder(mConnectionCallbacks.mSelectedDevice, mCastListener);
            // ApiClient to Connect to Google Play services
            mApiClient = new GoogleApiClient.Builder(myContext)
                    .addApi(Cast.API, apiOptionsBuilder.build())
                    .addConnectionCallbacks(mConnectionCallbacks)
                    .addOnConnectionFailedListener(mConnectionFailedListener)
                    .build();
            mConnectionCallbacks.setApiClient(mApiClient);//setting ApiClient to achieve sendMessage
            //Connect to Google Play services
            mApiClient.connect();
        }
        catch (Exception e)
        {
            Log.e(TAG, "Failed launchReceiver", e);
        }
    }
}

FirstActivity (连接chromecast的地方)

public class ConnectCastActivity extends ActionBarActivity {

    private static final String TAG = ConnectCastActivity.class.getSimpleName();
    private MediaRouter mMediaRouter;
    private MediaRouteSelector mMediaRouteSelector;
    private MediaRouter.Callback mMediaRouterCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));
        setContentView(R.layout.activity_connect_cast);

        // Configure Cast device discovery
        mMediaRouter = MediaRouter.getInstance(getApplicationContext());
        mMediaRouteSelector = new MediaRouteSelector.Builder().addControlCategory(CastMediaControlIntent.categoryForCast(getResources().getString(R.string.app_id))).build();
        mMediaRouterCallback = new MyMediaRouterCallback(getApplicationContext(),TAG);

        TextView myTextView = (TextView)findViewById(R.id.txt_helloworld);
        myTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(getApplicationContext(),MainActivity.class);
                startActivity(i);

            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Start media router discovery
        mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
    }

    @Override
    protected void onStop() {
        // End media router discovery
        Log.w(TAG, "onStop");
        //mMediaRouter.removeCallback(mMediaRouterCallback);
        super.onStop();
    }

    @Override
    public void onDestroy() {
        Log.w(TAG, "onDestroy");
//        mMediaRouterCallback.onRouteUnselected(mMediaRouter,null);
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu_connect_cast, menu);
        MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
        MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);
        // Set the MediaRouteActionProvider selector for device discovery.
        mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector);
        return true;
    }

}

SecondActivity (将发送消息的那个)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MediaRouter mMediaRouter = MediaRouter.getInstance(getApplicationContext());

        mConnectionCallbacks = new MyConnectionCallbacks(getApplicationContext(),TAG);
        setContentView(R.layout.activity_main);

    //What should I put here?

}

1 个答案:

答案 0 :(得分:0)

如果您的应用程序具有多个活动,那么如果您不将强制转换连接和相关状态与任何这些活动联系起来,那么您最好使用单例,或者使用您的Application实例或使用后台服务或...维护连接并访问在该全局位置维护的所需部分。如果它符合您的要求,您可能希望使用已经完成大部分常规工作的CastCompanionLibrary;如果没有,您可以查看它,看看CastVideos示例应用程序如何使用它并尝试为您的应用程序执行类似操作。