android - 连接到 Google API 客户端时出现问题

标签 android google-api chromecast google-api-java-client

我正在构建一个 chromecast 应用程序。我可以用静态文本启动接收器。但是,我无法与它交互(播放媒体)并且正在获取

10-27 10:01:20.192 2292-6161/? E/MDM: [217] b.run: Couldn't connect to Google API client: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null, message=null}

我认为这可能是我在启动应用程序时遇到超时(状态代码15)的问题。我还注意到,接收器屏幕在一段时间后停止转换,而我的发送器设备没有检测到这一点,并且仍然认为这是一个正在进行的 session 。有人看出问题了吗?

请参阅下面的代码以供引用。

public class MediaRouterButtonActivity extends FragmentActivity {

private static final String TAG = MediaRouterButtonActivity.class
        .getSimpleName();

private MediaRouter mMediaRouter;
private MediaRouteSelector mMediaRouteSelector;
private MediaRouter.Callback mMediaRouterCallback;
private MediaRouteButton mMediaRouteButton;
private int mRouteCount = 0;

private MediaMetadata mMediaMetadata;
private CastDevice mSelectedDevice;
private GoogleApiClient mApiClient;
private Cast.Listener mCastListener;
private ConnectionCallbacks mConnectionCallbacks;
private RemoteMediaPlayer mRemoteMediaPlayer;
private boolean mWaitingForReconnect;

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

    mMediaRouter = MediaRouter.getInstance(getApplicationContext());
    mMediaRouteSelector = new MediaRouteSelector.Builder()
            .addControlCategory(
                    CastMediaControlIntent.categoryForCast(getResources().getString(R.string.app_id))).build();

    // Set the MediaRouteButton selector for device discovery.
    mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
    mMediaRouteButton.setRouteSelector(mMediaRouteSelector);

    mMediaRouterCallback = new MediaRouterCallback();

    mCastListener = new CastListener();
    mConnectionCallbacks = new ConnectionCallbacks();
    mConnectionFailedListener = new ConnectionFailedListener();
    mWaitingForReconnect = false;

    mRemoteMediaPlayer = new RemoteMediaPlayer();
}

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

@Override
protected void onResume() {
    super.onResume();

    // Add the callback to start device discovery
    mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
            MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
}

@Override
protected void onPause() {
    mMediaRouter.removeCallback(mMediaRouterCallback);
    super.onPause();
}

@Override
protected void onStop() {
    setSelectedDevice(null);
    mMediaRouter.removeCallback(mMediaRouterCallback);
    super.onStop();
}

