TL; DR:
Я делаю живые обои, используя WallpaperService, и хочу нарисовать их из WebView. Однако, когда я создаю WebView, его ширина и высота равняются 0, поэтому ничто не рисует, кроме цвета фона WebView. Существует старое исправление для этого в Как установить размер веб-просмотра в WallpaperService? , но в современном Android оно не работает. Я надеюсь узнать, как установить размер WebView, созданного с помощью WallpaperService.
ОРИГИНАЛЬНАЯ ПОЧТА:
Я делаю живые обои, используя WallpaperService, и я хочу, чтобы весь их контент просто представлял собой WebView (поскольку анимация выполняется с помощью JavaScript с использованием HTML). Ни один из примеров, которые я нашел для живых обоев, не использует WebView; вместо этого они используют Android Canvas. Я нашел этот пост StackOverflow: Как установить размер веб-просмотра в WallpaperService? , который, кажется, говорит о том, что это возможно, но когда я попробовал их код, я получаю сообщение об ошибке. Вот мой код:
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:
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@e1a9690 -- permission denied for window type 2002
Если я закомментирую строку wm.addView(webView, params);
, я больше не получаю эту ошибку (но, конечно, в предварительном просмотре обоев ничего не появляется, кроме черноты).
Любые указатели или предложения будут оценены!
ОБНОВЛЕНИЕ 1:
Хорошо, ошибка 2002 года была вызвана использованием TYPE_PHONE, тогда как на самом деле это должно быть TYPE_WALLPAPER. Теперь я получаю эту ошибку вместо:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
При поиске этой ошибки появляются несколько сообщений, таких как Невозможно добавить окно - нулевой токен недействителен; ваша активность запущена? и Проблемы с созданием всплывающего окна в Android Activity , но я не уверен, что они охватывают этот случай. В любом случае, кажется, что существует множество теорий.
Одно из предложений - сделать addView
в onCreate
; Я попробовал, но это ничего не изменило.
Поскольку WallpaperService - это сервис, а не активность, есть ли у меня активность, чтобы добавить окно? Можно ли добавить окно в сервис? Если нет, могу ли я добавить активность в службу, чтобы добавить к ней окно?
ОБНОВЛЕНИЕ 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. Кажется, это работает, за исключением того, что WebView имеет ширину 0 и высоту 0. В этом, конечно, смысл Как установить размер веб-просмотра в WallpaperService? , но он опирается на addView, из-за чего у меня возникают проблемы при работе.
Может быть, есть другой способ установить размер WebView, чем метод addView? Я пытался использовать setLayoutParams в WebView, и это, похоже, не работает, предположительно потому, что у WebView нет родителя? Есть ли способ установить его ширину и высоту, не требуя родителя? Или есть способ дать ему родителя без использования addView?
ОБНОВЛЕНИЕ 3:
Я попробовал еще несколько вещей, чтобы установить размер WebView. Я попробовал конструктор WebView, который принимает AttributeSet, используя этот 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" />
Я также попытался установить размер из веб-JavaScript, установив window.innerWidth, а также вызвав window.resizeTo. Я также попытался просто сделать некоторый веб-контент и убедиться, что переполнение было видно. Ни один из этих методов не сработал.
Я знаю, что WebView рисует на поверхности, потому что, если я изменю цвет фона, цвет поверхности изменится.
Все еще ищите способ установить размер WebView!