Android, Google-cast, "Ошибка при завышении класса androidx.mediarouter.app.MediaRouteButton"

Я пытался добавить google-cast в свое приложение для Android, которое воспроизводит видео с помощью Exoplayer. Приложение имеет одно действие с темойTheme.Leanback, и один и тот же пользовательский интерфейс используется как для телефонов, так и для Android TV.

Чтобы добавить поддержку трансляции на телефонах, я изменил вид проигрывателя и добавил кнопку трансляции, как показано ниже:

<androidx.mediarouter.app.MediaRouteButton
   android:id = "@+id/media_route_button"
   android:layout_width = "wrap_content"
   android:layout_height = "wrap_content"
   android:layout_gravity = "left"
   android:scaleY = "0.8"
   android:scaleX = "0.8"
   android:background = "@android:color/transparent"
   android:mediaRouteTypes = "user"
   android:visibility = "visible" />

Когда я запускаю приложение, я получаю следующую ошибку:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.EXAMPLE.PACKAGE, PID: 10661
    android.view.InflateException: Binary XML file line #76 in com.EXAMPLE.PACKAGE:layout/activity_player: Binary XML file line #76 in com.EXAMPLE.PACKAGE:layout/activity_player: Error inflating class androidx.mediarouter.app.MediaRouteButton
    Caused by: android.view.InflateException: Binary XML file line #76 in com.EXAMPLE.PACKAGE:layout/activity_player: Error inflating class androidx.mediarouter.app.MediaRouteButton
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at android.view.LayoutInflater.createView(LayoutInflater.java:852)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1004)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1124)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1124)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1124)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
        at com.EXAMPLE.PACKAGE.fragment.PlayerFragment.onCreateView(PlayerFragment.java:162)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
        at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.IllegalArgumentException: background can not be translucent: #0
        at androidx.core.graphics.ColorUtils.calculateContrast(ColorUtils.java:161)
        at androidx.mediarouter.app.MediaRouterThemeHelper.getControllerColor(MediaRouterThemeHelper.java:177)
        at androidx.mediarouter.app.MediaRouterThemeHelper.getRouterThemeId(MediaRouterThemeHelper.java:313)
        at androidx.mediarouter.app.MediaRouterThemeHelper.createThemedButtonContext(MediaRouterThemeHelper.java:107)
        at androidx.mediarouter.app.MediaRouteButton.<init>(MediaRouteButton.java:153)
        at androidx.mediarouter.app.MediaRouteButton.<init>(MediaRouteButton.java:149)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
        at android.view.LayoutInflater.createView(LayoutInflater.java:852) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1004) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1124) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1124) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1124) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:680) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:532) 
        at com.EXAMPLE.PACKAGE.fragment.PlayerFragment.onCreateView(PlayerFragment.java:162) 
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963) 
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518) 
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282) 
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189) 
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100) 
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002) 
        at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

Я попытался сделать фон кастбустона прозрачным, как предлагалось в нескольких местах в Интернете, но это не помогло.

У меня может быть несколько других кнопок изображения и текста, которые работают нормально.

Я пробовал использовать <MediaRouteButton вместо <androidx.mediarouter.app.MediaRouteButton. Таким образом, кнопка будет отображаться и выделена серым цветом в макете проигрывателя, однако, когда я пытаюсь настроить контекст приведения, как показано ниже:

mMediaRouteButton = (MediaRouteButton) mView.findViewById(R.id.media_route_button);
CastButtonFactory.setUpMediaRouteButton(mContext, mMediaRouteButton);

mCastContext = CastContext.getSharedInstance(mContext);

Я получаю следующую ошибку:

java.lang.ClassCastException: android.app.MediaRouteButton cannot be cast to androidx.mediarouter.app.MediaRouteButton

I have been puzzled by this issue for couple of days.  Thank you very much in advance for your kind comments and suggestion.
1
0
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Убедитесь, что вы включили зависимость, содержащую этот класс, в список зависимостей вашего модуля, например:

implementation "androidx.mediarouter:mediarouter:1.2.6"

(или другая версия по необходимости)

Большое спасибо за ваш добрый ответ. Я уже включил эту зависимость.

krahimi 22.03.2022 01:08

Знаете ли вы, можно ли добавить MediaRouteButton при использовании Theme.Leanback?

krahimi 22.03.2022 14:23

@krahimi: Казалось бы, странная комбинация. Theme.Leanback обычно используется на телевизоре; MediaRouteButton будет использоваться на телевизоре без телевизора. Тем не менее, я бы не ожидал краха. Есть ли что-то еще в вашей трассировке стека, например, больше разделов «Вызвано» после той части, которую вы опубликовали?

CommonsWare 22.03.2022 14:41

Это правда, в настоящее время приложение использует одну тему как для телевизора, так и для телефонов. Нет, это вся трассировка стека, которую я вижу.

krahimi 22.03.2022 14:55

