Android Studio中从URL获取YouTube视频标题及相关报错解决
获取YouTube视频标题的问题及解决需求
我想要通过URL获取YouTube视频标题,最初找到如下代码,但其中IOUtils已过时,需要替代实现:
public class SimpleYouTubeHelper { public static String getTitleQuietly(String youtubeUrl) { try { if (youtubeUrl != null) { URL embededURL = new URL("http://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json" ); return new JSONObject(IOUtils.toString(embededURL)).getString("title"); } } catch (Exception e) { e.printStackTrace(); } return null; } }
随后我尝试了基于Thread的实现代码:
class getYoutubeJSON extends Thread { String data = " "; @Override public void run() { try { URL url = new URL("http://www.youtube.com/oembed?url="+" https://www.youtube.com/watch?v=a4NT5iBFuZs&ab_channel=FilipVujovic" + "&format=json"); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); InputStream inputStream = httpURLConnection.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = bufferedReader.readLine()) != null){ data =data + line; } if(!data.isEmpty()){ JSONObject jsonObject = new JSONObject(data); // JSONArray users = jsonObject.getJSONArray("author_name"); Log.d("RT " , jsonObject.toString()); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } }
但这段代码报错:Cleartext HTTP traffic to www.youtube.com not permitted,我尝试了相关解决方案仍有无法理解的报错,寻求解决办法。
解决方案
1. 替换过时IOUtils+解决明文HTTP问题(核心方案)
YouTube支持HTTPS协议,直接将请求地址的http改为https是解决明文流量报错的根本办法,同时用现代方式替代IOUtils的功能。
方案一:使用OkHttp实现(推荐,代码更简洁可靠)
先添加依赖(Android项目在build.gradle中配置):
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
实现代码:
import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import org.json.JSONObject; import java.io.IOException; public class YouTubeTitleHelper { private static final OkHttpClient client = new OkHttpClient(); // 同步方法,禁止在Android主线程调用 public static String getYouTubeTitle(String youtubeUrl) { if (youtubeUrl == null || youtubeUrl.isEmpty()) return null; String oEmbedUrl = "https://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json"; Request request = new Request.Builder().url(oEmbedUrl).build(); try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) throw new IOException("请求失败:" + response.code()); String jsonData = response.body().string(); return new JSONObject(jsonData).getString("title"); } catch (Exception e) { e.printStackTrace(); return null; } } // 异步回调方法,适合Android主线程调用 public interface TitleCallback { void onTitleReceived(String title); void onError(Exception e); } public static void getYouTubeTitleAsync(String youtubeUrl, TitleCallback callback) { if (youtubeUrl == null || youtubeUrl.isEmpty()) { callback.onError(new IllegalArgumentException("无效的YouTube链接")); return; } String oEmbedUrl = "https://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json"; Request request = new Request.Builder().url(oEmbedUrl).build(); client.newCall(request).enqueue(new okhttp3.Callback() { @Override public void onFailure(okhttp3.Call call, IOException e) { callback.onError(e); } @Override public void onResponse(okhttp3.Call call, Response response) throws IOException { if (!response.isSuccessful()) { callback.onError(new IOException("请求失败:" + response.code())); return; } try { String jsonData = response.body().string(); String title = new JSONObject(jsonData).getString("title"); callback.onTitleReceived(title); } catch (Exception e) { callback.onError(e); } } }); } }
方案二:原生Java标准库实现(无第三方依赖)
修改初始代码,用BufferedReader替代IOUtils,同时改用HTTPS:
import org.json.JSONObject; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; public class SimpleYouTubeHelper { public static String getTitleQuietly(String youtubeUrl) { if (youtubeUrl == null || youtubeUrl.isEmpty()) return null; try { URL embededURL = new URL("https://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json"); URLConnection connection = embededURL.openConnection(); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } reader.close(); return new JSONObject(sb.toString()).getString("title"); } catch (Exception e) { e.printStackTrace(); } return null; } }
2. 特殊场景下的明文HTTP兼容(不推荐)
如果因特殊需求必须使用HTTP,需在Android项目中配置:
- 在
AndroidManifest.xml的<application>标签添加:android:usesCleartextTraffic="true" - 或者创建
res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">youtube.com</domain> </domain-config> </network-security-config>
再在<application>标签添加:android:networkSecurityConfig="@xml/network_security_config"
3. 关键注意事项
- Android平台上,网络请求绝对不能在主线程执行,否则会抛出
NetworkOnMainThreadException,需用异步回调、线程池或协程处理。 - 确保设备能正常访问YouTube服务,部分地区需配置网络代理。
内容的提问来源于stack exchange,提问作者user2975634
相关产品推荐
相关产品推荐

