这是我的主要课程:
package com.mac.isaac.castcompanionapp;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.MediaRouteActionProvider;
import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.cast.ApplicationMetadata;
import com.google.android.gms.cast.Cast;
import com.google.android.gms.cast.CastDevice;
import com.google.android.gms.cast.CastMediaControlIntent;
import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.cast.MediaStatus;
import com.google.android.gms.cast.RemoteMediaPlayer;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import java.io.IOException;
public class CastActivity extends AppCompatActivity {
private Button mButton;
private MediaRouter mMediaRouter;
private MediaRouteSelector mMediaRouteSelector;
private MediaRouter.Callback mMediaRouterCallback;
private CastDevice mSelectedDevice;
private GoogleApiClient mApiClient;
private RemoteMediaPlayer mRemoteMediaPlayer;
private Cast.Listener mCastClientListener;
private boolean mWaitingForReconnect = false;
private boolean mApplicationStarted = false;
private boolean mVideoIsLoaded;
private boolean mIsPlaying;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("MYTAG", "onCreate()");
mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mVideoIsLoaded)
startVideo();
else
controlVideo();
}
});
initMediaRouter();
}
private void initMediaRouter() {
Log.i("MYTAG", "initMediaRouter()");
// Configure Cast device discovery
mMediaRouter = MediaRouter.getInstance(getApplicationContext());
mMediaRouteSelector = new MediaRouteSelector.Builder()
.addControlCategory(
CastMediaControlIntent.categoryForCast(getString(R.string.app_id)))
.build();
mMediaRouterCallback = new MediaRouterCallback();
}
@Override
protected void onResume() {
super.onResume();
Log.i("MYTAG", "onResume()");
// Start media router discovery
mMediaRouter.addCallback( mMediaRouteSelector,
mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN );
}
@Override
public boolean onCreateOptionsMenu(Menu menu ) {
Log.i("MYTAG", "onCreateOptionsMenu()");
super.onCreateOptionsMenu( menu );
getMenuInflater().inflate( R.menu.menu, menu );
MenuItem mediaRouteMenuItem = menu.findItem( R.id.media_route_menu_item );
MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat.getActionProvider( mediaRouteMenuItem );
mediaRouteActionProvider.setRouteSelector( mMediaRouteSelector );
return true;
}
private void startVideo() {
Log.i("MYTAG", "startVideo()");
MediaMetadata mediaMetadata = new MediaMetadata( MediaMetadata.MEDIA_TYPE_MOVIE );
mediaMetadata.putString( MediaMetadata.KEY_TITLE, getString( R.string.video_title ) );
MediaInfo mediaInfo = new MediaInfo.Builder( getString( R.string.video_url ) )
.setContentType( getString( R.string.content_type_mp4 ) )
.setStreamType( MediaInfo.STREAM_TYPE_BUFFERED )
.setMetadata( mediaMetadata )
.build();
try {
mRemoteMediaPlayer
.load( mApiClient, mediaInfo, true )
.setResultCallback( new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
@Override
public void onResult( RemoteMediaPlayer.MediaChannelResult mediaChannelResult ) {
if( mediaChannelResult.getStatus().isSuccess() ) {
mVideoIsLoaded = true;
mButton.setText( getString( R.string.pause_video ) );
}
}
} );
} catch( Exception e ) {
Log.e("MYTAG", "Error starting video "+e.getMessage());
e.printStackTrace();
}
}
private void controlVideo() {
Log.i("MYTAG", "controlVideo()");
if( mRemoteMediaPlayer == null || !mVideoIsLoaded )
return;
if( mIsPlaying ) {
mRemoteMediaPlayer.pause( mApiClient );
mButton.setText( getString( R.string.resume_video ) );
} else {
mRemoteMediaPlayer.play( mApiClient );
mButton.setText( getString( R.string.pause_video ) );
}
}
private void reconnectChannels( Bundle hint ) {
Log.i("MYTAG", "reconnectChannels()");
if( ( hint != null ) && hint.getBoolean( Cast.EXTRA_APP_NO_LONGER_RUNNING ) ) {
//Log.e( TAG, "App is no longer running" );
teardown();
} else {
try {
Cast.CastApi.setMessageReceivedCallbacks( mApiClient, mRemoteMediaPlayer.getNamespace(), mRemoteMediaPlayer );
} catch( IOException e ) {
Log.e( "MYTAG", "Exception while creating media channel ", e );
} catch( NullPointerException e ) {
Log.e( "MYTAG", "Something wasn't reinitialized for reconnectChannels" );
}
}
}
private class ConnectionFailedListener implements GoogleApiClient.OnConnectionFailedListener {
@Override
public void onConnectionFailed( ConnectionResult connectionResult ) {
Log.i("MYTAG", "onConnectionFailed()");
teardown();
}
}
@Override
protected void onPause() {
Log.i("MYTAG", "onPause()");
if ( isFinishing() ) {
// End media router discovery
mMediaRouter.removeCallback( mMediaRouterCallback );
}
super.onPause();
}
private void teardown() {
Log.i("MYTAG", "teardown()");
if( mApiClient != null ) {
if( mApplicationStarted ) {
try {
Cast.CastApi.stopApplication( mApiClient );
if( mRemoteMediaPlayer != null ) {
Cast.CastApi.removeMessageReceivedCallbacks( mApiClient, mRemoteMediaPlayer.getNamespace() );
mRemoteMediaPlayer = null;
}
} catch( IOException e ) {
Log.e( "MYTAG", "Exception while removing application " + e );
}
mApplicationStarted = false;
}
if( mApiClient.isConnected() )
mApiClient.disconnect();
mApiClient = null;
}
mSelectedDevice = null;
mVideoIsLoaded = false;
}
private void initCastClientListener() {
mCastClientListener = new Cast.Listener() {
@Override
public void onApplicationStatusChanged() {
}
@Override
public void onVolumeChanged() {
}
@Override
public void onApplicationDisconnected( int statusCode ) {
teardown();
}
};
}
private void launchReceiver() {
Log.i("MYTAG", "launchReceiver()");
Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions
.builder( mSelectedDevice, mCastClientListener );
ConnectionCallbacks mConnectionCallbacks = new ConnectionCallbacks();
ConnectionFailedListener mConnectionFailedListener = new ConnectionFailedListener();
mApiClient = new GoogleApiClient.Builder(CastActivity.this)
.addApi( Cast.API, apiOptionsBuilder.build() )
.addConnectionCallbacks( mConnectionCallbacks )
.addOnConnectionFailedListener( mConnectionFailedListener )
.build();
mApiClient.connect();
}
private void initRemoteMediaPlayer() {
Log.i("MYTAG", "initRemoteMediaPlayer()");
mRemoteMediaPlayer = new RemoteMediaPlayer();
mRemoteMediaPlayer.setOnStatusUpdatedListener( new RemoteMediaPlayer.OnStatusUpdatedListener() {
@Override
public void onStatusUpdated() {
MediaStatus mediaStatus = mRemoteMediaPlayer.getMediaStatus();
mIsPlaying = mediaStatus.getPlayerState() == MediaStatus.PLAYER_STATE_PLAYING;
}
});
mRemoteMediaPlayer.setOnMetadataUpdatedListener( new RemoteMediaPlayer.OnMetadataUpdatedListener() {
@Override
public void onMetadataUpdated() {
Log.i("MYTAG", "onMetadataUpdated()");
}
});
}
private class MediaRouterCallback extends MediaRouter.Callback {
@Override
public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
Log.i("MYTAG", "onRouteSelected()");
initCastClientListener();
initRemoteMediaPlayer();
mSelectedDevice = CastDevice.getFromBundle( info.getExtras() );
launchReceiver();
}
@Override
public void onRouteUnselected( MediaRouter router, MediaRouter.RouteInfo info ) {
Log.i("MYTAG", "onRouteUnselected()");
teardown();
mSelectedDevice = null;
mButton.setText( getString( R.string.play_video ) );
mVideoIsLoaded = false;
}
}
private class ConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks {
@Override
public void onConnected( Bundle hint ) {
Log.i("MYTAG", "onConnected()");
if( mWaitingForReconnect ) {
mWaitingForReconnect = false;
reconnectChannels( hint );
} else {
try {
Cast.CastApi.launchApplication( mApiClient, getString( R.string.app_id ), false )
.setResultCallback(
new ResultCallback<Cast.ApplicationConnectionResult>() {
@Override
public void onResult(
Cast.ApplicationConnectionResult applicationConnectionResult) {
Status status = applicationConnectionResult.getStatus();
if( status.isSuccess() ) {
//Values that can be useful for storing/logic
ApplicationMetadata applicationMetadata =
applicationConnectionResult.getApplicationMetadata();
String sessionId =
applicationConnectionResult.getSessionId();
String applicationStatus =
applicationConnectionResult.getApplicationStatus();
boolean wasLaunched =
applicationConnectionResult.getWasLaunched();
mApplicationStarted = true;
reconnectChannels( null );
}
}
}
);
} catch ( Exception e ) {
Log.e("MYTAG", "error launching application");
e.printStackTrace();
}
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i("MYTAG", "onConnectionSuspended()");
mWaitingForReconnect = true;
}
}
}
我在这里收到错误:
mRemoteMediaPlayer.load
它说:
04-23 21:29:31.730 4524-4524/com.mac.isaac.castcompanionapp E/MYTAG: Error starting video Attempt to invoke virtual method 'com.google.android.gms.common.api.PendingResult com.google.android.gms.cast.RemoteMediaPlayer.load(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.cast.MediaInfo, boolean)' on a null object reference
04-23 21:29:31.730 4524-4524/com.mac.isaac.castcompanionapp W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.common.api.PendingResult com.google.android.gms.cast.RemoteMediaPlayer.load(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.cast.MediaInfo, boolean)' on a null object reference
04-23 21:29:31.730 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at com.mac.isaac.castcompanionapp.CastActivity.startVideo(CastActivity.java:110)
04-23 21:29:31.730 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at com.mac.isaac.castcompanionapp.CastActivity.access$100(CastActivity.java:30)
04-23 21:29:31.730 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at com.mac.isaac.castcompanionapp.CastActivity$1.onClick(CastActivity.java:57)
04-23 21:29:31.731 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at android.view.View.performClick(View.java:5204)
04-23 21:29:31.731 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at android.view.View$PerformClick.run(View.java:21153)
04-23 21:29:31.731 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
04-23 21:29:31.731 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
04-23 21:29:31.731 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at android.os.Looper.loop(Looper.java:148)
04-23 21:29:31.731 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
04-23 21:29:31.731 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at java.lang.reflect.Method.invoke(Native Method)
04-23 21:29:31.732 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
04-23 21:29:31.732 4524-4524/com.mac.isaac.castcompanionapp W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
调试我收到了这个错误:
public static final int APPLICATION_NOT_RUNNING状态代码指示 请求的应用程序当前未运行。常数值: 2005
所以我猜问题出在chromecast设备而不是我的应用程序中。但是我的应用程序看起来像是在播放一首歌而不是视频,但仍然没有任何反应。
我可以在工具栏上看到投射按钮,我可以选择一个设备,然后看起来Chromecast在黑屏上持续3秒后重新启动,但是当它没有显示我的视频时。 我认为问题出在我的应用中,因为我无法正确发送信息。 我已经在Cast SDK控制台中设置了所有内容,我尝试了所有3个选项:
我仍然无法找到一个有效的教程(即使是谷歌的GitHub上的教程也不起作用,我认为它没有更新)。 有没有人使用过这个并且有工作样本?
答案 0 :(得分:0)
解决了,我必须选择StyledMediaReceiver,发布应用并重新启动Chromecast设备。每次在Google Cast SDK控制台中进行更改时,都必须重新启动chromecast设备才能获得它(看起来它只在启动时获取信息)。 我希望这有助于其他有同样问题的人。