Android:将WebView用于WallpaperService [英] Android: Use WebView for WallpaperService

查看:131
本文介绍了Android:将WebView用于WallpaperService的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR:

我正在使用WallpaperService制作动态壁纸,我想从WebView绘制到动态壁纸.但是,当我创建WebView时,它的宽度和高度为0,因此除了WebView的背景色之外,什么都没有绘制.在>如何在WallpaperService中设置Webview的大小的过程中,有一个旧的修复方法.?,但它似乎在现代Android中不起作用.我希望学习如何设置从WallpaperService创建的WebView的大小.

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.

原始帖子:

我正在使用WallpaperService制作动态壁纸,并且我希望它的所有内容都只是一个WebView(因为动画是使用HTML的JavaScript完成的).我发现的用于动态壁纸的示例均未使用WebView.他们改用Android Canvas.我发现了这个StackOverflow帖子:如何在WallpaperService中设置Webview的大小?似乎有可能,但是当我尝试他们的代码时,我最终得到了一个错误.这是我的代码:

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);
        }
    }
}

当我在模拟器中运行并进入设置中的墙纸预览时,我在logcat中收到此错误:

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:无法添加窗口android.view.ViewRootImpl$W@e1a9690-窗口类型2002的权限被拒绝

如果我注释掉 wm.addView(webView,params); 行,我将不再遇到该错误(但是,壁纸预览中除了黑色以外,什么都没有显示).

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!

更新1:

好的,2002错误是由于使用TYPE_PHONE引起的,而实际上应该是TYPE_WALLPAPER.我现在收到此错误:

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:无法添加窗口-令牌null无效;您的活动正在运行吗?

搜索该错误会弹出一些帖子,例如在以下位置创建弹出窗口的问题Android活动,但我不确定它们是否涵盖了这种情况.无论如何,似乎有很多理论.

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.

一个建议是在 onCreate 中执行 addView ;我尝试了一下,但没有任何变化.

One suggestion is to do the addView in the onCreate; I gave that a try but it didn't make a difference.

由于WallpaperService是服务而不是活动,因此我什至有活动要添加窗口吗?是否可以向服务添加窗口?如果不是,是否可以向该服务添加活动,以便可以向其添加窗口?

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?

更新2:

这是完整的错误:

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

同时,我正在尝试仅创建WebView的方法,而不是尝试将其添加到任何位置,而是使用WebView的draw函数将其绘制到曲面的画布上.除了WebView的宽度为0且高度为0以外,这似乎是可行的.当然,这就是如何在WallpaperService中设置Webview大小的问题?,但是它依赖于addView,这是我上班时遇到的麻烦.

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.

除了addView技术之外,还有其他方法可以设置WebView大小吗?我已经尝试过使用WebView的setLayoutParams,但这似乎不起作用,大概是因为WebView没有父级吗?有没有一种方法可以设置其宽度和高度而无需父母?还是有一种无需使用addView就可以为其赋予父项的方法?

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?

更新3:

我已经尝试了其他一些方法来设置WebView的大小.我尝试使用以下XML来采用AttributeSet的WebView构造函数:

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" />

我还尝试通过设置window.innerWidth以及调用window.resizeTo在Web JavaScript中设置大小.我还尝试仅制作一些Web内容,并确保可见溢出.这些技术都无效.

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.

我确实知道WebView正在绘制到表面,因为如果更改背景颜色,则表面的颜色也会改变.

I do know that the WebView is drawing to the surface, because if I change the background color, the color of the surface changes.

仍在寻找一种设置WebView大小的方法!

Still looking for a way to set the size of the WebView!

推荐答案

好,由于一些

Okay, I've got it working, thanks to some help on Reddit. So ultimately you need to create a WebView but not try to attach it to anything. Then you have to size it so it shows content; that was the last missing piece. Here's the code for that:

// Get the screen width and height and put them in screenWidth and screenWidth 
// and then do the following with them:
int widthSpec = View.MeasureSpec.makeMeasureSpec(screenWidth, View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(screenHeight, View.MeasureSpec.EXACTLY);
webView.measure(widthSpec, heightSpec);
webView.layout(0, 0, screenWidth, screenHeight);

然后,您可以从WebView绘制到SurfaceHolder的Canvas,一切都很可爱.

Then you can draw from the WebView to the SurfaceHolder's Canvas and everything is lovely.

谢谢大家的帮助!

更新2019年3月11日

现在一切正常,所以我认为我应该分享代码的要点,以防它对其他人有用:

It's all working now, so I thought I'd share a Gist of the code in case it's useful to other people:

https://gist.github.com/iangilman/71650d46384a2d4ae6387f2d4087cc37

这篇关于Android:将WebView用于WallpaperService的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