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

Автор работы: Пользователь скрыл имя, 01 Июня 2013 в 19:30, дипломная работа

Краткое описание

В дипломной работе освещены теоретические основы платформы J2ME, архитектуры Bluetooth и обработка видеоданных для обнаружения движения. Разработано приложение на платформе J2ME, которое позволяет осуществлять видеонаблюдение. В нем используются такие ресурсы мобильного телефона как файловая система, камера, Bluetooth, отправка SMS и MMS-сообщений. Изучена библиотека LWUIT, применяемая для построения графического интерфейса.

Содержание

Введение
1. Обзор литературы
2. Платформа J2ME
2.1 Основные понятия
2.2 Библиотека LWUIT
2.3 Bluetooth
3. Проектирование приложения для мобильного телефона на основе платформы J2ME
3.1 Постановка задачи
3.2 Построение интерфейса
3.3 Передача данных по Bluetooth
3.4 Работа с файловой системой телефона
3.5 Отправка SMS и MMS-сообщений
3.6 Алгоритм обнаружения движения
Заключение
Список источников

Прикрепленные файлы: 1 файл

j2me.doc

— 1.18 Мб (Скачать документ)

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()}));

} else {

addComponent (new MylistItem (MainMenuConstatns.MOVEMENT_NOTIFICATION,

"Movement notification"));

}

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

addComponent (new MylistItem (MainMenuConstatns.ERROR_NOTIFICATION,

new String[] {"Error Notification", pr.getErrNotificationNumber()}));

} else {

addComponent (new MylistItem (MainMenuConstatns.ERROR_NOTIFICATION,

"Error Notification"));

}

addComponent (new MylistItem (MainMenuConstatns.CAMERA, "Camera"));

addComponent (new MylistItem (MainMenuConstatns.EXIT, "Exit"));

addComponent (new MylistItem (MainMenuConstatns.HELP, "Help"));

Обработка нажатия пользователем  кнопок и определение, какая экранная форма должна быть показана далее, выполняется так, как показано в следующем листинге 3.6.

 

Листинг 3.6 – Обработка нажатий кнопок для главного меню

