Смекни!
smekni.com

Использование платформы j2me для мобильных телефонов при организации видеонаблюдений (стр. 4 из 7)

Сохранение ключа аутентификации выгодно при частом установлении соединения между данными устройствами.

После того, как два устройства аутентифицировали друг друга, шифрование может быть необходимо для данного соединения любому из этих устройств.

До применения шифрования устройства должны договориться о режиме шифрования и длине ключа.

Возможны три режима шифрования:

- отсутствие шифрования – если одно из устройств не поддерживает шифрование, то будет соединение без шифрования;

- шифрование пакетов между устройствами и широковещательных пакетов;

- шифрование только пакетов между устройствами.

До применения шифрования устройства должны договориться о размере ключа (8 – 128 бит).

Авторизация – это процесс предоставления удаленному Bluetooth-устройству доступа к некоторому сервису. Чтобы быть авторизированным, удаленное устройство вначале должно быть сначала аутентифицировано через bonding.

Доступ может быть предоставлен на время или постоянно.

При авторизации для некоторого устройства может быть установлен атрибут trust, который ассоциирует права авторизации с некоторым устройством. Устройство с таким атрибутом (доверенное устройство) может подключаться к Bluetooth-сервису и процесс авторизации будет успешен без вмешательства пользователя.

Чтобы хранить информацию о доверенных устройствах и различных уровнях авторизации для различных сервисов, применяются две базы данных – одна для устройств, другая для сервисов. Некоторым слоям необходим доступ к этим базам, который предоставляет менеджер безопасности.

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

3. Проектирование приложения для мобильного телефона на основе платформы J2ME

3.1 Постановка задачи

Требуется разработать приложение для мобильного телефона на платформе J2ME, которое будет осуществлять видеонаблюдение и предоставлять следующие основные возможности:

- расписание работы камеры – возможность указывать время начала и окончания видеонаблюдения;

- обнаружение движения и отправка SMS-сообщения или MMS-сообщения с соответствующим изображением;

- оповещение о возникающих ошибочных ситуациях на указанный номер;

- файловый браузер для выбора или создания папки, в которую требуется сохранять видеоданные от камеры как последовательность изображений;

- передача видеоданных, получаемых от камеры, в виде отдельных кадров по Bluetooth.

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

3.2 Построение интерфейса

Графический интерфейс приложения реализован с помощью библиотеки LWUIT. Стиль оформления всех использованных элементов интерфейса был настроен вручную. Основные принципы настройки стиля следующие.

Во-первых, можно изменить стиль одного конкретного компонента. Стиль каждого элемента определяется объектом класса Style. Чтобы получить стиль компонента, необходимо вызвать метод getStyle(). С помощью метода setStyle() можно изменить стиль данного компонента.

Во-вторых, можно изменить стиль всех компонентов одного типа, например, кнопок. Для этого необходимо получить объект UIManager.getInstance(), который определяет стиль оформления всех элементов по умолчанию. Далее следует использовать его метод setComponentStyle с двумя аргументами – имя класса компонента и объект класса Style. В листинге 3.1 приведен программный код настройки стиля текстового поля по умолчанию.

Листинг 3.1 – Применение стиля оформления для текстового поля

/**

* ConfigureTextFieldStyle

*

* @param manager– User Interface Manager

*/

private void configureTextField (UIManager manager) {

Style textFieldStyle = new Style();

textFieldStyle.setFgSelectionColor(0x0000);

textFieldStyle.setFgColor(0x000000);

textFieldStyle.setBgTransparency(0x00);

textFieldStyle.setFont(boldFont);

textFieldStyle.setBorder (Border.createLineBorder(1));

manager.setComponentStyle("TextField", textFieldStyle);

}

На рисунке 3.1 показана экранная форма с основными элементами и уже примененными стилями.


Рисунок 3.1 – Заставка приложения

При создании экрана заставки (рисунок 3.1) было необходимо выравнивание по центру. В библиотеке LWUIT нет такого способа размещения компонентов, поэтому был создан класс CenterLayout (листинг 3.2), расширяющий класс Layout. Layout является абстрактным классом, который наследуют все остальные классы-менеджеры размещения компонентов контейнера. В новом классе были переопределены методы layoutContainer (Containerparent) и getPreferredSize (Containerparent).

Листинг 3.2 – Выравнивание элементов по центру

/**

* Layout the given parent container children

* @param parent the given parent container

*/

public class CenterLayout extends Layout {

public void layoutContainer (Container parent) {

int components = parent.getComponentCount();

Style parentStyle = parent.getStyle();

int centerPos = parent.getLayoutWidth() / 2 +

parentStyle.getMargin (Component.LEFT);

int y = parentStyle.getMargin (Component.TOP);

for (int iter = 0; iter < components; iter++) {

Component current = parent.getComponentAt(iter);

Dimension d = current.getPreferredSize();

current.setSize(d);

current.setX (centerPos – d.getWidth() / 2);

Style currentStyle = current.getStyle();

y += currentStyle.getMargin (Component.TOP);

current.setY(y);

y += d.getHeight() + currentStyle.getMargin (Component.BOTTOM);

}

}

/**

* Returns the container preferred size

*

* @param parent the parent container

* @return the container preferred size

*/

public Dimension getPreferredSize (Container parent) {

int components = parent.getComponentCount();

Style parentStyle = parent.getStyle();

int height = parentStyle.getMargin (Component.TOP)

+ parentStyle.getMargin (Component.BOTTOM);

int marginX = parentStyle.getMargin (Component.RIGHT)

+ parentStyle.getMargin (Component.LEFT);

int width = marginX;

for (int iter = 0; iter < components; iter++) {

Component current = parent.getComponentAt(iter);

Dimension d = current.getPreferredSize();

Style currentStyle = current.getStyle();

width = Math.max (d.getWidth() + marginX

+ currentStyle.getMargin (Component.RIGHT) +

currentStyle.getMargin (Component.LEFT), width);

height += currentStyle.getMargin (Component.TOP) + d.getHeight() +

currentStyle.getMargin (Component.BOTTOM);

}

Dimension size = new Dimension (width, height);

return size;

}

}