Я также попробовал контекстную оболочку при раздувании View: Context app_compat__context = new ContextThemeWrapper(mContext, R.style.Theme_AppCompat); inflater.cloneInContext(app_compat__context);, но я все еще вижу ту же ошибку.

krahimi 22.03.2022 14:57

Поскольку MediaRouteButton, который вы используете, находится в библиотеке, вы должны иметь возможность поставить точку останова в его конструкторе. Посмотрите, попали ли вы в него, и посмотрите, как далеко вы сможете пройти через него. InvocationTargetException иногда означает, что класс или метод не public, но здесь это не так. Это также иногда означает, что вы где-то потерпели крах в вызываемом методе — в идеале это должно отображаться как еще один раздел «Причинено», но если вы этого не понимаете, возможно, отладка покажет, где что-то идет не так.

CommonsWare 22.03.2022 15:03

@ CommonsWare: Большое спасибо. Я только что понял, что часть трассировки стека была свернута, чего я раньше не замечал. Извини за это. Я только что обновил трассировку стека. Я также попытаюсь пройти через код.

krahimi 22.03.2022 15:18

Похоже, проблема вызвана здесь: Caused by: java.lang.IllegalArgumentException: background can not be translucent: #0

krahimi 22.03.2022 15:22

Казалось бы, это соответствует android:background = "@android:color/transparent". Если вы удалите это, вы получите другой сбой?

CommonsWare 22.03.2022 15:41

Оказывается, у основного цвета темы не должно быть прозрачного канала. После внесения этого изменения он работает нормально. Большое спасибо за подсказки

krahimi 22.03.2022 15:56

Большой! Возможно, вы захотите опубликовать свой собственный ответ на свой вопрос с подробностями того, что вы изменили!

CommonsWare 22.03.2022 15:59

Обязательно сделаю. Спасибо еще раз

krahimi 22.03.2022 16:03
Ответ принят как подходящий

Проблема заключалась в том, что primaryColor темы приложения, которую я использовал, имел канал прозрачности, то есть #3d000000. Однако MediaRouteButton, который использует primaryColor темы, нуждается в цвете без канала прозрачности, таком как #000000. Итак, я решил проблему следующим образом:

<style name = "AppTheme" parent = "@style/Theme.Leanback">
   <!--   Primary Color -->
   <item name = "colorPrimary">@color/defaultColor</item>
</style>

где я определил <color name = "defaultColor">#000000</color>

Позже я столкнулся с другой проблемой, что MediaCastButton можно использовать только с AppCompat наследственной темой. Решение для меня состояло в том, чтобы изменить тему приложения на тему Theme.AppCompat.Light.NoActionBar и изменить ее, чтобы она выглядела как Theme.Leanback, как показано ниже:

<style name = "AppTheme1" parent = "@style/Theme.AppCompat.Light.NoActionBar">
        <item name = "colorPrimary">@color/blackColor</item>
        <item name = "android:windowBackground">@color/blackColor</item>

<!--        <item name = "mediaRouteButtonTint">@color/whiteColor</item>-->

        <item name = "baseCardViewStyle">@style/Widget.Leanback.BaseCardViewStyle</item>
        <item name = "imageCardViewStyle">@style/Widget.Leanback.ImageCardViewStyle</item>
        <item name = "imageCardViewImageStyle">@style/Widget.Leanback.ImageCardView.ImageStyle</item>
        <item name = "imageCardViewTitleStyle">@style/Widget.Leanback.ImageCardView.TitleStyle</item>
        <item name = "imageCardViewContentStyle">@style/Widget.Leanback.ImageCardView.ContentStyle</item>
        <item name = "imageCardViewBadgeStyle">@style/Widget.Leanback.ImageCardView.BadgeStyle</item>
        <item name = "imageCardViewInfoAreaStyle">@style/Widget.Leanback.ImageCardView.InfoAreaStyle</item>

        <item name = "browsePaddingStart">@dimen/lb_browse_padding_start</item>
        <item name = "browsePaddingEnd">@dimen/lb_browse_padding_end</item>
        <item name = "browsePaddingTop">@dimen/lb_browse_padding_top</item>
        <item name = "browsePaddingBottom">@dimen/lb_browse_padding_bottom</item>
        <item name = "browseRowsMarginStart">@dimen/lb_browse_rows_margin_start</item>
        <item name = "browseRowsMarginTop">@dimen/lb_browse_rows_margin_top</item>
        <item name = "browseRowsFadingEdgeLength">@dimen/lb_browse_rows_fading_edge</item>