class MainMenuActionListener implements ActionListener {

public void actionPerformed (ActionEvent act) {

Component cmp = getFocused();

if (cmp instanceof MylistItem) {

int id = ((MylistItem) cmp).getId();

switch (id) {

case MainMenuConstatns.SCHEDULE:

midlet.getScheduleDisplay().show();

break;

case MainMenuConstatns.TRANSLATE_VIDEO:

midlet.getVideoTransmitionDisplay().show();

break;

case MainMenuConstatns.MOVEMENT_NOTIFICATION:

midlet.getMovementNotificationDisplay().show();

break;

case MainMenuConstatns.CAMERA:

midlet.getCamera().show();

midlet.getCamera().startCamera();

midlet.getCamera().revalidate();

break;

case MainMenuConstatns.EXIT:

midlet.exitMIDlet();

break;

case MainMenuConstatns.HELP:

midlet.getHelpScreen().show();

break;

case MainMenuConstatns.ERROR_NOTIFICATION:

midlet.getErrorNotification().show();

break;

}

}

}

На форме настройки расписания (рисунок 3.3) необходимо было реализовать динамическое скрытие / отображение некоторых элементов, а именно: когда выбирается радиокнопка enter time, то должны сразу под ней отобразиться поля для ввода часов, минут, дня, месяца, года. А при выборе радиокнопки unbounded эти поля должны быть скрыты.

 

Рисунок 3.3 – Заполнение расписания работы камеры

 

Такая функциональность реализуется  путем указания у каждой радиокнопки ActionListener, который отслеживает выбор радиокнопок (листинг 3.7). dateFrom и dateTo являются контейнерами типа Container и содержат все необходимые поля для указания точной даты и времени.

 

Листинг 3.7 – Обработка выбора радиокнопок

public void actionPerformed (ActionEvent evt) {

Component cmp = (Component) evt.getSource();

if (cmp == rb1DateFromEnter) {

if (rb1DateFromEnter.isSelected()) {

if (! getContentPane().contains(dateFrom)) {

addComponent (3, dateFrom);

revalidate();

return;

}

}

}

if (cmp == rbDateFromUnbounded) {

if (getContentPane().contains(dateFrom)) {

removeComponent(dateFrom);

revalidate();

return;

}

}

if (cmp == rbDateToEnter) {

if (rbDateToEnter.isSelected()) {

if (! getContentPane().contains(dateTo)) {

addComponent (getContentPane().getComponentCount() – 2, dateTo);

dateTo.setFocus(true);

revalidate();

return;

}

}

}

if (cmp == rbDateToUnbounded) {

if (getContentPane().contains(dateTo)) {

removeComponent(dateTo);

revalidate();

return;

}

}

}

 

 

Рисунок 3.4 – Экранная форма со списком

 

Для всех списков в данном приложении разработан специальный способ их отображения – класс MyListCellRenderer. По умолчанию для отображения списков применяется DefaultListCellRenderer, который просто преобразовывает все элементы к объектам класса Label. Для создания своего способа отображения элементов списка необходимо реализовать интерфейс ListCellRenderer.

Метод getListCellRendererComponent этого интерфейса должен возвращать отображаемый элемент списка из объекта, передаваемого ему в качестве параметра. Переопределение методов getListFocusComponent обеспечивает возможность настройки стилей отображения выделенного и невыделенного элемента списка.

Пример списка, реализованного с  помощью MyListCellRenderer, приведен на рисунке 3.4. В листинге 3.8 приведен программный код класса, который прорисовывает список.

 

Листинг 3.8 – Прорисовка списка

public class MyListCellRenderer extends Container implements ListCellRenderer {

public MyListCellRenderer() {

setLayout (new BoxLayout (BoxLayout.Y_AXIS));

}

/**

* Returns displayable list element from received object

*/

public Component getListCellRendererComponent (List list, Object value,

int index, boolean isSelected) {

if (value instanceof String) {

setText((String) value);

} else {

setText (value.toString());

}

setFocus(isSelected);

applyStyle (this, isSelected);

return this;

}

/**

* Applies style for selected and unselected element

*/

private void applyStyle (Component component, boolean isSelected) {

Style style = null;

if (isSelected) {

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

} else {

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

}

component.setStyle(style);

}

public Component getListFocusComponent (List list) {

return null;

}

}

3.3 Передача данных по Bluetooth

 

API для работы с Bluetooth содержится в пакете JSR-82 [9]. Эта библиотека состоит из двух пакетов: базовое Bluetooth API и OBEX.

Для работы с Bluetooth у телефона должны быть минимум 512 килобайт памяти, а также поддерживаться CLDC.

Чтобы приложение могло использовать возможности Bluetooth, необходимо реализовать интерфейс DiscoveryListener и его методы deviceDiscovered(), inquiryCompleted(), servicesDiscovered(), serviceSearchCompleted(), используемые для обнаружения рядом находящихся Bluetooth-устройств.

Далее приводится программный код (листинг 3.9), который инициирует поиск. Вначале инициализируется переменная LocalDevice local, которая представляет собой данный телефон; потом инициализируется переменная DiscoveryAgent agent. Именно этот объект запускает поиск методом startInquiry() с параметрами DiscoveryAgent.GIAC и ссылкой на объект, который реализовал интерфейс DiscoveryListener и будет обрабатывать все события, связанные с обнаружением устройств и их сервисов. Этот метод возвращает true, если поиск устройств был успешно начат, или false в противном случае.

Переменная Vector devicesFound используется для сохранения всех обнаруженных устройств.

 

Листинг 3.9 – Начало поиска устройств

* This method starts device discovering

*/

public void doDeviceDiscovery() {

try {

local = LocalDevice.getLocalDevice();

} catch (BluetoothStateException bse) {

Log.out.println ("EXCEPTION!" + bse.toString());

}

agent = local.getDiscoveryAgent();

devicesFound = new Vector();

try {

if (! agent.startInquiry (DiscoveryAgent.GIAC, this)) {

Log.out.println (" DISCOVERING IS NOT STARTED");

}

} catch (BluetoothStateException bse) {

Log.out.println (" BluetoothStateException "+ bse.toString());

}

}

При обнаружении Bluetooth-устройства вызывается метод deviceDiscovered(), который получает в качестве параметров найденное устройство remoteDevice и его тип deviceClass.

Далее приводится программный код (листинг 3.10) этого метода. В методе выполняется добавление в список, отображаемый на экране, доступных рядом находящихся Bluetooth-устройств. Найденное устройство также добавляется в массив devicesFound.

 

Листинг 3.10 – Обработка события, связанного с обнаружением нового устройства

/**

* Called when a device is discovered during device discovery

* @param remoteDevice founded device

* @param deviceClass

public void deviceDiscovered (RemoteDevice remoteDevice,

DeviceClass deviceClass) {

try {

midlet.getSelectDeviceDisplay().getDevicesList().addItem (

remoteDevice.getFriendlyName(false));

devicesFound.addElement(remoteDevice);

} catch (IOException ex) {

Log.out.println ("ex when device has been discovered "+ex.toString());

}

}

После окончания поиска всех устройств  вызывается метод inquiryCompleted(), в параметре которого содержится код результата поиска. Далее приводится этот метод (листинг 3.11).

 

Листинг 3.11 – Завершение поиска устройств

/**

* Called when device discovering is complete

* @param – param discovering status

public void inquiryCompleted (int param) {

midlet.getSelectDeviceDisplay().removeCommand (midlet.getSelectDeviceDisplay().

getStopSearchDevices());

midlet.getSelectDeviceDisplay().addCommand (midlet.getSelectDeviceDisplay().

getBackSelectDevice());

switch (param) {

case DiscoveryListener.INQUIRY_COMPLETED:

if (devicesFound.size() > 0) {

midlet.getSelectDeviceDisplay().removeCommand (

midlet.getSelectDeviceDisplay().getStopSearchDevices());

midlet.getSelectDeviceDisplay().addCommand (

midlet.getSelectDeviceDisplay().getBackSelectDevice());

doServiceSearch((RemoteDevice) devicesFound.elementAt(0));

} else

break;

case DiscoveryListener.INQUIRY_ERROR: 

//Error during inquiry

break;

case DiscoveryListener.INQUIRY_TERMINATED: 

// Inquiry terminated by agent.cancelInquiry()

break;

}

}

 

Рисунок 3.5 – Список найденных устройств

 

После поиска устройств (на рисунке 3.5 показан список обнаруженных устройств) начинается поиск сервисов на одном из них. Найденные сервисы запоминаются в массиве ServiceRecord[] servicesFound. В следующем листинге 3.12 приводится метод, который начинает поиск сервисов. Для начала поиска вызывается метод searchServices() ранее созданного объекта DiscoveryAgent agent, которому передаются следующие параметры: атрибуты искомого сервиса или его UUID, удаленное устройство, на котором производить поиск, а также ссылка на объект, который будет обрабатывать все события, связанные с обнаружением сервисов.

 

Листинг 3.12 – Инициация поиска сервисов

/**

* This method starts service search on the divice

* @param device to be scanned for services

public void doServiceSearch (RemoteDevice device) {

* Service search will always give the default attributes:

* ServiceRecordHandle (0x0000), ServiceClassIDList (0x0001),

* ServiceRecordState (0x0002), ServiceID (0x0003) and

* ProtocolDescriptorList (0x004).

* These hex-values must be supplied through an int array

*/

int[] attributes = null; // {0x100};

/*

* Supplying UUIDs in an UUID array enables searching for

* specific services.

UUID[] uuids = new UUID[1];

uuids[0] = new UUID(0x0003);

try {

agent.searchServices (attributes, uuids, device, this);

} catch (BluetoothStateException e) {

Log.out.println ("BluetoothStateException error" + e.getMessage());

}

}

Когда поиск сервисов завершен, вызывается метод serviceSearchCompleted(), код которого приведен ниже (листинг 3.13). В параметре данного метода содержится код результата поиска сервисов.

 

Листинг 3.13 – Завершение поиска сервисов

/**

* Called when service search completes

* @param transID identifies a particular service search

* @param respCode indicates why the service search is ended

*/

public void serviceSearchCompleted (int transID, int respCode) {

switch (respCode) {

case DiscoveryListener.SERVICE_SEARCH_COMPLETED:

Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_COMPLETED");

if (servicesFound.length > 0) {

midlet.getSelectDeviceDisplay().addCommand (

midlet.getSelectDeviceDisplay().getSelectDeviceCommand());

}

/*

* The service to connect to has been found earlier

* (by service discovery) and the service record is

* referencedthrough the object named: service (of type

* ServiceRecord)

*/

break;

case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:

Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_DEVICE_NOT_REACHABLE");

break;

case DiscoveryListener.SERVICE_SEARCH_ERROR:

Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_ERROR");

break;

case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:

Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_NO_RECORDS");

break;

case DiscoveryListener.SERVICE_SEARCH_TERMINATED:

Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_TERMINATED");

break;

}

}

Когда среди обнаруженных устройств  выбрано одно и выполнен на нем  поиск сервисов, то можно осуществить передачу данных по Bluetooth. Передача осуществляется через StreamConnection, URL которого получается с помощью следующего метода (листинг 3.14).

 

Листинг 3.14 – Получение URL для доступа к сервису

public String getServiceConnectionURL (int nom) {

if (nom < servicesFound.length) {

return servicesFound[nom].getConnectionURL (

ServiceRecord.NOAUTHENTICATE_NOENCRYPT,

false);

} else {

return null;

}

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