private class MediaRouterCallback extends MediaRouter.Callback {
    @Override
    public void onRouteAdded(MediaRouter router, RouteInfo route) {
        Log.d(TAG, "onRouteAdded");
        if (++mRouteCount >= 1) {
            // Show the button when a device is discovered.
            mMediaRouteButton.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onRouteRemoved(MediaRouter router, RouteInfo route) {
        Log.d(TAG, "onRouteRemoved");
        if (--mRouteCount == 0) {
            // Hide the button if there are no devices discovered.
            mMediaRouteButton.setVisibility(View.GONE);
        }
    }

    @Override
    public void onRouteSelected(MediaRouter router, RouteInfo info) {
        Log.d(TAG, "onRouteSelected");
        // Handle route selection
        mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
        setSelectedDevice(mSelectedDevice);
    }

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

private void setSelectedDevice(CastDevice device) {
    Log.d(TAG, "setSelectedDevice: " + device);
    mSelectedDevice = device;

    if (mSelectedDevice != null) {
        try {
            disconnectApiClient();
            connectApiClient();
        } catch (IllegalStateException e) {
            Log.w(TAG, "Exception while connecting API client", e);
            disconnectApiClient();
        }
    } else {
        if (mApiClient != null) {
            disconnectApiClient();
        }
        mMediaRouter.selectRoute(mMediaRouter.getDefaultRoute());
    }
}

private void connectApiClient() {
    Cast.CastOptions apiOptions = Cast.CastOptions.builder(mSelectedDevice, mCastListener)
            .build();
    mApiClient = new GoogleApiClient.Builder(getApplicationContext())
            .addApi(Cast.API, apiOptions)
            .addConnectionCallbacks(mConnectionCallbacks)
            .addOnConnectionFailedListener(mConnectionFailedListener)
            .build();
    Log.d(TAG, "connectApiClient");
    mApiClient.connect();
}

private void disconnectApiClient() {
    if (mApiClient != null) {
        if (mApiClient.isConnected() || mApiClient.isConnecting()) {
            mApiClient.disconnect();
            Log.d(TAG, "disconnectApiClient");
        }
        mApiClient = null;
    }
}

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

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.d(TAG, "ConnectionCallbacks.onConnected");
        if (mWaitingForReconnect) {
            mWaitingForReconnect = false;
        } else {
            Cast.CastApi.launchApplication(mApiClient, getResources().getString(R.string.app_id))
                    .setResultCallback(new ConnectionResultCallback());
        }
    }
}


private final class ConnectionResultCallback implements
        ResultCallback<ApplicationConnectionResult> {
    @Override
    public void onResult(ApplicationConnectionResult result) {
        Status status = result.getStatus();
        Log.d(TAG, "onResultOnConnected" + status.isSuccess());
        if (status.isSuccess()) {
            try {
                Cast.CastApi.setMessageReceivedCallbacks(mApiClient,
                        mRemoteMediaPlayer.getNamespace(),
                        mRemoteMediaPlayer);
                JSONObject customData = new JSONObject();
                String accessToken = "asdkfalksdjfkaljsdfla";
                try {
                    customData.put("X-At", accessToken);
                } catch (JSONException e) {
                    Log.e(TAG, "Empty Access Token", e);
                }
                Log.d(TAG, "mediaMetaDataDebug");
                mMediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
                mMediaMetadata.putString(MediaMetadata.KEY_TITLE, "Demo Video");
                MediaInfo mediaInfo = new MediaInfo.Builder(
                        "https://abcdef.com")       //link Instead
                        .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
                        .setCustomData(customData)
                        .build();
                try {
                    mRemoteMediaPlayer.load(mApiClient, mediaInfo, true)
                            .setResultCallback(new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
                                @Override
                                public void onResult(RemoteMediaPlayer.MediaChannelResult mediaChannelResult) {
                                    Status status = mediaChannelResult.getStatus();
                                    if (status.isSuccess()) {
                                        //allow users to pause video somehow;
                                    }
                                }
                            });

                } catch (Exception e) {
                    Log.e(TAG, "Problem while loading media", e);
                }
                Log.d(TAG, "wtf");
            } catch (IOException e) {
                Log.e(TAG, "Exception while creating channel", e);
            }

        } else {
            Log.d(TAG, "ConnectionResultCallback. Unable to launch the application. statusCode: "
                    + status.getStatusCode());
        }
    }
}


//google play services crap, fix later
private class CastListener extends Cast.Listener {
    @Override
    public void onApplicationDisconnected(int statusCode) {
        Log.d(TAG, "onApplicationDisconnected");
        setSelectedDevice(null);
        try {
            Cast.CastApi.removeMessageReceivedCallbacks(mApiClient,
                    mRemoteMediaPlayer.getNamespace());
        } catch (IOException e) {
            Log.w(TAG, "Exception while launching application", e);
        }
    }
}

}

这是我收到的相关日志

10-27 10:01:20.192 2292-6161/? E/MDM: [217] b.run: Couldn't connect to Google API client: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null, message=null}
10-27 10:59:54.962 2292-19493/? D/DeviceConnectionService: client connected with version: 8115000
10-27 11:01:12.922 27024-27024/? D/MediaRouterButtonActivity: ConnectionCallbacks.onConnected
10-27 11:01:13.002 2292-6727/? D/DeviceConnectionService: client connected with version: 8115000
10-27 11:01:33.952 27024-27024/? D/MediaRouterButtonActivity: ConnectionResultCallback. Unable to launch the application. statusCode: 15

最佳答案

以下更改使其在我的环境中正常工作:

  1. 将应用程序 ID 更改为我有权访问的内容;您可以使用 CastVideos 应用使用的默认应用 ID 或 4F8B3483,或者创建您自己风格的接收器。
  2. MediaInfo 需要有一个内容类型,因此在定义 MediaInfo 的位置添加以下内容:'.setContentType("video/mp4")'
  3. 将内容的网址更新为真实存在且可访问的内容(公共(public)服务器上的 mp4 媒体)

然后我就可以启动应用程序并通过单击“媒体路由按钮”查看媒体播放

关于android - 连接到 Google API 客户端时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33374509/

相关文章:

android - 如何在android中检查设备是平板电脑,手机还是Android TV

java -\n 不会在 AlertDialog 中生成换行符

Android 应用程序在 FragmentActivity.java android.support.v4.app.FragmentActivity.startActivityForResult 上崩溃

android - 如何在 android 中使用访问 token 和 api 在 youtube 上上传视频?

ios - Google 放置网络服务 : How to get next page of results in Swift 3

ios - 如何让 Chrome Cast 在 iOS 后台运行?

android - 如何在 Android 设备中禁用强制网络助手?

使用 Google API 的 Android 融合位置

android - 使用自定义接收器测试 chromecast 应用程序?

android - 如何在 Android 中从 VPN 中排除 Chromecast 连接