I came across ServiceWorkerController while looking through the Android WebView documentation and decided to give it a try. Unfortunately I have been unable to get intercept any
I have found the issue to be a misunderstanding. I had believed that installing a ServiceWorkerClient
would allow for me to intercept all requests from all WebViews in my app regardless of domain. This appears to not be the case. The ServiceWorkerClient
is only called if a webview has installed a ServiceWorker already. All service worker requests from all service workers are then funneled to the ServiceWorkerClient
. What this means is that if you wish to intercept all network requests within all webviews in your app you will also need to override shouldInterceptRequest()
on your WebViewClient
as well.
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.ServiceWorkerClient;
import android.webkit.ServiceWorkerController;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.Nullable;
public class MainActivity extends Activity {
private final static String LOGTAG = MainActivity.class.getSimpleName();
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ServiceWorkerController swController = ServiceWorkerController.getInstance();
swController.setServiceWorkerClient(new ServiceWorkerClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
Log.e(LOGTAG, "in service worker. isMainFrame:"+request.isForMainFrame() +": " + request.getUrl());
return null;
}
});
swController.getServiceWorkerWebSettings().setAllowContentAccess(true);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
WebSettings webSettings = mWebView.getSettings();
WebView.setWebContentsDebuggingEnabled(true);
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient() {
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view,
WebResourceRequest request) {
Log.e(LOGTAG, "in webview client. isMainFrame:"+request.isForMainFrame() +": " + request.getUrl());
return super.shouldInterceptRequest(view, request);
}
});
Log.e(LOGTAG, "about to load URL");
//service worker handler only invoked on pages with service workers
mWebView.loadUrl("https://developers.google.com/web/fundamentals/primers/service-workers/");
}
@Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
}