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

Android WebView打开Facebook视频链接出现net::ERR_UNKNOWN_URL_SCHEME错误

Android WebView打开Facebook视频链接报错net::ERR_UNKNOWN_URL_SCHEME

问题详情

  • 目标链接:https://www.facebook.com/watch/?v=269637072007881
  • 错误表现:在App的WebView中打开该链接时,会自动重定向到fb://fullscreen_video/269637072007881?loop=false&wtsid=wt_0p0MNje32ZvW5oQjV,随后抛出错误:

Webpage not available
The webpage at fb://fullscreen_video/269637072007881?loop=false&wtsid=wt_0p0MNje32ZvW5oQjV could not be loaded because:
net::ERR_UNKNOWN_URL_SCHEME

  • 对比结果:在第三方浏览器中打开该链接可正常播放视频

现有WebView代码

WebSettings webSettings = page.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
page.setWebViewClient(new WebViewClient() {//it seems not setting webclient, launches
    //default browser instead of opening the page in webview
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        if(blockedWebsites.contains(Utils.getBaseDomain(request.getUrl().toString()))){                        
            Log.d("vdd", "URL : " + request.getUrl().toString());
            new AlertDialog.Builder(getContext())
                    .setMessage("Youtube is not supported according to google policy.")
                    .setNegativeButton("Ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    })
                    .create()
                    .show();
            return true;
        }
        return super.shouldOverrideUrlLoading(view, request);
    }

    @Override
    public void onPageStarted(final WebView webview, final String url, Bitmap favicon) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                EditText urlBox = getVDActivity().findViewById(R.id.et_search_bar);
                urlBox.setText(url);
                urlBox.setSelection(urlBox.getText().length());
                BrowserWindow.this.url = url;
            }
        });
        view.findViewById(R.id.loadingProgress).setVisibility(View.GONE);
        loadingPageProgress.setVisibility(View.VISIBLE);
        super.onPageStarted(webview, url, favicon);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        loadingPageProgress.setVisibility(View.GONE);
    }

    @Override
    public void onLoadResource(final WebView view, final String url) {
        Log.d("fb :", "URL: " + url);
        final String page = view.getUrl();
        final String title = view.getTitle();

        new VideoContentSearch(getActivity(), url, page, title) {
            @Override
            public void onStartInspectingURL() {
                Utils.disableSSLCertificateChecking();
            }

            @Override
            public void onFinishedInspectingURL(boolean finishedAll) {
                HttpsURLConnection.setDefaultSSLSocketFactory(defaultSSLSF);
            }

            @Override
            public void onVideoFound(String size, String type, String link, String name, String page, boolean chunked, String website, boolean audio) {
                videoList.addItem(size, type, link, name, page, chunked, website, audio);
                updateFoundVideosBar();
            }
        }.start();
    }

    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        if (getActivity() != null) {
            Log.d("VDDebug", "Url: " + url);
            if (getActivity().getSharedPreferences("settings", 0).getBoolean(getString(R
                    .string.adBlockON), true)
                    && (url.contains("ad") || url.contains("banner") || url.contains("pop"))
                    && getVDActivity().getBrowserManager().checkUrlIfAds(url)) {
                Log.d("VDDebug", "Ads detected: " + url);
                return new WebResourceResponse(null, null, null);
            }
        }
        return super.shouldInterceptRequest(view, url);
    }

    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && getVDActivity() !=
                null) {
            if (MyApplication.getInstance().getSharedPreferences("settings", 0).getBoolean(getString
                    (R.string.adBlockON), true)
                    && (request.getUrl().toString().contains("ad") ||
                    request.getUrl().toString().contains("banner") ||
                    request.getUrl().toString().contains("pop"))
                    && getVDActivity().getBrowserManager().checkUrlIfAds(request.getUrl()
                    .toString())) {
                Log.i("VDInfo", "Ads detected: " + request.getUrl().toString());
                return new WebResourceResponse(null, null, null);
            } else return null;
        } else {
            return shouldInterceptRequest(view, request.getUrl().toString());
        }
    }
});
page.setWebChromeClient(new WebChromeClient() {
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        loadingPageProgress.setProgress(newProgress);
    }

    @Override
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);
        videoList.deleteAllItems();
        updateFoundVideosBar();
//                    VisitedPage vp = new VisitedPage();
//                    vp.title = title;
//                    vp.link = view.getUrl();
//                    new HistorySQLite(getActivity()).addPageToHistory(vp);
    }
});

page.loadUrl(url);
loadedFirsTime = true;

解决方案

错误原因是WebView默认仅支持http/https协议,遇到fb://这类自定义协议时无法识别处理。需要在shouldOverrideUrlLoading方法中添加自定义协议的处理逻辑:

修改后的shouldOverrideUrlLoading方法

@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    String url = request.getUrl().toString();
    
    // 处理被屏蔽网站逻辑
    if(blockedWebsites.contains(Utils.getBaseDomain(url))){                        
        Log.d("vdd", "URL : " + url);
        new AlertDialog.Builder(getContext())
                .setMessage("Youtube is not supported according to google policy.")
                .setNegativeButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .create()
                .show();
        return true;
    }
    
    // 处理非http/https协议的URL
    if (!url.startsWith("http://") && !url.startsWith("https://")) {
        // 尝试调用系统应用打开自定义协议链接
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(intent);
            return true;
        } catch (ActivityNotFoundException e) {
            // 如果没有对应应用,转换为网页版链接(以fb://为例)
            if (url.startsWith("fb://")) {
                String webUrl = url.replace("fb://", "https://www.facebook.com/");
                view.loadUrl(webUrl);
                return true;
            }
            // 其他协议可根据需求扩展处理
            e.printStackTrace();
        }
    }
    
    return super.shouldOverrideUrlLoading(view, request);
}

逻辑说明

  1. 保留原有被屏蔽网站的处理逻辑;
  2. 判断当前URL是否为http/https协议,若不是则进入自定义处理分支;
  3. 优先尝试调用系统应用打开自定义协议链接(比如用户手机上安装了Facebook应用,会直接跳转到应用内播放视频);
  4. 如果没有对应应用,将fb://协议转换为https://www.facebook.com/开头的网页链接,让WebView加载网页版内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:55:01