Автор работы: Пользователь скрыл имя, 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 Алгоритм обнаружения движения
Заключение
Список источников
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_
new String[] {"Movement notification", msgType
+ pr.getMovNotification()}));
} else {
addComponent (new MylistItem (MainMenuConstatns.MOVEMENT_
"Movement notification"));
}
if (pr.getErrNotificationNumber()
addComponent (new MylistItem (MainMenuConstatns.ERROR_
new String[] {"Error Notification",
pr.getErrNotificationNumber()}
} else {
addComponent (new MylistItem (MainMenuConstatns.ERROR_
"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().
break;
case
MainMenuConstatns.TRANSLATE_
midlet.
break;
case
MainMenuConstatns.MOVEMENT_
midlet.
break;
case MainMenuConstatns.CAMERA:
midlet.getCamera().show();
midlet.getCamera().
midlet.getCamera().revalidate(
break;
case MainMenuConstatns.EXIT:
midlet.exitMIDlet();
break;
case MainMenuConstatns.HELP:
midlet.getHelpScreen().show();
break;
case
MainMenuConstatns.ERROR_
midlet.getErrorNotification().
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(
addComponent (3, dateFrom);
revalidate();
return;
}
}
}
if (cmp == rbDateFromUnbounded) {
if (getContentPane().contains(
removeComponent(dateFrom);
revalidate();
return;
}
}
if (cmp == rbDateToEnter) {
if (rbDateToEnter.isSelected()) {
if (! getContentPane().contains(
addComponent (getContentPane().
dateTo.setFocus(true);
revalidate();
return;
}
}
}
if (cmp == rbDateToUnbounded) {
if (getContentPane().contains(
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().
} else {
style = UIManager.getInstance().
}
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-
Далее приводится программный код (листинг 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(
remoteDevice.getFriendlyName(
devicesFound.addElement(
} 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(
getStopSearchDevices());
midlet.getSelectDeviceDisplay(
getBackSelectDevice());
switch (param) {
case
DiscoveryListener.INQUIRY_
if (devicesFound.size() > 0) {
midlet.getSelectDeviceDisplay(
midlet.getSelectDeviceDisplay(
midlet.getSelectDeviceDisplay(
midlet.getSelectDeviceDisplay(
doServiceSearch((RemoteDevice) devicesFound.elementAt(0));
} else
break;
case
DiscoveryListener.INQUIRY_
//Error during inquiry
break;
case
DiscoveryListener.INQUIRY_
// 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 – Завершение поиска сервисов
/**
* 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_
Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_COMPLETED");
if (servicesFound.length > 0) {
midlet.getSelectDeviceDisplay(
midlet.getSelectDeviceDisplay(
}
/*
* 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_
Log.out.println ("serviceSearchCompleted:
SERVICE_SEARCH_DEVICE_NOT_
break;
case
DiscoveryListener.SERVICE_
Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_ERROR");
break;
case
DiscoveryListener.SERVICE_
Log.out.println ("serviceSearchCompleted: SERVICE_SEARCH_NO_RECORDS");
break;
case
DiscoveryListener.SERVICE_
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].
ServiceRecord.NOAUTHENTICATE_
false);
} else {
return null;
}