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

Пишем приложение «Спокойный сон»

Современные телефоны на Android – далеко не просто «звонилки». При помощи как сторонних, так и предустановленных программных средств мобильные гаджеты умеют самостоятельно получать обновления в социальных сетях, принимать электронную почту и так далее – и зачастую всё это сопровождается звуковыми уведомлениями. Удобно – до тех пор, пока не нужно лечь спать, а смартфон в 3 часа ночи радостно «жужжит» про обновление статуса Васи Пупкина «Вконтакте». Приходится отключать все оповещения на ночь. Программу, которая будет это делать, мы и будем создавать.

В качестве среды разработки мы будем использовать Eclipse. Не забываем, что понадобятся также установленные Android SDK и JDK.

Начнем с интерфейса. Его создание происходит во встроенном редакторе, и в целом всё интуитивно понятно – это конструктор форм. Развернутые рекомендации и советы по поводу создания пользовательского интерфейса для Android-приложений можно прочитать в посвященном этому разделе официального сайта разработчиков для ОС Android – http://developer.android.com/intl/zh-TW/guide/practices/ui_guidelines/index.html. По указанной ссылке также выложены шаблоны для программ Photoshop и Illustrator, которые могут значительно облегчить процесс создания иконок – так что на данном вопросе мы детально останавливаться не будем, нас больше интересует программная часть.

Несколько слов о хранении настроек пользователя. Для работы с последними в Android имеется класс PreferenceManager. Метод getSharedPreferences() первым аргументом принимает название набора настроек, а вторым – режим создания (открытый для записи, для чтения или закрытый). В ответ получается объект класса SharedPreferences – он позволяет записывать и/или считывать настройки. Если набора не существует, он будет создан:

            SharedPreferences preferences = getSharedPreferences("goodnight", MODE_PRIVATE);

Для считывания разных видов данных существуют разные методы, у которых первый аргумент – это название поля, а второй – его значение по умолчанию:

            preferences.getBoolean("isEnabled", false)

preferences.getInt("startHour", 23)

Для записи нужно получить объект SharedPreferences.Editor при помощи метода edit(), с вызовом в конце метода commit():

Editor prefEditor =preferences.edit();

prefEditor.putBoolean("isEnabled",isEnabledCheckBox.isChecked());

prefEditor.putInt("startHour", startTimePicker.getCurrentHour());

prefEditor.putInt("startMinute", startTimePicker.getCurrentMinute());

prefEditor.putInt("endHour", endTimePicker.getCurrentHour());

prefEditor.putInt("endMinute", endTimePicker.getCurrentMinute());

prefEditor.commit();

Чтобы сохранять деятельность приложения, даже когда оно не открыто, то есть в фоне, существуют сервисы. Кстати, это одно из ключевых отличий от iOS, и мы хотим сказать, что оно дает множество очков в пользу ОС Android в извечном противостоянии. Но ближе к делу. Для того, чтобы создать сервис, нужно сначала создать собственный класс, унаследованный от android.app.Service и который переопределяет метод onBind():

public class GoodnightService extends Service {

  @Override

  public IBinder onBind(Intent intent) {

    // TODO Auto-generated method stub

    return null;

  }

}

Могут оказаться полезными методы onCreate() и onDestroy():

@Override

  public void onCreate() {

    super.onCreate();

    Log.i("GoodnightService", "Service created");

  }

@Override

  public void onDestroy() {

    super.onDestroy();

    Log.i("GoodnightService", "Service destroyed");

  }

Всего есть два типа взаимодействия с сервисами – это передача параметров при старте или же с использованием AIDL (Android IDL). В первом случае, после запуска сервиса – его можно только закрыть. А при использовании второго типа взаимодействия можно создать интерфейс, позволяющий управлять сервисом – в нашем случае, например, менять начало и конец ночи. Создаем файл с расширением .aidl и прописываем в нем интерфейс:

interface IGoodnightService {

  void UpdateSettings();

}

Теперь нужно скомпилировать проект. Это необходимо для того, чтобы сгенерировать из созданного .aidl-файла IDL-интерфейс. После завершения компиляции можно обновить метод onBind(), а также создать новое свойство binder:

