android - 如何使用 Google Cast SDK 3 添加自定义 SessionProvider

标签 android chromecast google-cast samsung-smart-tv

我们最近将 Google Cast SDK 更新到了版本 3。有了这个 SDK,应该可以通过在 OptionsProvider 中实现 getAdditionalSessionProviders() 添加对非转换设备的支持。 .我们创建了自定义 SessionProvider使用 getAdditionalSessionProviders() 方法返回。

但是,此 SessionProvider 从未被使用过,它可能仅在设备已被发现并在选择列表中被选中时使用 MediaRouteButtonSession 中所述按下文档。但是我们找不到将我们发现的非转换设备添加到此列表的方法。我们搜索了在线提供的 API、文档和示例,但找不到如何执行此操作。我们只找到了旧 sdk 版本的示例,但这些完全不同且无法使用。

我们希望使用此功能通过三星的 SmartView SDK 将三星电视添加到 Google Cast 列表中,就像 YouTube 和 Netflix 应用一样。

最佳答案

创建一个自定义媒体路由提供者:这是一个用于自定义媒体路由的假 MediaRouteProvider。这个类除了发布一个假的自定义 MediaRoute 之外什么都不做,这样它就可以被 MediaRouter 的 Cast SDK 看到和选择。

import android.content.Context;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.support.v7.media.MediaRouteDescriptor;
import android.support.v7.media.MediaRouteDiscoveryRequest;
import android.support.v7.media.MediaRouteProvider;
import android.support.v7.media.MediaRouteProvider.RouteController;
import android.support.v7.media.MediaRouteProviderDescriptor;
import android.support.v7.media.MediaRouter;
import java.util.ArrayList;

public final class CustomMediaRouteProvider extends MediaRouteProvider {
  private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC;
  private static MediaRouteDescriptor DEFAULT_MEDIA_ROUTE_DESCRIPTOR;

  static {
    // This filter will be used by Cast SDK to match the session category.
    IntentFilter customControls = new IntentFilter();
    customControls.addCategory(CustomSessionProvider.CUSTOM_CATEGORY);

    CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>();
    CONTROL_FILTERS_BASIC.add(customControls);

    Bundle extras = new Bundle();
    extras.putCharSequence("ROUTE_URL", "http://abcdef.cyz");
    DEFAULT_MEDIA_ROUTE_DESCRIPTOR =
        new MediaRouteDescriptor.Builder("fake-custom-route-id", "fake custom route")
            .setDescription("Foo description")
            .addControlFilters(CONTROL_FILTERS_BASIC)
            .setPlaybackStream(AudioManager.STREAM_MUSIC)
            .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
            .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
            .setVolumeMax(100)
            .setVolume(10)
            .setExtras(extras)
            .build();
  }

  public CustomMediaRouteProvider(Context context) {
    super(context);
  }

  @Override
  public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
    if (request == null || request.getSelector() == null) {
      return;
    }

    publishRoutes();
  }

  @Override
  public RouteController onCreateRouteController(String routeId) {
    return null;
  }

  private void publishRoutes() {
    MediaRouteProviderDescriptor providerDescriptor =
        new MediaRouteProviderDescriptor.Builder().addRoute(DEFAULT_MEDIA_ROUTE_DESCRIPTOR).build();

    setDescriptor(providerDescriptor);
  }
}

您的自定义 session 需要一个 SessionProvider 实现:

import android.content.Context;
import com.google.android.gms.cast.framework.Session;
import com.google.android.gms.cast.framework.SessionProvider;

public class CustomSessionProvider extends SessionProvider {
  public static final String CUSTOM_CATEGORY = "CUSTOM";

  public CustomSessionProvider(Context applicationContext) {
    super(applicationContext, CUSTOM_CATEGORY);
  }

  @Override
  public Session createSession(String sessionId) {
    return new CustomSession(getContext(), getCategory(), sessionId);
  }

  @Override
  public boolean isSessionRecoverable() {
    return true;
  }
}

还有一个 Session 实现:这里是自定义媒体路由类型的假 Session 实现。它总是在开始/恢复/结束时成功。

import android.content.Context;
import android.os.Bundle;
import com.google.android.gms.cast.framework.Session;

public class CustomSession extends Session {
  private static final String FAKE_SESSION_ID = "custom.session.id.12345";

  CustomSession(Context applicationContext, String category, String sessionId) {
    super(applicationContext, category, sessionId);
  }

  @Override
  protected void start(Bundle routeInfoExtra) {
    notifySessionStarted(FAKE_SESSION_ID);
  }

  @Override
  protected void resume(Bundle routeInfoExtra) {
    notifySessionResumed(false);
  }

  @Override
  protected void end(boolean stopCasting) {
    notifySessionEnded(0);
  }
}

在您的 Cast V3 发送器应用中,指定额外的 session 提供程序:

public class CastOptionsProvider implements OptionsProvider {
@Override
  public List<SessionProvider> getAdditionalSessionProviders(Context appContext) {
    List<SessionProvider> additionalProviders = new ArrayList<>();
    additionalProviders.add(new CustomSessionProvider(appContext));
    return additionalProviders;
  }
}

在您的应用程序中添加 MediaRouter 提供程序:

public class CastVideosApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    MediaRouter mediaRouter = MediaRouter.getInstance(this);
    mediaRouter.addProvider(new CustomMediaRouteProvider(this));
  }
}

关于android - 如何使用 Google Cast SDK 3 添加自定义 SessionProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39148993/

相关文章:

android - ListView 和列表 Activity

java - 重置其他字段后如何重置日历对象中的时间参数?

android - 从 Android 转换 - 您可以转换整个应用程序还是仅转换应用程序内的媒体内容

android - 使用 CastCompanionLibrary 将转换按钮添加到 ActionBar

android - HTML5 navigator.online 在 WebView 中不起作用

java - 想要在日期选择器上选择上一个日期。 (安卓)

android - 将视频和图像从本地存储加载到 Google ChromeCast android

chromecast - 发送到自定义接收器应用程序的对象是否有大小限制?

android - MediaRouteActionProvider 连接对话框主题

audio - 从接收者网站播放音频