androidexoplayergoogle-cast

Android, Google-cast, "Error inflating class androidx.mediarouter.app.MediaRouteButton"


I have been trying to add google-cast to my Android app that plays videos using Exoplayer. The app has one single activity withTheme.Leanback theme and the same UI is used for both Phones and Android TV.

To add casting support on phones, I have modified in the player view and I added the cast button as below:

<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" />

When I run the application I get the following error:

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) 

I have tried setting the background of the castbusston transparent as was suggested in few places online but that did not help.

I can have several other Image Button and Text Buttons that are working fine.

I tried using <MediaRouteButton instead of <androidx.mediarouter.app.MediaRouteButton. This way the button will be showed and greyed out in the player layout however, when I try to intitize the cast context as below:

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

mCastContext = CastContext.getSharedInstance(mContext);

I get the following error:

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.

Solution

  • The issue was that the primaryColor of the app theme that I was using had transparency channel, ie, #3d000000. However MediaRouteButton that is taking the primaryColor of theme needs a color without transparency channel such as #000000. So I resolved the issue as follow:

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

    where I defined <color name="defaultColor">#000000</color>

    Later on I encountered another issue that MediaCastButton can only be used with AppCompat decedent theme. The solution for me was to change the app theme to an Theme.AppCompat.Light.NoActionBar theme and modify it to look like Theme.Leanback as below:

    <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>