TL;DR:
I'm making a live wallpaper using WallpaperService, and I want to draw to it from a WebView. However, when I create the WebView, it's 0 width and height, so nothing draws but the WebView's background color. There is an old fix for that in How to set size of webview in WallpaperService? but it doesn't appear to work in modern Android. I'm hoping to learn how to set the size of the WebView created from a WallpaperService.
ORIGINAL POST:
I'm making a live wallpaper using WallpaperService, and I want all of its content to simply be a WebView (since the animation is done with JavaScript using HTML). None of the examples I've found for live wallpaper use WebView; they use the Android Canvas instead. I have found this StackOverflow post: How to set size of webview in WallpaperService? which seems to say that it's possible, but when I tried their code I end up getting an error. Here's my code:
public class MyLWPService extends WallpaperService {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public Engine onCreateEngine() {
return new MyEngine(this);
}
public class MyEngine extends Engine {
public MyEngine(Context context) {
WebView webView = new WebView(context);
webView.setVisibility(webView.GONE);
webView.loadUrl("http://example.com/");
WindowManager wm = (WindowManager)context.getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT
);
params.width = 200;
params.height = 200;
wm.addView(webView, params);
}
}
}
When I run in the emulator and go into the wallpaper preview in the settings, I get this error in logcat:
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@e1a9690 -- permission denied for window type 2002
If I comment out the wm.addView(webView, params);
line, I no longer get that error (but of course nothing shows up in the wallpaper preview but blackness).
Any pointers or suggestions would be appreciated!
UPDATE 1:
Okay, the 2002 error was caused by using TYPE_PHONE, when it should in fact be TYPE_WALLPAPER. I'm now getting this error instead:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
Searching for that error brings up a few posts such as Unable to add window -- token null is not valid; is your activity running? and Problems creating a Popup Window in Android Activity but I'm not sure they cover this case. At any rate, there seems to be a lot of theories.
One suggestion is to do the addView
in the onCreate
; I gave that a try but it didn't make a difference.
Since the WallpaperService is a service, not an activity, do I even have an activity to add the window to? Is it possible to add a window to a service? If not, can I add an activity to the service so I can add the window to that?
UPDATE 2:
Here's the full error:
2019-01-24 14:01:21.929 1914-6592/? W/WindowManager: Attempted to add wallpaper window with unknown token null. Aborting.
2019-01-24 14:01:21.930 32356-32356/? D/AndroidRuntime: Shutting down VM
2019-01-24 14:01:21.931 32356-32356/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pixfabrik.livingworlds, PID: 32356
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:798)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at com.pixfabrik.livingworlds.MyLWPService$MyEngine.onSurfaceCreated(MyLWPService.java:130)
at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:884)
at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:1020)
at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:1343)
at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:37)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-01-24 14:01:21.938 1914-1929/? I/ActivityManager: Showing crash dialog for package com.pixfabrik.livingworlds u0
Meanwhile, I'm trying the approach of just creating the WebView but not trying to add it anywhere, but instead drawing it to the surface's canvas using the WebView's draw function. This seems to be working except the WebView is 0 width and 0 height. That is of course the point of How to set size of webview in WallpaperService?, but it relies on addView, which is what I'm having trouble getting to work.
Might there be another way to set the WebView size than the addView technique? I've tried using WebView's setLayoutParams, and that doesn't seem to work, presumably because the WebView doesn't have a parent? Is there a way to set its width and height without requiring a parent? Or is there a way to give it a parent without using addView?
UPDATE 3:
I've tried some more things to set the WebView size. I tried the WebView constructor that takes in an AttributeSet, using this XML:
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="500dp"
android:layout_height="500dp" />
I also tried setting the size from within the web JavaScript, by setting window.innerWidth, and also by calling window.resizeTo. I also tried just making some web content and making sure overflow was visible. None of these techniques worked.
I do know that the WebView is drawing to the surface, because if I change the background color, the color of the surface changes.
Still looking for a way to set the size of the WebView!