Android WebView调用Javascript实现Facebook视频下载点击无响应求助
问题排查与修复方案
核心问题点及修改方式
- JS注入方法不兼容高版本Android
Android 7.0 (API 24) 以上执行JavaScript代码建议使用evaluateJavascript,原有loadUrl的方式在部分高版本系统上执行会失效,同时你在onLoadResource中重复执行注入逻辑,会反复覆盖节点绑定的事件,直接导致点击无响应,可修改注入逻辑如下:
@Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); String js = "javascript:(function() { " + "var el = document.querySelectorAll('div[data-sigil]');" + "for(var i=0;i<el.length; i++){" + "var sigil = el[i].dataset.sigil;" + "if(sigil.indexOf('inlineVideo') > -1 && !el[i].dataset.downloadBound){" + "el[i].dataset.downloadBound = 'true';" + "delete el[i].dataset.sigil;" + "try { var jsonData = JSON.parse(el[i].dataset.store); } catch(e) { return; }" + "el[i].addEventListener('click', function(e) {" + "e.stopPropagation();" + "e.preventDefault();" + "FBDownloader.processVideo(jsonData.src, jsonData.videoID);" + "});" + "}" + "}" + "})()"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { view.evaluateJavascript(js, null); } else { view.loadUrl(js); } } // 移除onLoadResource中的注入逻辑,避免重复执行
- DOM结构适配问题
你参考的是早年的解决方案,当前Facebook的页面DOM结构已经多次更新,大量视频节点不再使用inlineVideo作为data-sigil的标识,视频地址也可能存储在playable_url、hd_src等字段中,你可以通过Chrome的WebView调试工具查看当前页面的视频节点结构,调整选择器逻辑。 - 下载请求缺少Cookie
Facebook的视频地址需要携带登录态Cookie才能访问,你直接调用DownloadManager发起请求不会携带WebView中的Cookie,会返回403错误,需要手动把Cookie加到下载请求中:
// 在processVideo方法中添加以下代码 String cookie = CookieManager.getInstance().getCookie(vidData); req.addRequestHeader("Cookie", cookie); req.addRequestHeader("User-Agent", webView.getSettings().getUserAgentString());
- 存储权限与分区存储适配
Android 6.0以上需要动态申请WRITE_EXTERNAL_STORAGE权限,Android 10 (API 29) 以上禁止直接写入外部存储公共目录,你可以修改存储路径为应用私有目录,或者适配MediaStore存储逻辑:
// 适配分区存储的存储路径示例 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { mBaseFolderPath = getExternalFilesDir(Environment.DIRECTORY_MOVIES) + File.separator + "FacebookVideos" + File.separator; } else { mBaseFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + File.separator + "FacebookVideos" + File.separator; }
- 动态内容绑定问题
Facebook是滚动加载的动态页面,后续滚动加载的视频节点不会被注入的JS处理,你可以添加滚动监听,或者定时执行JS绑定逻辑,覆盖新增的视频节点。
内容的提问来源于stack exchange,提问作者Pratham Jindal
相关产品推荐
相关产品推荐

