» Программирование Android

Создание виджета обратного отсчета

Данная статья будет посвящена программированию на Android, а именно – созданию несложного виджета обратного отсчета своими руками. Для примера – мы создадим виджет, который будет отображать время до Нового Года.

Итак, в Android существует системный класс CountDownTimer. Он без проблем справляется с отсчетом времени, кроме того способен выполнять указанное действие через каждый заданный интервал времени. Исходя из таких возможностей сам по себе напрашивается следующий алгоритм – в onUpdate() нашего виджета указываем старт счетчика, а частоту обновления выставляем равно нулю. Счетчик обратного отсчета будет запускаться при включении виджета.

Касательно того, какой интервал задавать для выполнения действий счетчика, то оптимальным, пожалуй, будет значение равное одной минуте. Это будет не так сильно нагружать систему и садить аккумуляторную батарею. То есть интерфейс виджета будет обновляться каждую минуту. Мы не будем привязываться к самому счетчику, а для простоты будем брать данные об остатке минут, часов и дней напрямую из системных констант, используя системный класс Calendar.

Перейдем сразу к описанию нашего виджета обратного отсчета. Итак, вот готовый код для рассмотрения, назовем его NYCounter.java:

            package com.newyear.counter;

 

import java.util.Calendar;

import java.util.Date;

 

import android.appwidget.AppWidgetManager;

import android.appwidget.AppWidgetProvider;

import android.content.Context;

import android.os.CountDownTimer;

import android.widget.RemoteViews;

 

public class NYCounter extends AppWidgetProvider{

 

  public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

 

  final Context context_t = context;

  final RemoteViews views = new RemoteViews(context_t.getPackageName(), R.layout.widget);

  final AppWidgetManager wm = appWidgetManager;

  final int[] ids = appWidgetIds;

 

  //запускаем счетчик до 1 Января 2012 (а доживем ли ? =) ), с выполнением действия каждую минуту           

  CountDownTimer timer = new CountDownTimer (dateToMilliSeconds(1,0,2012,0,0),60000) {

 

    public void onTick(long millisUntilFinished) { //выполняем регулярное действие

 

      Calendar c = Calendar.getInstance();

      c.setTime(new Date());

      int doy = c.get(Calendar.DAY_OF_YEAR); //получаем нынешний день

      int hod = c.get(Calendar.HOUR_OF_DAY); // час

      int moh = c.get(Calendar.MINUTE); // минуту

      //int som = c.get(Calendar.SECOND); // секунду

      int diy = 0;

 

      if (isLeapViaPopeGregory (c.YEAR)) { // проверяем на высокосный год

        diy = 366;

      } else {

        diy = 365;

      }

 

      int daysLeft = diy — doy;

      String hoursLeft = Integer.toString(24 — hod);

      String minutesLeft = Integer.toString(60 — moh);

      //String secondsLeft = Integer.toString(60 — som);

 

      if (hoursLeft.length() < 2) {

        hoursLeft = «0» + hoursLeft;

      }

 

      if (minutesLeft.length() < 2) {

            minutesLeft = «0» + minutesLeft;

      }

 

 

      //меняем текст виджета

      views.setTextViewText(R.id.dayCounter, daysLeft + «»);

      views.setTextViewText(R.id.hmCounter, hoursLeft + » : » + minutesLeft);

 

      wm.updateAppWidget(ids, views);

    }

 

  public void onFinish() {

  }

 

}.start();

}

 

  public long dateToMilliSeconds(int day, int month, int year, int hour, int minute)  {

 

    Calendar c = Calendar.getInstance();

    c.set(year, month, day, hour, minute, 00);

 

    return c.getTimeInMillis();

 

  }

 

  public static final boolean isLeapViaPopeGregory ( int yyyy ) {

    if ( yyyy < 0 ) return( yyyy + 1 ) % 4 == 0;

    if ( yyyy < 1582 ) return yyyy % 4 == 0;

    if ( yyyy % 4 != 0 ) return false;

    if ( yyyy % 100 != 0 ) return true;

    if ( yyyy % 400 != 0 ) return false;

    return true;

  }

}

 

Описываем наш виджет и привязываем к нему дизайн. Директория xml, файл widget_info.xml:

            <?xml version=»1.0″ encoding=»UTF-8″?>

<appwidget-provider xmlns:android=»http://schemas.android.com/apk/res/android»

    android:minWidth=»220dp»

    android:minHeight=»144dp»

    android:updatePeriodMillis=»0″

    android:initialLayout=»@layout/widget»>

</appwidget-provider>

 

            Теперь папка layout, файл widget.xml:

<?xml version=»1.0″ encoding=»utf-8″?>

<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»

    android:orientation=»vertical»

    android:layout_width=»wrap_content»

    android:layout_height=»wrap_content»

    android:background=»@drawable/ball_red»

    >

            <TextView

                    android:id=»@+id/dayCounter»

                    android:layout_width=»fill_parent»

                    android:layout_height=»wrap_content»

                    android:text=»0″

                    android:paddingLeft=»70px»

                    android:paddingTop=»15px»

                    android:textColor=»#FFFFFF»

                    android:textSize=»80px»/>         

            <TextView

                        android:id=»@+id/hmCounter»

                        android:layout_width=»fill_parent»

                        android:layout_height=»wrap_content»

                        android:text=»00 : 00″

                        android:paddingLeft=»50px»

                        android:textColor=»#FFFFFF»

                        android:textSize=»50px»/>

            <TextView

                        android:id=»@+id/sCounter»

                        android:layout_width=»fill_parent»

                        android:layout_height=»wrap_content»

                        android:text=»»

                        android:paddingLeft=»110px»

                        android:textColor=»#FFFFFF»

                        android:textSize=»30px»/>

</LinearLayout>

 

            Не забываем также наполнить архиважный AndroidManifest.xml:

<?xml version=»1.0″ encoding=»utf-8″?>

<manifest xmlns:android=»http://schemas.android.com/apk/res/android»

      package=»com.newyear.counter»

      android:versionCode=»1″

      android:versionName=»1.0″>

    <application android:icon=»@drawable/ball_red» android:label=»@string/app_name»>

        

<receiver android:name="NYCounter" >
                <intent-filter>

                 

 Далее необходимо добавить в наш проект соответствующую иконку, а также картинку, которая будет служить фоном самого виджета. Так как наш виджет – это отсчёт времени до Нового Года, то картинка должна быть соответствующей тематики:

Иконку проще всего сделать, уменьшив наш фон.

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

Конечно же, сделанный нами виджет достаточно сырой и без излишних «наворотов». Это скорее простое решение для простой задачи, но данное решение может послужить отличным примером и как основа для создания более сложных и комплексных проектов.