@Override

  public IBinder onBind(Intent intent) {

    return binder;

  }

private final IGoodnightService.Stub binder = new IGoodnightService.Stub() {

    @Override

    public void UpdateSettings() {

      Init();

      Update();

    }

  };

Если метода Stub() нет, то, вероятно, файл, содержащий интерфейс имеет расширение не .aidl, а .java.

Напомним, что важно не забыть добавить сервис в «манифест» (AndroidManifest.xml).

Для использования созданного интерфейса, при нажатии на кнопку «Применить», нужно выполнить пару простых действий. Сначала понадобится объект с типом интерфейса:

  private IGoodnightService service;

Далее нужно создать свойство типа ServiceConnection. Оно будет отслеживать текущее состояние сервиса и необходимо для связи сервиса с интерфейсом:

private ServiceConnection svcConn=new ServiceConnection() {

    public void onServiceConnected(ComponentName className,

    IBinder binder) {

      service=IGoodnightService.Stub.asInterface(binder);

    }

    public void onServiceDisconnected(ComponentName className) {

    service=null;

    }

    };

Не забываем связать сервис с приложением при помощи метода bindService():

bindService(new Intent(this,GoodnightService.class), svcConn, BIND_AUTO_CREATE);

После проделанных действий можно обращаться к методам, которые описаны в IGoodnightService:

    try {

      service.UpdateTimers();

    } catch (RemoteException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

    }

Для отображения процесса работы сервиса пользователю, мы будем использовать механизмом Android-оповещений. Это может быть вибрация, звук или иконка в строке состояния. Если открыть строку состояния – можно увидеть оповещение в развернутом виде. Текстовые оповещения, в свою очередь, бывают двух видов – сообщающие о новых событиях или сообщающие просто о работе программы. Первый тип оповещений можно удалять из списка, нажав на «Очистить уведомления». Первый вариант в нашем приложении содержал такие оповещения каждую минуту – чтобы они не пропадали с экрана. Но, как показывает практика, устройство начинает жутко подтормаживать уже через 5-6 часов работы, а оповещения перестают обновляться. А оптимизация – это, как известно, одна из основ программирования. Потом есть и другой вариант. Для того, чтобы создать оповещения, мы прибегнем к NotificationManager, получаемый при помощи метода getSystemService():

    final NotificationManager mgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

Далее, необходимо само оповещение (Notification):

    Notification note = new Notification(R.drawable.status,

        getResources().getString(R.string.startMessage),

        System.currentTimeMillis());

    note.flags |= Notification.FLAG_ONGOING_EVENT;

    PendingIntent i = PendingIntent.getActivity(this, 0,

        new Intent(this, Setup.class), 0);

    String interval = String.format("%d:%02d – %d:%02d", startHour,

        startMinute, endHour, endMinute);

    note.setLatestEventInfo(this, interval,

        getResources().getString(R.string.notificationMessage), i);

PendingIntent – ссылка на приложение, которое будет запущено после клика по уведомлению. В свою очередь, Notification.FLAG_ONGOING_EVENT задает второй тип оповещений. Для отправки оповещения применяется метод notify():

    mgr.notify(NOTIFY_ME_ID, note);

Для удаления оповещения из строки состояния вызывается метод cancel():

    mgr.cancel(NOTIFY_ME_ID);

Для доступа к функции управления звуком (возможности включать или выключать его), понадобится получение AudioManager:

    AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

Устанавливаем необходимый режим при помощи setRingerMode():

    manager.setRingerMode(AudioManager.RINGER_MODE_SILENT);

Теперь можно приступить к финальной сборке приложения. Чтобы собрать программу в .apk-файл, который является ни чем иным, как контейнером, необходимо выбрать проект, в контекстном меню выбрать мастер экспорта (расположен в Android Tools), и дальше следовать указаниям.

В целом, создавать приложения для Android не слишком сложно – достаточно приловчится, а дальше, как говориться, «дело техники». Главное – желание самосовершенствоваться в навыках программирования.

Сергей Назипов
2013-08-03 02:43:39
а готовый apk можно скачать?