一个应用程序是不是可以有多个 CastOptionsProvider,作为投射到 2 个不同的接收器应用程序的一种方式?

Posted

技术标签:

【中文标题】一个应用程序是不是可以有多个 CastOptionsProvider,作为投射到 2 个不同的接收器应用程序的一种方式?【英文标题】:Is it possible for an app to have more than one CastOptionsProvider, as a means to cast to 2 different Receiver Apps?一个应用程序是否可以有多个 CastOptionsProvider,作为投射到 2 个不同的接收器应用程序的一种方式? 【发布时间】:2020-05-19 10:49:36 【问题描述】:

基本上,我正在将应用程序转换为库模块。问题是这个应用程序有 Chromecast 功能,因此在清单中有自己的CastOptionsProvider,而要使用这个库的应用程序有自己的CastOptionsProvider,导致清单合并失败。

我知道这应该是一个明显的合并问题,但这更多的是关于应用程序的 Chromecast 部分。一个应用是否可以将 2 个CastOptionsProviders 投射到 2 个不同的 Receiver 应用中?

【问题讨论】:

【参考方案1】:

TL;DR 你可以在你的库中声明一个OptionsProvider 类,如果需要,你的应用程序可以声明它自己的OptionsProvider 类来代替使用。 要在您的应用程序运行时在不同的接收器应用程序之间切换,您应该使用CastContext.setReceiverApplicationId 方法覆盖OptionsProvider 中的设置。

背景

根据Chromecast codelab,CastOptionsProvider 是你自己写的一个类。只要它实现com.google.android.gms.cast.framework.OptionsProvider,您实际上可以调用它任何您想要的名称。这也意味着您可以在同一个应用程序中编写多个CastOptionsProvider 类,只要将它们放在不同的包中或给它们起不同的名称即可。您可以像这样声明您的每个OptionsProviders:

package your.pkg.goes.here;

import com.google.android.gms.cast.framework.OptionsProvider;
...

public class YourOptionsProvider implements OptionsProvider 

    @Override
    public CastOptions getCastOptions(Context context) ...

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(Context context) ...

到目前为止,一切都很好。因为您可以随心所欲地调用OptionsProvider,所以您还需要在清单中声明您的OPTIONS_PROVIDER_CLASS_NAME,以便应用知道如何获取其演员选项。该代码属于您的AndroidManifest.xml 文件,它看起来像这样:

<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="your.pkg.goes.here.YourOptionsProvider" />

这就是棘手的地方。 meta-data 用于声明键值对,you can't have more than one value for the same key。您可以在代码中浮动多个OptionsProvider 类,这很好,但一次只能使用其中一个类。要更改使用哪一个,您需要编辑 you can't do while the app is running 的清单。您可以做的最接近的事情是拥有使用不同OptionsProviders 的不同版本的应用程序。

那么我应该使用哪个 OptionProvider?

OptionsProvider 的行为仅由其实现函数的方式定义,getCastOptionsgetAdditionalSessionProviders。从库中找出您需要的行为,并将该行为编写为可以由您的应用程序扩展的库函数或类。例如:

package your.library;

import com.google.android.gms.cast.framework.CastOptions;
import com.google.android.gms.cast.framework.OptionsProvider;
...

public class LibraryOptionsProvider implements OptionsProvider 

    public String YOUR_LIBRARY_APPLICATION_ID = "ASDFASDF";

    @Override
    public CastOptions getCastOptions(Context context) 
        return new CastOptions.Builder()
                .setReceiverApplicationId(YOUR_LIBRARY_APPLICATION_ID)
                // maybe set some other settings, too
                .build();
    

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(Context context) ...

对于不需要特殊行为的应用,您可以将LibraryOptionsProvider 放在应用的清单中:

<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="your.library.LibraryOptionsProvider" />

但是对于需要特殊功能的应用程序,您可以声明自己的 ApplicationOptionsProvider,它使用 LibraryOptionsProvider 来处理其某些行为。

package your.application;

import your.library.LibraryOptionsProvider;
...

public class ApplicationOptionsProvider extends LibraryOptionsProvider 

    @Override
    public CastOptions getCastOptions(Context context) 
        return new CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id)) // use a different application ID from the one in LibraryOptionsProvider
                .build();
    

    // inherit getAdditionalSessionProviders from LibraryOptionsProvider, no need to override it unless we want different behavior

那么你的清单应该指向ApplicationOptionsProvider而不是LibraryOptionsProvider

<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="your.application.ApplicationOptionsProvider" />

到目前为止的总结: 由应用程序决定它需要从其OptionsProvider 中获得什么行为。如果不需要特殊行为,应用程序应使用您在库中声明的OptionsProvider。当需要自定义行为时,例如当您需要不同的转换选项或不同的转换应用程序 ID 时,应用程序应该声明自己的 OptionsProvider,这可以依赖于库代码而不是重新实现共享行为。

多个应用程序 ID

OptionsProvider 用于初始化 CastOptions,它是“一个包含 Cast SDK 全局上下文的单例类”(source)。 CastContext 在应用程序启动时在后台初始化,但您可以随时更改应用程序 ID,使用 CastContext.setReceiverApplicationId(String applicationId)。通过这样做,您将忽略在CastOptions 中配置的接收器应用程序 ID。 这是您可以在单个构建中在多个接收器应用之间切换的方式。

【讨论】:

以上是关于一个应用程序是不是可以有多个 CastOptionsProvider,作为投射到 2 个不同的接收器应用程序的一种方式?的主要内容,如果未能解决你的问题,请参考以下文章

一个应用程序是不是可以有多个 CastOptionsProvider,作为投射到 2 个不同的接收器应用程序的一种方式?

Android App Bundles - 是不是可以在一个版本中上传多个应用程序包?

同一进程中是不是可以有多个 ORB 对象?

如果设备上安装的iOS通用链接上有多个支持的应用程序,是不是可以选择每次打开的应用程序?

对于使用机器人框架的数据驱动测试,是不是可以有多个数据驱动程序(使用多个数据表)?

将 TEXT 字段拆分为多个表是不是可以在多语言应用程序中提供性能优化?