You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pierfrancescosoffritti YouTubePlayerView的Android TV应用遭Play Store驳回求解决

YouTubePlayerView在Android TV上的DPad控制与Google Play驳回修复方案

一、DPad控制失效的修复方案

YouTubePlayerView内部会拦截KeyEvent,导致外部设置的setOnKeyListener无法生效。正确的做法是自定义继承类,重写dispatchKeyEvent来接管DPad按键逻辑:

public class TVYouTubePlayerView extends YouTubePlayerView {
    private YouTubePlayer mPlayer;

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

    public TVYouTubePlayerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setPlayerInstance(YouTubePlayer player) {
        this.mPlayer = player;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN && mPlayer != null) {
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_DPAD_CENTER:
                case KeyEvent.KEYCODE_ENTER:
                    // 触发播放/暂停
                    if (mPlayer.isPlaying()) {
                        mPlayer.pause();
                    } else {
                        mPlayer.play();
                    }
                    return true;
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    // 快退10秒
                    long currentTime = mPlayer.getCurrentTimeMillis();
                    if (currentTime >= 10000) {
                        mPlayer.seekTo(currentTime - 10000);
                    }
                    return true;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    // 快进10秒
                    long duration = mPlayer.getDurationMillis();
                    currentTime = mPlayer.getCurrentTimeMillis();
                    if (currentTime <= duration - 10000) {
                        mPlayer.seekTo(currentTime + 10000);
                    }
                    return true;
                case KeyEvent.KEYCODE_DPAD_UP:
                    // 音量增加
                    AudioManager audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
                    audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
                    return true;
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    // 音量降低
                    AudioManager audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
                    audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
                    return true;
            }
        }
        return super.dispatchKeyEvent(event);
    }
}

使用时,在布局文件中替换原YouTubePlayerView为这个自定义类,并在播放器初始化成功后传入实例:

TVYouTubePlayerView playerView = findViewById(R.id.youtube_player);
playerView.initialize(YT_API_KEY, new YouTubePlayerInitListener() {
    @Override
    public void onInitSuccess(@NonNull YouTubePlayer youTubePlayer) {
        playerView.setPlayerInstance(youTubePlayer);
        youTubePlayer.loadVideo(VIDEO_ID);
    }

    @Override
    public void onInitFailure(@NonNull YouTubePlayer.Error error) {
        // 处理初始化失败
    }
});

二、Google Play媒体播放合规性修复

针对Play Store的驳回要求,需确保以下几点:

  • 生命周期绑定:在Activity/Fragment的生命周期方法中同步播放器状态:
    @Override
    protected void onStart() {
        super.onStart();
        playerView.onStart();
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        playerView.onResume();
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        playerView.onPause();
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        playerView.onStop();
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        playerView.onDestroy();
    }
    
  • 错误处理:给播放器添加监听器,处理播放错误并给出用户提示:
    youTubePlayer.addListener(new YouTubePlayerListener() {
        @Override
        public void onError(@NonNull YouTubePlayer.Error error) {
            Toast.makeText(getApplicationContext(), "播放错误: " + error.name(), Toast.LENGTH_SHORT).show();
        }
    
        // 实现其他必要的回调方法
        @Override public void onReady() {}
        @Override public void onStateChange(@NonNull PlayerState state) {}
        @Override public void onPlaybackQualityChange(@NonNull PlaybackQuality playbackQuality) {}
        @Override public void onPlaybackRateChange(@NonNull PlaybackRate playbackRate) {}
        @Override public void onApiChange() {}
    });
    
  • TV特性声明:在AndroidManifest.xml中添加TV相关配置:
    <uses-feature
        android:name="android.software.leanback"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />
    
    <activity
        android:name=".YourTVPlayerActivity"
        android:theme="@style/Theme.Leanback">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
        </intent-filter>
    </activity>
    
  • 控制提示:首次进入播放页面时,显示DPad按键操作提示(比如用Toast或弹窗),告知用户可通过中心键播放/暂停、左右键快进快退等。

三、验证步骤

  1. 使用Android TV模拟器或真实设备测试所有DPad按键,确保操作响应正常。
  2. 模拟网络异常、视频不可用等场景,验证错误提示是否正常显示。
  3. 检查后台播放行为:切换到后台时播放器是否暂停,回到前台能否恢复播放。

内容的提问来源于stack exchange,提问作者Harsh kansoda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:15:32