Создание виджета для Android

| 23.03.2014

Виджеты — это графические компоненты, размещаемые на «домашнем экране» и, как правило, служащие в качестве ярлыков для быстрого запуска приложений, либо же для предоставления той или иной информации, обновляемой с определенным интервалом. Не каждое приложение включает возможность разместить виджет, однако, разработчику под Андроид это нужно уметь делать. В данной статье мы как раз рассмотрим, как можно создать простейший виджет.

Итак, создадим виджет, который будет выводить текущую дату и время.

Рабочее поле домашнего экрана любого смартфона обычно представляет собой 16 «ячеек» — 4 х 4, имеющих размер 74 на 74 dp минус 2 пикселя на границы ячейки. Если мы создаем виджет, который имеет ширину в 130 dp, то весь виджет по ширине все равно будет занимать две ячейки (в оставшуюся часть от второй ячейки уже ничего другого не будет размещено).

Создадим необходимый код для нашего виджета.

1. Создадим layout для виджета, то есть его внешний вид. Код res/layout/main.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@android:color/white"
    android:orientation="vertical" >
 
    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test" />
 
</LinearLayout>

Как видим, наш виджет представляет собой всего лишь одно текстовое поле, которое мы будем заполнять информацией о дате и времени. По умолчанию, в качестве текстового значения выводим слово «Test».

2. Создадим конфигурационный файл, описывающий наш виджет — res/xml/widget_provider.xml:

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="146dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="1800000"
    android:initialLayout="@layout/main" />

Все нужные настройки мы помещаем внутрь тега appwidget-provider. Мы задаем его высоту (74dp минус 2dp на границы), ширину (74dp + 74dp минус 2dp на границы), частоту обновления updatePeriodMillis в миллисекундах и файл компоновки initialLayout, который мы создали на предыдущем шаге.

Стоит отметить, что можно задавать любое количество миллисекунд, однако, в реальности виджет не будет обновляться чаще, чем раз в 30 минут. Такое ограничение позволяет экономить заряд батареи и другие ресурсы устройства. Таким образом, время, показанное нашим виджетом будет обновляться раз в полчаса. Это не очень практично, но наша цель — научиться создавать виджет и попрактиковаться.

3. Создаем java-код, который будет обновлять наш виджет — src/ru/androiddocs/widget/MyWidget.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package ru.androiddocs.widget;
 
import java.text.SimpleDateFormat;
import java.util.Date;
 
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
 
public class MyWidget extends AppWidgetProvider {
 
    public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
 
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        //вызываем переопределенный метод родительского класса		
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        //пишем в лог имя данного метода для отслеживания
        Log.d("kkk", "onUpdate");
 
        //Создаем новый RemoteViews
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
        //Создаем строку с текущей датой и временем       
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = new Date();
        String now = dateFormat.format(date);
        //обновляем данные в TextView виджета
        remoteViews.setTextViewText(R.id.textView2, now);         
        appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
 
    }
 
    @Override
    public void onReceive(Context context, Intent intent) {
        //вызываем переопределенный метод родительского класса
        super.onReceive(context, intent);
        //пишем в лог имя текущего метода
        Log.d("kkk", "onReceive");
 
        //Ловим наш Broadcast
        final String action = intent.getAction();
        if (ACTION_WIDGET_RECEIVER.equals(action)) {              
 
        }         
   }
}

Внутри данного класса — два метода: onUpdate() и onReceive(). Первый метод срабатывает всегда, когда «наступает момент» для обновления виджета (время мы задали в миллисекундах в конфигурационном xml-файле). Второй метод — с наступлением определенного события-intent (Intent broadcast). На данный момент мы не помещаем какую-либо серьезную логику во второй метод, но используем логирование, чтобы увидеть, что при вызове onUpdate следом также вызывается и метод onReceive().

логирование

Здесь мы могли бы не включать метод onReceive() в код, но оставим его для примера. В дальнейшем если мы захотим обновить виджет из активити не дожидаясь наступления нужного времени, то как раз данный метод пригодиться очень кстати.

Чтобы получить доступ к TextView виджета мы должны использовать RemoteViews, т.к. обратиться к layout напрямую не получится. Далее мы «сеттим» текст (время в строковом формате):

1
remoteViews.setTextViewText(R.id.textView2, now);

и обновляем виджет:

1
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);

Сам виджет выглядит на эмуляторе вот так:

виджет на Андроид устройстве

Автор: mastri.ru

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*