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

Android Lollipop API22 WebView无法创建RTCPeerConnection求助

Fixing "cannot create rtcpeerconnection: undefined is not a function" on Android Lollipop (API22) WebView

Let's jump straight to the root of your issue: Android 5.1 (API22)'s system WebView doesn’t natively support the RTCPeerConnection JavaScript API—that’s exactly why your JS code throws the "undefined is not a function" error when trying to set up the peer connection. The org.webrtc:google-webrtc dependency you added is for native Android WebRTC development, not for enabling WebRTC capabilities in the system WebView.

Here are two solid solutions to get this working:


Crosswalk is a Chromium-based WebView replacement that brings modern web APIs (including full WebRTC support) to older Android versions like API22. This is the most straightforward and reliable fix.

Step 1: Add Crosswalk Dependency to Gradle

Update your app-level build.gradle file to include the Crosswalk library (pick a version compatible with API22):

dependencies {
    // Remove the unused org.webrtc dependency unless you need it for native code
    // implementation 'org.webrtc:google-webrtc:1.0.+'
    implementation 'org.xwalk:xwalk_core_library:23.53.589.4'
}

Step 2: Update Your Layout XML

Swap out the standard WebView in fragment_camera_view.xml with Crosswalk's XWalkView:

<org.xwalk.core.XWalkView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Step 3: Adjust Your Fragment Code

Update CameraViewFrag to use XWalkView and handle its lifecycle properly (Crosswalk manages most WebRTC config automatically):

public class CameraViewFrag extends Fragment {
    private static final String TAG = "CameraViewFrag";
    private XWalkView mWebView;
    private String url = "https://appr.tc/r/658450307";
    private Button goOnButton;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_camera_view,container,false);
        goOnButton = (Button) view.findViewById(R.id.gotoButton);
        mWebView = (XWalkView) view.findViewById(R.id.webview);
        
        // Enable core settings for WebRTC
        XWalkSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setMediaPlaybackRequiresUserGesture(false);

        goOnButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Handle camera/audio permissions
                mWebView.setWebChromeClient(new XWalkWebChromeClient(mWebView) {
                    @Override
                    public void onPermissionRequest(final PermissionRequest request) {
                        getActivity().runOnUiThread(() -> request.grant(request.getResources()));
                    }
                });
                mWebView.loadUrl(url);
            }
        });
        return view;
    }

    // Crosswalk requires lifecycle handling
    @Override
    public void onPause() {
        super.onPause();
        if (mWebView != null) {
            mWebView.pauseTimers();
            mWebView.onHide();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mWebView != null) {
            mWebView.resumeTimers();
            mWebView.onShow();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mWebView != null) {
            mWebView.onDestroy();
        }
    }
}

Solution 2: Inject WebRTC Polyfill (Alternative)

If you want to stick with the system WebView, you can inject the WebRTC adapter polyfill (adapter.js) to add support for RTCPeerConnection in older browsers. Note this may have compatibility quirks with appr.tc's specific implementation.

Step 1: Add adapter.js to Assets

Download a version of adapter.js targeted at older browsers and place it in your app's assets folder.

Step 2: Inject the Polyfill Before Loading the URL

Modify your WebView setup to load the polyfill first, then load appr.tc once it’s ready:

// Inside your goOnButton onClick listener
// Load the polyfill from assets
mWebView.loadUrl("file:///android_asset/adapter.js");
// Load the target URL after the polyfill finishes loading
mWebView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        if (url.equals("file:///android_asset/adapter.js")) {
            mWebView.loadUrl("https://appr.tc/r/658450307");
        }
    }
});

Quick Verification Checks

  • Confirm all camera/audio permissions are declared in the manifest (you already have this covered, but double-check)
  • For forward compatibility, consider adding runtime permission requests (required for API23+, but API22 only needs manifest permissions)
  • Ensure DomStorageEnabled and MediaPlaybackRequiresUserGesture(false) are always enabled before loading the WebRTC page

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:27:50