Android启动YouTube TV播放视频报This isn't a hierarchical URI
错误根因
- 你传入的
vnd.youtube:GGjVd7mLM3k属于非层级(不透明)URI,这类URI没有//标识的authority段,不支持路径解析、查询参数提取等操作。 - YouTube TV版的主Activity在处理VIEW类型Intent时,会调用仅支持层级URI的解析方法,遇到非层级URI就会直接抛出你看到的
UnsupportedOperationException: This isn't a hierarchical URI异常。 - 额外问题:
vnd.youtube:是手机端YouTube的专属自定义scheme,本身就不在YouTube TV的Intent Filter匹配规则里。
修复方法
最小修改方案
直接将URI替换为YouTube TV支持的层级结构格式即可,修正后代码:
Intent appIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube.tv://watch?v=GGjVd7mLM3k")); appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 无特殊需求请移除FLAG_ACTIVITY_CLEAR_TASK、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,前者会清空YouTube TV的返回栈导致用户按返回键直接回桌面,后者会导致播放页不在最近任务列表显示,体验很差 startActivity(appIntent);
全场景兼容写法
如果需要同时适配手机端YouTube、YouTube TV、无客户端时跳转网页播放,可以用鲁棒性更强的写法,避免崩溃:
String videoId = "GGjVd7mLM3k"; Intent playIntent = null; // 优先尝试拉起YouTube TV Intent tvIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube.tv://watch?v=" + videoId)); tvIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (tvIntent.resolveActivity(getPackageManager()) != null) { playIntent = tvIntent; } else { // 次优先拉起手机端YouTube Intent mobileIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:" + videoId)); mobileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (mobileIntent.resolveActivity(getPackageManager()) != null) { playIntent = mobileIntent; } else { // 无客户端时拉起网页版 playIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/watch?v=" + videoId)); playIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } } startActivity(playIntent);
补充说明
- 跳转前调用
resolveActivity做校验是必要操作,可以避免设备未安装对应客户端时抛出ActivityNotFoundException导致应用崩溃。 - 不要硬编码YouTube相关的包名做定向跳转,不同地区、不同版本的YouTube包名可能存在差异,通过URI和系统PackageManager匹配是官方推荐的做法。
内容的提问来源于stack exchange,提问作者YeJong Choe
相关产品推荐
相关产品推荐

