Android: загрузка вывода WebView в виджет приложения

в то время как я ценю, что Приложение Виджете не поддерживает WebView непосредственно, можно ли вообще использовать ImageView (который поддерживается) и техника, как описано здесь для создания изображения для ImageView? The WebView не будет использоваться напрямую, а только в фоновом режиме, чтобы обеспечить изображение для ImageView.

2 ответов


это возможно, видимо, по крайней мере на моем устройстве, хотя ваш пробег может варьироваться.

в манифесте, мы регистрируем виджет <receiver> как обычно, а также зарегистрировать наш Service обработки WebView и его захват изображения.

<manifest ... >
    ...

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <application ... >
        ...

        <receiver
            android:name=".WebWidgetProvider"
            android:label="@string/widget_name" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_info" />
        </receiver>

        <service android:name=".WebShotService" />

    </application>

</manifest>

в информационном файле виджета,widget_info.xml, Я установил минимальный размер 4 x 2.

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_layout"
    android:minWidth="292dip"
    android:minHeight="146dip" />

для этого примера макет виджета,widget_layout.xml, просто ImageView.

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="fitXY"
    android:src="@drawable/ic_launcher" />

в AppWidgetProvider в этом примере переопределяется только onUpdate() метод, так как мы используем тот же ACTION_APPWIDGET_UPDATE для запуска наших собственных обновлений с AlarmManager. Обратите внимание, что пример тревоги будет срабатывать каждые 30 секунд, пока есть активный виджет. Вы, вероятно, не хотите делать это вне тестирования, так как обновления виджетов могут быть довольно дорогостоящими.

public class WebWidgetProvider extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // We can't trust the appWidgetIds param here, as we're using
        // ACTION_APPWIDGET_UPDATE to trigger our own updates, and
        // Widgets might've been removed/added since the alarm was last set.
        final int[] currentIds = appWidgetManager.getAppWidgetIds(
            new ComponentName(context, WebWidgetProvider.class));

        if (currentIds.length < 1) {
            return;
        }

        // We attach the current Widget IDs to the alarm Intent to ensure its
        // broadcast is correctly routed to onUpdate() when our AppWidgetProvider
        // next receives it.
        Intent iWidget = new Intent(context, WebWidgetProvider.class)
            .setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
            .putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, currentIds);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, iWidget, 0);

        ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE))
            .setExact(AlarmManager.RTC, System.currentTimeMillis() + 30000, pi);

        Intent iService = new Intent(context, WebShotService.class);
        context.startService(iService);
    }
}

на Service, мы создаем экземпляр WebView и добавить его в FrameLayout, который в свою очередь добавляется к WindowManager С нуля для параметры width и height. Затем мы загружаем тестовый URL-адрес в WebView, и когда страница заканчивается, мы заставляем WebView макет до соответствующего размера, и нарисовать его к нашей цели Bitmap через


добавление к приведенному выше ответу,

для людей, которые получают эту ошибку - не удалось добавить окно. Разрешение запрещено для этого типа окна по крайней мере, в моем случае с устройствами под управлением marshmallow тип должен быть изменен.

просто заменить

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY или

WindowManager.LayoutParams.TYPE_TOAST (или)

WindowManager.LayoutParams.TYPE_APPLICATION_PANEL

и он будет работать прекрасно.

Примечание: проверено и подтверждено с Nexus6p работает последняя версия marsmallow.

на WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY требуется разрешение android.разрешение.INTERNAL_SYSTEM_WINDOW, который может быть добавлен только для системы Android обзоры приложения.

также не забудьте изменить высоту и ширину веб-представления после завершения загрузки страницы в onPageFinished () для людей, которые хотят анализировать данные с помощью Javascript.

Я полностью упустил важность этого в приведенном выше ответе и в конечном итоге потратил много времени.

первоначально мое предположение было, так как мое требование не должно было отображать содержимое в веб-представлении виджету через представление изображения, это не требовалось.

Как оказалось, javascript не может анализировать данные из веб-представления, если ширина и высота представления не равны нулю.