В следующем листинге 3.3 содержится программный код экранной формы-заставки с применением разработанного класса-менеджера размещения элементов CenterLayout.

Листинг 3.3 – Экранная форма заставки

publicclassSplashScreenextendsForm {

public SplashScreen() {

setLayout (new CenterLayout());

setTitle ("Welcome");

addComponent (new Label(("Video observer")));

addComponent (new Label(("by M. Luskanova")));

}

}


Рисунок 3.2 – Главное меню

Для создания главного меню (рисунок 3.2) был реализован специальный класс, который представляет собой один пункт меню. Каждый элемент такого меню является контейнером с несколькими строчками и представляет их как единое целое. Такая функциональность достигается за счет наследования от класса Container и переопределения методов getComponentAt() и pointerPressed() (листинг 3.4).

Метод getComponentAt (int x, int y) вызывается, когда необходимо вернуть компонент, находящийся в заданной точке экрана. Если этот метод не переопределить, то будет возвращен элемент, входящий в данный контейнер. Переопределение второго метода гарантирует, что не произойдет никакой обработки (например, выделения) в случае, если пользователь выберет какой-либо элемент данного пункта.

Метод pointerPressed (int x, int y) выполняется в случае нажатия сенсорного указателя. Если этот метод не переопределить, то будет выделен компонент внутри данного контейнера.

Листинг 3.4 – Пункт главного меню

public class MylistItem extends Container implements FocusListener {

private Style selectedStyle =

UIManager.getInstance().getComponentStyle ("_selected");

private Style unselectedStyle =

UIManager.getInstance().getComponentStyle ("_unselected");

/**

* This method provides performance of

* included components as one

*/

public Component getComponentAt (int x, int y) {

return this;

}

/**

* Do nothing when user clicks on any element

*/

public void pointerPressed (int x, int y) {

}

/**

* Returns"_unselected" style by default

*/

protected String getUIID() {

return "_unselected";

}

/**

* Change style for selected menu item

*/

public void focusGained (Component cmp) {

cmp.setStyle(selectedStyle);

}

/**

* Change style for unselected menu item

*/

public void focusLost (Component cmp) {

cmp.setStyle(unselectedStyle);

}

}

Метод getUIID() переопределен для того, чтобы возвращать стиль невыделенного элемента. Метод focusGained() вызывается при получении данным пунктом меню фокуса, и поэтому требуется этот пункт отрисовать другим стилем.

При перемещении фокуса на следующий пункт меню нужно поменять стиль этого пункта на обычный, что и выполняется в переопределенном методе focusLost().

Само меню создается следующим образом с использованием вышеуказанного класса (листинг 3.5). Preferences.getInstanse() – это объект, который хранит все сделанные пользователем настройки.

Листинг 3.5 – Создание главного меню

Preferences pr = Preferences.getInstanse();

setLayout (new BoxLayout (BoxLayout.Y_AXIS));

getContentPane().setIsScrollVisible(false);

MylistItem mli = new MylistItem (MainMenuConstatns.SCHEDULE, "Schedule");

if (! pr.isStartRecordFromUnbounded()) {

mli.addString ("from" +

pr.getStartRecordFromCalendar().get (java.util. Calendar.YEAR) +"." +

pr.getStartRecordFromCalendar().get (java.util. Calendar.MONTH) +"." +

pr.getStartRecordFromCalendar().get (java.util. Calendar.DAY_OF_MONTH)

+" "+pr.getStartRecordFromCalendar().get (java.util. Calendar.HOUR_OF_DAY)

+":"+pr.getStartRecordFromCalendar().get (java.util. Calendar.MINUTE));

}

if (! pr.isEndRecordAtUnbounded()) {

mli.addString ("till" +

pr.getEndsRecordAtCalendar().get (java.util. Calendar.YEAR) +"." +

pr.getEndsRecordAtCalendar().get (java.util. Calendar.MONTH) +"." +

pr.getEndsRecordAtCalendar().get (java.util. Calendar.DAY_OF_MONTH) + " " +

pr.getEndsRecordAtCalendar().get (java.util. Calendar.HOUR_OF_DAY) +":" +

pr.getEndsRecordAtCalendar().get (java.util. Calendar.MINUTE));

}

if (! pr.isStartRecordFromUnbounded() ||! pr.isEndRecordAtUnbounded()) {

if (pr.isScheduleIsActive()) {

mli.addString ("Active");

} else {

mli.addString ("Disabled");

}

}

addComponent(mli);

mli = new MylistItem (MainMenuConstatns.TRANSLATE_VIDEO, "Translate video");

addComponent(mli);

if (pr.getBTConnectionURL()!= "") {

mli.addString ("via bluetooth to "+pr.getBTFriendlyName());

}

if (pr.getSaveVideoToFile()!= "") {

mli.addString (pr.getSaveVideoToFile());

}

if (pr.getMovNotification()!= "") {

String msgType = (pr.isSendSMS()? "sms": "mms") +" to";

addComponent (new MylistItem (MainMenuConstatns.MOVEMENT_NOTIFICATION,

new String[] {"Movement notification", msgType

+ pr.getMovNotification()}));