<!--            <item name = "headersVerticalGridStyle">@style/Widget.Leanback.Headers.VerticalGridView</item>-->
<!--            <item name = "headerStyle">@style/Widget.Leanback.Header</item>-->
<!--            <item name = "sectionHeaderStyle">@style/Widget.Leanback.Header.Section</item>-->

        <item name = "rowsVerticalGridStyle">@style/Widget.Leanback.Rows.VerticalGridView</item>
        <item name = "rowHorizontalGridStyle">@style/Widget.Leanback.Row.HorizontalGridView</item>
        <item name = "itemsVerticalGridStyle">@style/Widget.Leanback.GridItems.VerticalGridView</item>

        <item name = "browseTitleViewLayout">@layout/lb_browse_title</item>
        <item name = "browseTitleTextStyle">@style/Widget.Leanback.Title.Text</item>
        <item name = "browseTitleIconStyle">@style/Widget.Leanback.Title.Icon</item>
        <item name = "browseTitleViewStyle">@style/Widget.Leanback.TitleView</item>

        <item name = "rowHeaderStyle">@style/Widget.Leanback.Row.Header</item>
        <item name = "rowHeaderDescriptionStyle">@style/Widget.Leanback.Row.Header.Description</item>
        <item name = "rowHoverCardTitleStyle">@style/Widget.Leanback.Row.HoverCardTitle</item>
        <item name = "rowHoverCardDescriptionStyle">@style/Widget.Leanback.Row.HoverCardDescription</item>
        <item name = "rowHeaderDockStyle">@style/Widget.Leanback.Row.HeaderDock</item>

<!--            <item name = "searchOrbViewStyle">@style/Widget.Leanback.SearchOrbViewStyle</item>-->


        <item name = "detailsDescriptionTitleStyle">@style/Widget.Leanback.DetailsDescriptionTitleStyle</item>
        <item name = "detailsDescriptionSubtitleStyle">@style/Widget.Leanback.DetailsDescriptionSubtitleStyle</item>
        <item name = "detailsDescriptionBodyStyle">@style/Widget.Leanback.DetailsDescriptionBodyStyle</item>
        <item name = "detailsActionButtonStyle">@style/Widget.Leanback.DetailsActionButtonStyle</item>
        <!-- Attributes used for styling of a playback -->
        <item name = "playbackPaddingStart">@dimen/lb_playback_controls_margin_start</item>
        <item name = "playbackPaddingEnd">@dimen/lb_playback_controls_margin_end</item>
        <item name = "playbackMediaItemPaddingStart">@dimen/lb_playback_media_row_horizontal_padding</item>

        <item name = "playbackMediaListHeaderStyle">@style/Widget.Leanback.PlaybackMediaListHeaderStyle</item>
        <item name = "playbackMediaItemRowStyle">@style/Widget.Leanback.PlaybackMediaItemRowStyle</item>
        <item name = "playbackMediaItemSeparatorStyle">@style/Widget.Leanback.PlaybackMediaItemSeparatorStyle</item>
        <item name = "playbackMediaListHeaderTitleStyle">@style/Widget.Leanback.PlaybackMediaListHeaderTitleStyle</item>
        <item name = "playbackMediaItemDetailsStyle">@style/Widget.Leanback.PlaybackMediaItemDetailsStyle</item>
        <item name = "playbackMediaItemNumberViewFlipperStyle">@style/Widget.Leanback.PlaybackMediaItemNumberViewFlipperStyle</item>
        <item name = "playbackMediaItemNumberViewFlipperLayout">@layout/lb_media_item_number_view_flipper</item>
        <item name = "playbackMediaItemNumberStyle">@style/Widget.Leanback.PlaybackMediaItemNumberStyle</item>
        <item name = "playbackMediaItemNameStyle">@style/Widget.Leanback.PlaybackMediaItemNameStyle</item>
        <item name = "playbackMediaItemDurationStyle">@style/Widget.Leanback.PlaybackMediaItemDurationStyle</item>

        <item name = "playbackControlsButtonStyle">@style/Widget.Leanback.PlaybackControlsButtonStyle</item>
        <item name = "playbackControlButtonLabelStyle">@style/Widget.Leanback.PlaybackControlLabelStyle</item>
        <item name = "playbackControlsTimeStyle">@style/Widget.Leanback.PlaybackControlsTimeStyle</item>
        <item name = "playbackControlsActionIcons">@style/Widget.Leanback.PlaybackControlsActionIconsStyle</item>
        <item name = "playbackControlsAutoHideTimeout">@integer/lb_playback_controls_show_time_ms</item>
        <item name = "playbackControlsAutoHideTickleTimeout">@integer/lb_playback_controls_tickle_timeout_ms</item>

        <item name = "errorMessageStyle">@style/Widget.Leanback.ErrorMessageStyle</item>

        <item name = "defaultSearchColor">@color/lb_default_search_color</item>
        <item name = "defaultSearchIconColor">@color/lb_default_search_icon_color</item>
        <item name = "defaultSearchBrightColor">?attr/defaultSearchColor</item>
        <item name = "defaultSearchIcon">@drawable/lb_ic_in_app_search</item>

        <item name = "defaultSectionHeaderColor">?attr/defaultSearchColor</item>

        <item name = "overlayDimMaskColor">@color/lb_view_dim_mask_color</item>
        <item name = "overlayDimActiveLevel">@fraction/lb_view_active_level</item>
        <item name = "overlayDimDimmedLevel">@fraction/lb_view_dimmed_level</item>

    </style>

Другие вопросы по теме