Мобильное приложение для оценки эффективности мерчендайзинга торговой компании

Системное и функциональное проектирование. Описание взаимодействия с сервером, классов системных компонентов. Обзор функциональных классов из пакетов helpers, dialogs и networking. Разработка программных модулей. Технико-экономическое обоснование проекта.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 15.06.2014
Размер файла 1,7 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

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

public class FakeWebClient implements IWebClient {

@Override

public String logIn(String login, String password) {

return "user";

}

@Override

public List<StoreEntity> updateCache(int version) {

return null;

}

@Override

public String uploadPicture(byte[] picture) {

try {

FileOutputStream out =

new FileOutputStream(String.format(

"/storage/extSdCard/X/screen%d.jpg",

Calendar.getInstance().getTimeInMillis()));

out.write(picture);

out.close();

} catch (Exception e) {

e.printStackTrace();

}

return "some_random_generated_id";

}

@Override

public boolean sendMetadata(Metadata data) {

return true;

}

Данная версия вместо отправки фото на сервер, сохраняет его на SD-карту телефона для проверки качества получаемых фотографий.

Помимо нескольких классов, наподобие Fake Web Client, которые использовались для проверки остальных веб-методов, следует отметить класс Location Helper, содержащий несколько методов для симуляции ошибочных ситуаций. В качестве примера, ниже приведён листинг метода emulate Location Error, имитирующего помехи в работе GPS и возвращающего геокоординаты каждый третий запрос:

public static void emulateLocationError(

final Context context,

final PendingIntent pendingIntent) {

counter++;

if (counter > 2) {

counter = 0;

getLocation(context, pendingIntent);

return;

}

final Looper myLooper = Looper.myLooper();

final Handler handler = new Handler(myLooper);

handler.postDelayed(new Runnable() {

public void run() {

reportError(context, pendingIntent);

}

}, TIMEOUT - 3000);

Таким образом, несмотря на отсутствие unit- и monkey- тестов, в проекте были созданы условия для довольно информативного, хоть и не автоматизированного тестирования. Кроме этого итоговый продукт был протестирован на достаточно большом количестве конфигураций, как виртуальных, так и физических.

6. Руководство пользователя

Поскольку разрабатываемое приложение ориентировано на использование исключительно в рамках компании-заказчика, было принято решение не размещать его в магазине приложений Google Play, а распространять в виде установочного.apk файла.

Приложение не требовательно к ресурсам и способно работать на всех современных моделях телефонов. Единственным обязательным требованием является наличие задней камеры. Кроме этого, для того, чтобы воспользоваться всеми функциями приложения, требуется наличие GPS, а также камеры с автофокусом и вспышкой. Минимальная версия ОС Android - 4.0, «Ice Cream Sandwich».

При первом запуске приложение попросит указать адрес сервера для хранения фотографий (рисунок 6.1).

а) б)

Рисунок 6.1 - Первый запуск приложения: а - всплывающее окно; б - страница настроек

Помимо адреса сервера, страница настроек позволяет отменить получение координат при сохранении фотографии для ускорения загрузки.

После первоначального запуска, страница настроек доступна через контекстное меню на странице авторизации.

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

Рисунок 6.2 - Страница авторизации

При успешной авторизации, пользователь попадает на страницу взаимодействия с камерой (рисунок 6.3). При помощи кнопок в верхнем правом углу, пользователь может изменить разрешение снимка, а также установить режим вспышки. Кнопка в верхнем левом углу позволяет выйти из аккаунта, а кнопка в нижней части экрана - сделать снимок. После получения фото, в нижней части появляется панель с кнопками «Отмена» и «Далее», которая позволяет принять снимок или сделать повторный. После получения удовлетворительного изображения, следует нажать на кнопку «Далее», которая откроет страницу сохранения фото.

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

а)

б) в)

Рисунок 6.3 -Камера: а - общий вид; б - меню выбор разрешения; в - подтверждение сохранения снимка

После заполнения всех полей необходимо нажать кнопку «Отправить» внизу страницы или же воспользоваться её аналогом в правом верхнем углу экрана. Дальнейший процесс отправки фото представлен на рисунке 6.4. При успешном завершении загрузки, появится всплывающее окно с сообщение об окончании и кнопкой «ОК», нажатие на которую возвращает на страницу камеры.

а) б)

в) г)

Рисунок 6.4 - Страница метаданых: а - общий вид; б - загрузка фото; в - получение координат; г - завершение сохранения

7. Технико-экономическое обоснование проекта Equation Section 7

7.1 Описание проекта

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

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

Таким образом, положительный экономический эффект у заказчика может быть получен вследствие:

1. Уменьшения излишнего документооборота (снижения затрат на расходные материалы и уменьшения трудоёмкости составления отчётов).

2. Мониторинга динамики продаж в зависимости от проводимых маркетинговых акций и мерчендайзиноговой политики.

3. Мониторинга работы сотрудников с целью улучшения качественного показателя кадрового состава.

7.2 Расчет сметы затрат и цены ПО

Разрабатываемый программный модуль относится к третьей категории сложности, поскольку не относится к ПО, планирующемуся к использованию под нагрузкой, либо в различных наукоёмких или требующих оптимизации системах. Однако, дополнительный коэффициент сложности выше единицы и равен 1,06 за счёт наличия интерактивного интерфейса. Программный модуль является ПО общего назначения и относится к категории новизны В (КН = 0,7). С большой долей уверенности можно сказать о наличии схожих систем у других компаний.

При разработке модуля используются существующие технологии и средства разработки, которые охватывают около 20 - 40% реализуемых функций, поэтому коэффициент использования стандартных модулей принимается равным 0,7.

Отправной точкой для расчёта плановой сметы затрат на разработку ПО, требуется определить общий объем программного продукта (VО). В качестве единицы измерения примем количество строк исходного кода (Lines of Code, LOC). Прогнозируемый общий объём ПО определяется по каталогу функций. Каталог функций данного программного модуля представлен в таблице 7.1.

Таблица 7.1 - Каталог функций ПО

Код функции

Наименование (содержание) функции

Объем функций (LOC)

101

Организация ввода информации

150

102

Контроль, предварительная обработка информации

450

109

Организация ввода/вывода информации в интерактивном режиме

320

201

Генерация структуры базы данных

4300

208

Организация поиска и поиск в базе данных

5480

305

Обработка файлов

720

506

Обработка ошибочых и сбойных ситуаций

410

507

Обеспечение интерфейса между компонентами

970

-

Общий объём (VО)

12800

На основе общего объёма и категории сложности ПО определяется нормативная трудоёмкость, которая, в данном случае, для VО = 12800 и третьей категории сложности, составит ТН = 260.

Исходя из нормативной трудоёмкости можно определить общую трудоёмкость ТО:

где КС - дополнительный коэффициент сложности;

КТ - коэффициент использования типовых программ и модулей;

КН - коэффициент новизны.

Подставив значения в формулу 7.1, получим:

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

Для определения срока разработки проекта, необходимо рассчитать эффективный фонд времени одного работника (ФЭФ):

где ДГ - количество дней в году;

ДП - количество праздничных дней в году;

ДВ - количество выходных дней в году;

ДО - количество дней отпуска.

Таким образом, по формуле 7.2 фонд эффективного времени составит:

Срок разработки проекта (ТР) определяется по формуле:

где ЧР - численность исполнителей проекта;

ТО - общая трудоемкость разработки проекта;

ТР - срок разработки проекта;

ФЭФ - эффективный фонд времени работы одного работника.

Подставив значения в формулу 7.3, получим:

При планировании сложных задач с длительным периодом разработки, трудоемкость определяется как сумма трудоёмкостей отдельных стадий разработки ПО: техническое задание (ТЗ), эскизный проект (ЭП), технический проект (ТП), рабочий проект (РП), внедрение (ВН). При этом трудоемкость отличается в зависимости от стадий. Общая формула для расчёта трудоемкости на разных стадиях имеет вид:

где ТСТ - трудоемкость изготовления ПО на данной стадии;

ТН - нормативная трудоемкость;

КС - коэффициент сложности изготовления ПО на выбранной стадии;

dСТ - удельный вес трудоемкости выбранной стадии разработки ПО;

КН - коэффициент новизны ПО на выбранной стадии.

При этом на «Рабочий проект» полученное значение трудоемкости изготовления ПО дополнительно умножается на КТ. Результаты расчетов трудоемкости по стадиям представлены в таблице 7.2.

Таблица 7.2 - Расчет трудоемкости разработки ПО с учётом стадий

Показатели

Стадии

Итого

ТЗ

ЭП

ТП

РП

ВН

Удельных веса трудоемкости стадии разработки (dСТ)

0,09

0,07

0,07

0,61

0,16

1,00

Коэффициент сложности (КС)

1,06

1,06

1,06

1,06

1,06

-

Коэффициент стандартных модулей (КТ)

-

-

-

0,8

-

-

Коэффициент новизны (КН)

0,7

0,7

0,7

0,7

0,7

-

Трудоемкость (ТСТ), чел./дн.

17,36

13,5

13,5

94,15

30,9

169,38

На основе уточнённого значения трудоёмкости заново рассчитаем срок разработки проекта используя формулу 7.3:

Основой для расчёта сметы затрат является основная заработная плата (ЗП) разработчиков проекта. В данном случае имеется один работник - инженер-программист 1-й категории (тарифный разряд - 12, тарифный коэффициент - 2,84). Месячная ставка исполнителя (ТМ) определяется через действующую ставку тарифного разряда и тарифный коэффициент:

где ТМ1 - месячная тарифная ставка первого разряда на момент составления сметы (конец 2013 года) в тысячах рублей;

ТК - тарифный коэффициент.

Месячная ставка, определённая по формуле 7.5, составит:

Исходя из месячной тарифной ставки рассчитывается часовая:

где ТЧ - часовая тарифная ставка (тыс. руб.);

ФР - среднемесячная норма рабочего времени в часах (170 часов).

При подстановке значений в формулу 7.6, получим:

Основная заработная плата исполнителей рассчитывается по формуле:

где n - количество исполнителей;

ТЧi - часовая тарифная ставка -го исполнителя (тыс. руб.);

ТЧ - количество часов работы в день, ч;

К - коэффициент премирования, принятый 1,4;

ФП - плановый фонд рабочего времени i-го исполнителя (дн.).

Учитывая число разработчиков n = 1, определим основную заработную плату по формуле 7.7:

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

где НД - норматив дополнительной заработной платы (15%).

Отчисления в фонды социальной защиты и социального страхования определяются по следующим формулам:

где НСЗ - норматив отчислений в фонд социальной защиты наделения;

НСС - норматив отчислений в фонд социального страхования.

Отчисления в фонд социальной защиты - 34%, отчисления в фонд социального страхования - 0,6%. Исходя из этого, по формулам 7.9 и 7.10, получаем:

Расходы по статье «Материалы» отражают расходы на бумагу, тонер и прочие вещи, необходимые для разработки ПО. Нормы расхода материалов в суммарном выражении определяются в расчете на 100 строк исходного кода. Сумма затрат на расходные материалы определяется по формуле:

где НМ - норма расхода материалов в расчете на 100 строк исходного кода ПО равная 3% от ЗО, то есть 247 руб./100 строк;

VO - общий объем ПО (строк исходного кода).

Подставив значения в формулу 7.11, получим:

Расходы по статье «Машинное время» включает оплату машинного времени, необходимого для разработки и отладки ПО и определяются по формуле:

где НРМ - цена одного машино-часа (тыс. руб.);

ТО - общее время работы над проектом (часов).

Расходы по статье «Научные командировки» определяются по формуле:

где ННК - норматив расходов на командировки по организации (15%).

Расходы по статье «Прочие затраты» включают затраты на приобретение и подготовку специальной научно-технической информации и специальной литературы. Определяется по формуле:

где НПЗ - норматив прочих затрат в целом по организации.

Затраты по статье «Накладные расходы» (РН) связаны с необходимостью содержания аппарата управления, вспомогательных хозяйств и опытных производств. Определяются по формуле:

где НРН - норматив накладных расходов в целом по организации.

Общая сумма расходов по смете (СП) определяется как сумма выше рассчитанных показателей:

Подставив рассчитанные ранее значения в формулу 7.16, получим:

Прогнозируемая прибыль от создаваемого ПО определяется как:

где УР - уровень рентабельности ПО (15%).

На основе прогнозируемой прибыли определяется прогнозируемая цена ПО без налогов:

Подставляя значения в формулу 7.18, получим:

При расчёте отпускной цены дополнительно учитывается налог на добавочную стоимость (НДС):

где НДС - ставка НДС равная 20%.

По формуле 7.19 налог на добавочную стоимость равен:

Таким образом, с учётом НДС, отпускная цена рассчитывается как:

Подставив значения в формулу 7.20, получим:

В дополнение к выше рассчитанным параметрам, определяются расходы на сопровождение (РС) и освоение (РО) ПО:

где НС - норматив расходов на сопровождение ПО (20%);

НО - норматив расходов на освоение ПО (10%).

Используя формулы 7.21 и 7.22, определим значения расходов:

Все выше рассчитанные параметры, а также результирующие показатели сведены в таблицу 7.3.

Таблица 7.3 - Расчёт себестоимости и отпускной цены.

Наименование статьи

Норматив

Формула расчёта

Значение, тыс. руб.

Основная ЗП

-

8240,101

Дополнительная ЗП

НД =15%

1236,015

Отчисления в фонд соцзащиты

НСЗ =34%

3222

Отчисления в фонд соцстраха

НСС =0,6%

56,86

Материалы и комплектующие

НМ =247 руб/100 стр

31642

Машинное время

НРМ =2500 руб/ч

5239,4

Научные командировки

ННК =15%

1236,015

Прочие затраты

НПЗ =20%

1648,02

Накладные расходы

НРН =30%

2472,03

Общая сумма по смете

-

54992,32

Прогнозируемая прибыль

УР =25%

13748,08

Прогнозируемая цена без налогов

-

68740,4

НДС

НДС =20%

14540,37

Отпускная цена

-

82488,5

Сопровождение ПО

НС =20%

10998,5

Освоение ПО

НО =10%

5499,23

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

где П - чистая прибыль;

ППС - прогнозируемая прибыль (тыс. руб.);

НП - налог на прибыль (24%).

Подставив значения в формулу 7.23, определим чистую прибыль:

Анализируя полученные данные, можно подвести итоги финансовой оценки проекта со стороны разработчика:

- себестоимость проекта составила 55 миллионов рублей;

- прогнозируемая отпускная цена - 82,5 миллионов рублей;

- чистая прибыль разработчика составит 10,5 миллионов рублей.

Для определения экономического эффекта от использования нового ПО у потребителя необходимо произвести сравнение полученного ПО с некоторым базовым, имеющимся на текущий момент вариантом. К сожалению, подобные данные не могут быть получены в связи с проводимой компанией-заказчиком политикой безопасности. Исходя из этого расчет экономического эффекта невозможен.

С большой вероятностью можно предположить, что до внедрения разрабатываемой системы, компания-заказчик не использовала схожих решений. В таком случае, можно сказать, что причина экономического эффекта будет аналогичной таковой при переходе с бумажного документооборота на электронный. Кроме этого не стоит забывать, что дополнительный положительный эффект может создаться за счёт пересмотра кадрового состава на основе анализа производимой конкретными сотрудниками работы.

8. Обеспечение пожарной безопасности на ЗАО «Итранзишэн»

В настоящем разделе рассмотрим вопросы обеспечения пожарной безопасности на ЗАО «Итранзишэн». Пожарная безопасность на данном предприятии организуется посредствам функционирования двух систем: автоматизированной системы пожарной сигнализации (ПС) и системы оповещения о пожаре (СО).

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

Спроектированные системы ПС и СО предназначены для:

- обнаружения первичных факторов пожара (дым, тепло), в контролируемых помещениях здания;

- отображения информации о работоспособности и неисправности установки;

- формирования команд на включение системы оповещения о пожаре;

- сообщения людям информации о возникновении пожара и путях эвакуации.

В качестве приёмно-контрольного оборудования используется оборудование производства «Ровалэнт».

Центральной частью системы являются приборы приёмно-контрольные охранно-пожарные «А16-512». Прибор предназначен для контроля 16 шлейфов пожарной сигнализации, с соответствующей индикацией состояния на выносной панели управления ВПУ-А16, и выдачи сигналов о пожаре на технические средства оповещения. К прибору подключаются модули расширения АР-16 (до 2-х шт.), каждый модуль расширения также осуществляет контроль 16-ти шлейфов сигнализации. Приборы А16-512, выносная панель ВПУ-А16 и модули расширения АР-16 объединяются в единую систему с помощью контроллера КСО-А по интерфейсу RS-485 Программирование системы, и управление осуществляется с помощью клавиатуры ВПУ-А16.

На предприятии ЗАО «Итранзишэн» установлены два прибора А16-512, объединённые в единую систему посредством контроллера КСО-А. Контроллер отвечает за организацию, сбор данных и отображение информации о состоянии системы, а также программирование конфигурации сети. Каждый из приборов А16-512 имеет по одному модулю расширения АР-16 (структура системы ПС приведена на рисунке 8.1).

Рисунок 8.1 - Структурная схема системы ПС

Каждый прибор осуществляет управление шлейфами пожарной сигнализации с включенными в них:

- тепловыми извещателями нормально-замкнутыми ИП 101-01 А2М;

- дымовыми пожарными извещателями ИП212-5МУ;

- ручными пожарными извещателями ИП5-2Р.

Шлейфы с дымовыми извещателями запрограммированы, как «Пожарный дымовой двухпроводный» со сбросом после верификации. В данном режиме, при срабатывании извещателя прибор с помощью реле сброса снимает напряжение в шлейфе (на 4 секунды), сбрасывая извещатель в состояние «Норма», и выдает извещение «Внимание». При повторном срабатывании любого извещателя в этом же шлейфе, в течение запрограммированного времени верификации, прибор выдает извещение «Пожар».

Тепловые шлейфы прибора запрограммированы как «Пожарный на 4 состояния». В данный шлейф включены пожарные извещатели нормально замкнутыми контактами (тепловые), к параллельным контактам которых установлены шунтирующие сопротивления 1.5 кОм. В данном режиме, при срабатывании извещателя прибор выдает извещение «Внимание» и ожидает в течение запрограммированного времени верификации срабатывания второго извещателя этого же шлейфа.

Релейный модуль РМ-64 устанавливается в контроллер КСО-А и служит для автоматического включения системы оповещения, передачи сигналов на УОО «Молния и ряда других функций. В проекте предусмотрено управление системой оповещении о пожаре в автоматическом режиме, в зависимости от сработавшего шлейфа, сигнализации и зоны срабатывания, а также управлением вентиляцией в случае пожара (отключение приточной и вытяжной вентиляции).

К выходам РМ-64, подключено устройство оповещения (УО) «Молния». УО предназначено для автоматического вызова спасательной пожарной бригады. После срабатывания УО у контролёра прибора А16-512 есть не более трёх минут для отмены вызова, в случае ложного срабатывания системы.

Выносная панель управления ВПУ-А-16 предназначена для работы в составе прибора А16-512 и процессорного модуля КСО-А и служит для индикации общего состояния системы, шлейфов сигнализации и линий технических средств оповещения. С помощью клавиатуры ВПУ-А-16 осуществляется постановка под охрану и снятие с охраны зон путем предъявления ключей пользователей, сброс тревог, программирование конфигурации прибора или конфигурации любого прибора, подключенного к модулю процессорному КСО-А Клавиатура ВПУ-А-16 позволяет контролировать до 48-ми шлейфов сигнализации при подключении к плате управления прибора А16-512 и общее количество шлейфов сигнализации всех приборов, подключенных к модулю КСО-А.

Оповещение о пожаре для людей, находящихся в здании, предусмотрено с учетом объемно-планировочных решений и конструктивных особенностей здания.

Выбор типа системы оповещения (СО) принят с учетом функционального назначения здания, и, в соответствии с правилами СНБ 2.02.02-01, используется система оповещения людей о пожаре типа СО-2 производства ОДО «Авангардспецмонтаж».

Прибор управления (ПУ) предназначен для построения систем управления оповещением и эвакуацией типа СО-2 и обеспечивает выполнение следующих основных функций:

- управление светозвуковыми, световыми оповещателями и указателями;

- управление лампами аварийного освещения и устройствами разблокировки замков аварийных выходов;

- прием сигналов «Пожар» от приборов приемно-контрольных пожарных (ППКП);

- контроль исправности входных и выходных цепей;

- контроль удаленных источников питания;

- работу в ручном и автоматическом режиме.

ПУ предназначен для управления системами оповещения и эвакуации в шести независимых зонах. На предприятии выделено 4 зоны, соответствующие четырём этажам здания. В качестве оповещателей используются светозвуковые транспаранты АСТО-12С/1, световые транспаранты АСТО-12.

При поступлении сигнала «пожар» от реле прибора РМ-64 пожарной сигнализации, сначала производится включение оповещения и зоне, где непосредственно произошёл пожар. Потом с задержкой в 15 секунд производится оповещение в другую зону, расположенную на этом же этаже, и в то же время - на самый верхний этаж.

Прибор А16-512 установлен на первом этаже здания, на ресепшене. Извещатели установлены согласно требованиям ТКП 45-2.02-190-2010 «Пожарная автоматика зданий и сооружений. Строительные нормы проектирования». В каждом помещении установлено не менее двух извещателей. Ручные извещатели установлены на высоте менее человеческого роста, в легкодоступных местах на пути эвакуации.

Установка пожарной сигнализации является потребителем первой категории согласно ПУЭ и требует двух независимых источников питания: первый - от независимого щитка электропитания, а второй - от аккумуляторной батареи.

В качестве резервного источника электропитания системы оповещения применяется ИРПА124/1, который обеспечивает питание системы в дежурном режиме не менее суток, и в тревожном не менее часа.

Каждый из приборов А16-512 питается от аккумуляторной батареи ёмкостью 18А/ч, которая обеспечивает питание системы в дежурном режиме не менее суток и в тревожном - не менее трёх часов.

Все работы были произведены согласно правилам устройства электроустановок.

К обслуживанию установки допускаются лица, прошедшие инструктаж по технике безопасности. Происхождения инструктажа отмечается в соответствующем журнале.

Также инструктаж по пожарной безопасности производится со всеми сотрудниками в рамках инструктажа по технике безопасности. Сами инструктажи по ТБ производятся в соответствии с нормами охраны труда и отмечаются в специальном журнале.

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

На каждом этаже вывешены планы эвакуации с указанием на них маршрутов эвакуации, а также расположением средств пожаротушения.

Все системы для обеспечения пожаробезопасности были установлены сторонним предприятием-подрядчиком и принимались непосредственно комиссией МЧС, которая также производит периодические проверки соблюдения норм пожаробезопасности.

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

Заключение

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

Крупные компании заинтересованы в решениях, позволяющих снизить трудоёмкость операций по контролю за проведением маркетинговых акций, в чём им может помочь разработанное приложение. Очевидно, что переход на быструю, автоматизированную отчётность, совмещённую с основными обязанностями мерчендайзеров, снизит время и затраты, отводимые на контроль за выполнением работы сотрудниками компании.

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

системный класс программный пакет

Список литературы

[1] Eckel, B. Thinking in Java (4th Edition) / Bruce Eckel - Prentice Hall Ptr, 2006. - 1079 с.

[2] Java™ Platform, Standard Edition 7 API Specification [Электронный ресурс]. - Электронные данные. - Режим доступа: http://docs.oracle.com/javase/7/docs/api/.

[3] Android Application Architecture. Part I: Background [Электронный ресурс]. - Электронные данные. - Режим доступа: http://vladnevzorov.com/2011/04/18/android-application-architecture-part-i-background/.

[4] Android Developers [Электронный ресурс]. - Электронные данные. - Режим доступа: http://developer.android.com/develop/index.html.

[5] Meier, R. Professional Android 2 Application Development / Reto Meier - WROX, 2010. - 576 с.

[6] Android Service - Tutorial [Электронный ресурс]. - Электронные данные. - Режим доступа: http://www.vogella.com/tutorials/AndroidServices/article.html.

[7] Учебник о Android. Уроки для начинающих Tutorial [Электронный ресурс]. - Электронные данные. - Режим доступа: http://startandroid.ru/ru/uroki/vse-uroki-spiskom.html.

[8] Android Design Patterns [Электронный ресурс]. - Электронные данные. - Режим доступа: http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html.

[9] Харди, Б. Программирование под Android / Б. Харди, Б. Филлипс - СпБ: Питер, 2014. - 592 с.

[10] Welcome to Android Studio [Электронный ресурс]. - Электронные данные. - Режим доступа: http://tools.android.com/welcome-to-android-studio

[11] Gradle [Электронный ресурс]. - Электронные данные. - Режим доступа: http://www.gradle.org/.

[12] Gradle Plugin User Guide [Электронный ресурс]. - Электронные данные. - Режим доступа: http://tools.android.com/tech-docs/new-build-system/user-guide.

[13] SQLite Documentation [Электронный ресурс]. - Электронные данные. - Режим доступа: http://sqlite.org/docs.html.

[14] Newest `android' questions. Stackoverflow. [Электронный ресурс]. - Электронные данные. - Режим доступа: http://stackoverflow.com/questions/tagged/android.

Приложение А

Исходный текст класса LoginAtivity

public class LoginActivity

extends Activity

implements View.OnClickListener, TextWatcher,

TextView.OnEditorActionListener,

DialogInterface.OnClickListener {

public static final int ACTION_CODE_LOGIN = 100;

private static final String SAVE_CREDENTIALS_PROPERTY = "skip_login";

private static final String PROGRESS_DIALOG_TAG = "progress";

private static final String REPORT_DIALOG_TAG = "report";

private static final String REDIRECT_DIALOG_TAG = "redirect";

private EditText loginEditText = null;

private EditText passwordEditText = null;

private CheckBox saveCredentialsCheckBox = null;

private Button signinButton = null;

private boolean saveCredetials = false;

private ProgressDialogFragment progressDialog;

private SharedPreferences preferences;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_login);

progressDialog = (ProgressDialogFragment)getFragmentManager().

findFragmentByTag(PROGRESS_DIALOG_TAG);

loginEditText = (EditText)findViewById(R.id.loginEditText);

passwordEditText = (EditText)findViewById(R.id.passwordEditText);

saveCredentialsCheckBox = (CheckBox)findViewById(R.id.saveCredentialsCheckBox);

signinButton = (Button)findViewById(R.id.signinButton);

loginEditText.addTextChangedListener(this);

passwordEditText.addTextChangedListener(this);

passwordEditText.setOnEditorActionListener(this);

signinButton.setOnClickListener(this);

preferences = PreferenceManager.getDefaultSharedPreferences(this);

restoreProperties();

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

menu.

add(1, 1, 1, R.string.action_settings).

setIcon(R.drawable.ic_action_settings).

setIntent(new Intent(this, SettingsActivity.class));

return super.onCreateOptionsMenu(menu);

}

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.signinButton :

tryBeginAuthorizeUser();

break;

}

private void tryBeginAuthorizeUser() {

if (AccessibilityHelper.isNetworkingEnabled(this)) {

beginAuthorizeUser(

loginEditText.getText().toString(),

passwordEditText.getText().toString());

} else {

AccessibilityHelper.getNetworkDialog(this).show();

}

@Override

protected void onPause() {

savePreferences();

super.onPause();

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (resultCode == RESULT_OK) {

switch (requestCode) {

case ACTION_CODE_LOGIN :

endAuthorizeUser(data.getStringExtra(CommonConstants.ROLE_FIELD));

break;

}

} else {

progressDialog.dismiss();

String error = data.getStringExtra(CommonConstants.ERROR_FIELD);

if (WorkerService.HOST_NOT_SPECIFIED.equals(error)){

showRedirectDialog();

signinButton.setEnabled(true);

} else {

reportError(WorkerService.UNKNOWN_HOST.equals(error) ?

R.string.err_unknown_host : R.string.err_unknown);

}

private void navigateToCameraActivity() {

Intent intent = new Intent(this, CameraActivity.class);

intent.setFlags(

Intent.FLAG_ACTIVITY_CLEAR_TOP|

Intent.FLAG_ACTIVITY_CLEAR_TASK|

Intent.FLAG_ACTIVITY_NEW_TASK);

progressDialog.dismiss();

startActivity(intent);

}

//region TextWatcher implementation

@Override

public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

}

@Override

public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

}

@Override

public void afterTextChanged(Editable editable) {

signinButton.setEnabled(

!TextUtils.isEmpty(loginEditText.getText()) &&

!TextUtils.isEmpty(passwordEditText.getText()));

}

@Override

public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {

if (i == EditorInfo.IME_ACTION_DONE &&

signinButton.isEnabled()) {

InputMethodManager inputManager =

(InputMethodManager)this.getSystemService(INPUT_METHOD_SERVICE);

inputManager.hideSoftInputFromWindow(

textView.getWindowToken(),

InputMethodManager.HIDE_NOT_ALWAYS);

tryBeginAuthorizeUser();

}

return true;

}

//endregion

private void beginAuthorizeUser(String login, String password) {

signinButton.setEnabled(false);

progressDialog = new ProgressDialogFragment(

R.string.login_progress_title, R.string.login_progress_text);

progressDialog.show(getFragmentManager(), PROGRESS_DIALOG_TAG);

PendingIntent pending = createPendingResult(

ACTION_CODE_LOGIN,

new Intent(),

PendingIntent.FLAG_ONE_SHOT);

Intent intent = new Intent(this, WorkerService.class).

putExtra(CommonConstants.LOGIN_FIELD, login).

putExtra(CommonConstants.PASSWORD_FIELD, password).

putExtra(WorkerService.PENDING_INTENT_FIELD, pending);

intent.setAction(WorkerService.ACTION_LOGIN);

startService(intent);

}

private void endAuthorizeUser(String role) {

if (AuthorizationHelper.isValidRole(role)) {

navigateToCameraActivity();

} else {

reportError(AuthorizationHelper.AUTHORIZATION_ERROR.equals(role) ?

R.string.err_invalid_credentials : R.string.err_unknown);

}

}

private void reportError(int messageId) {

ReportDialogFragment reportDialog = new ReportDialogFragment(R.string.error, messageId);

reportDialog.show(getFragmentManager(), REPORT_DIALOG_TAG);

progressDialog.dismiss();

signinButton.setEnabled(true);

}

private void showRedirectDialog() {

new RedirectToSettingsDialogFragment()

.show(getFragmentManager(), REDIRECT_DIALOG_TAG);

}

@Override

public void onClick(DialogInterface dialogInterface, int i) {

dialogInterface.dismiss();

}

//region Work with preferences

private void restoreProperties() {

saveCredetials = preferences.getBoolean(SAVE_CREDENTIALS_PROPERTY, false);

saveCredentialsCheckBox.setChecked(saveCredetials);

if (saveCredetials) {

String login = preferences.getString(CommonConstants.LOGIN_FIELD, "");

String password = preferences.getString(CommonConstants.PASSWORD_FIELD, "");

loginEditText.setText(login);

passwordEditText.setText(password);

}

String hostName = PreferenceManager.

getDefaultSharedPreferences(this).

getString(CommonConstants.HOST_NAME_PROPERTY, null);

if (hostName == null || hostName.isEmpty()) {

showRedirectDialog();

}

private void savePreferences() {

saveCredetials = saveCredentialsCheckBox.isEnabled();

SharedPreferences.Editor editor = preferences.edit();

editor.putBoolean(SAVE_CREDENTIALS_PROPERTY, saveCredetials);

if (saveCredetials) {

editor.putString(CommonConstants.LOGIN_FIELD, loginEditText.getText().toString());

editor.putString(CommonConstants.PASSWORD_FIELD, passwordEditText.getText().toString());

}

editor.commit();

}

Приложение Б

Исходный текст класса CameraActivity

public class CameraActivity

extends Activity

implements SurfaceHolder.Callback,

Camera.PictureCallback,

View.OnClickListener,

Camera.AutoFocusCallback,

ListView.OnItemClickListener{

private static String PROPERTY_SIZE_INDEX = "PictureSizeIndex";

private static String PROPERTY_FLASH = "Flash";

private Camera camera;

private int cameraId;

private LinearLayout bottomPanel;

private RelativeLayout cameraButtonLayout;

private Button cameraButton;

private OrientationEventListener orientationObserver;

private int iconOrientation = Surface.ROTATION_0;

private Camera.Size[] pictureSizes;

private int pictureSizeIndex = 0;

private SharedPreferences preferences;

private boolean useAutoFocus = false;

private boolean useFlash = false;

private boolean hasFlash = false;

private ActionBar actionBar = null;

private Button settingsButton;

private ImageView settingsImageView;

private Button logOutButton;

private ImageView logOutImageView;

private Button flashButton;

private ImageView flashImageView;

private ImageView cameraIconImage = null;

private PopupWindow popupWindow = null;

private int popupWindowCenter = 0;

private SurfaceHolder surfaceHolder = null;

//region Activity lifecycle

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_camera);

ImageStore.clean();

camera = tryGetBackCamera();

pictureSizes = getPictureSizes(camera);

preferences = PreferenceManager.getDefaultSharedPreferences(this);

pictureSizeIndex = preferences.getInt(PROPERTY_SIZE_INDEX, 0);

hasFlash = getFlashAvailability();

useFlash = hasFlash && preferences.getBoolean(PROPERTY_FLASH, false);

surfaceHolder = ((SurfaceView)findViewById(R.id.cameraSurface)).getHolder();

assert surfaceHolder != null;

surfaceHolder.addCallback(this);

actionBar = getActionBar();

assert actionBar != null;

actionBar.setDisplayShowTitleEnabled(false);

actionBar.setDisplayUseLogoEnabled(false);

actionBar.setDisplayShowHomeEnabled(false);

actionBar.setDisplayShowCustomEnabled(true);

findViewById(R.id.cameraButton).setOnClickListener(this);

findViewById(R.id.cancelButton).setOnClickListener(this);

findViewById(R.id.continueButton).setOnClickListener(this);

bottomPanel = (LinearLayout)findViewById(R.id.bottomPanel);

cameraButton = (Button)findViewById(R.id.cameraButton);

cameraIconImage = (ImageView)findViewById(R.id.cameraIconImage);

cameraButtonLayout = (RelativeLayout)findViewById(R.id.cameraButtonLayout);

}

protected void onPause() {

orientationObserver.disable();

closeCamera();

preferences.edit().

putInt(PROPERTY_SIZE_INDEX, pictureSizeIndex).

putBoolean(PROPERTY_FLASH, useFlash).

commit();

if (!bottomPanelHidden) {

swapElementsVisibility();

}

super.onPause();

}

@Override

protected void onResume() {

setUpPopupWindow();

setUpOrientationEventListener();

if (settingsButton != null) {

orientationObserver.enable();

}

if (camera == null) {

camera = tryGetBackCamera();

}

setUpCameraParameters();

resetCameraPreview(surfaceHolder);

camera.startPreview();

super.onResume();

}

//endregion

//region Methods for camera

private Camera tryGetBackCamera() {

if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {

cameraId = findBackFacingCamera();

if (cameraId >= 0) {

return Camera.open(cameraId);

}

return null;

}

private int findBackFacingCamera() {

int cameraId = -1;

int numberOfCameras = Camera.getNumberOfCameras();

for (int i = 0; i < numberOfCameras; i++) {

Camera.CameraInfo info = new Camera.CameraInfo();

Camera.getCameraInfo(i, info);

if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {

cameraId = i;

break;

}

return cameraId;

}

private void closeCamera() {

if (camera != null) {

camera.release();

camera = null;

}

private int getRotationValue() {

int rotation = this.getWindowManager().getDefaultDisplay().getRotation();

int degrees = 0;

switch (rotation) {

case Surface.ROTATION_0: degrees = 0; break;

case Surface.ROTATION_90: degrees = 90; break;

case Surface.ROTATION_180: degrees = 180; break;

case Surface.ROTATION_270: degrees = 270; break;

}

Camera.CameraInfo info = new Camera.CameraInfo();

Camera.getCameraInfo(cameraId, info);

return (info.orientation - degrees + 360) % 360;

}

private boolean getFlashAvailability() {

//noinspection ConstantConditions

if (camera != null && getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {

List<String> modes = camera.getParameters().getSupportedFlashModes();

return modes != null && // workaround for some tablets an chinese devices

!(modes.size() == 1 &&

Camera.Parameters.FLASH_MODE_OFF.equals(modes.get(0)));

}

return false;

}

private Camera.Size[] getPictureSizes(Camera camera) {

List<Camera.Size> sizes = camera.getParameters().getSupportedPictureSizes();

assert sizes != null;

int count = sizes.size();

if (count > 3) {

sizes = sizes.subList(count - 3, count);

}

return sizes.toArray(new Camera.Size[sizes.size()]);

}

private void setPictureSize(int index) {

Camera.Size newSize = pictureSizes[index];

pictureSizeIndex = index;

Camera.Parameters parameters = camera.getParameters();

parameters.setPictureSize(newSize.width, newSize.height);

camera.setParameters(parameters);

}

private void setFlashMode(boolean useFlash) {

this.useFlash = useFlash;

Camera.Parameters parameters = camera.getParameters();

parameters.setFlashMode(useFlash ?

Camera.Parameters.FLASH_MODE_ON : Camera.Parameters.FLASH_MODE_OFF);

camera.setParameters(parameters);

}

private void setUpCameraParameters() {

Camera.Size newSize = pictureSizes[pictureSizeIndex];

Camera.Parameters parameters = camera.getParameters();

List<String> focusModes = parameters.getSupportedFocusModes();

assert focusModes != null;

if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

useAutoFocus = true;

} else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

}

parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);

parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);

parameters.setExposureCompensation(0);

parameters.setPictureSize(newSize.width, newSize.height);

if (hasFlash) {

parameters.setFlashMode(useFlash ?

Camera.Parameters.FLASH_MODE_ON : Camera.Parameters.FLASH_MODE_OFF);

}

camera.setParameters(parameters);

}

private void resetCameraPreview(SurfaceHolder surfaceHolder) {

try {

camera.setDisplayOrientation(getRotationValue());

//setCameraRotation(getRotationValue());

camera.setPreviewDisplay(surfaceHolder);

} catch (IOException exception) {

closeCamera();

}

//endregion

//region Options menu

@Override

public boolean onCreateOptionsMenu(Menu menu) {

LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);

View view = inflater.inflate(R.layout.menu_camera, null);

actionBar.setCustomView(view);

logOutButton = (Button)view.findViewById(R.id.logoutButton);

logOutImageView = (ImageView)view.findViewById(R.id.logoutImageView);

flashButton = (Button)view.findViewById(R.id.flashButton);

flashImageView = (ImageView)view.findViewById(R.id.flashImageView);

settingsButton = (Button)view.findViewById(R.id.settingsButton);

settingsImageView = (ImageView)view.findViewById(R.id.settingsImageView);

settingsButton.setOnClickListener(this);

logOutButton.setOnClickListener(this);

if (hasFlash) {

flashButton.setOnClickListener(this);

} else {

flashButton.setEnabled(false);

flashImageView.setAlpha(0.7f);

}

updateFlashIcon();

orientationObserver.enable();

return true;

}

//endregion

//region Click listener callbacks

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.cameraButton :

if (camera != null) {

cameraButton.setEnabled(false);

if (useAutoFocus) {

camera.autoFocus(this);

} else {

camera.takePicture(null, null, this);

}

}

break;

case R.id.cancelButton:

ImageStore.clean();

swapElementsVisibility();

if (camera != null) {

camera.startPreview();

}

break;

case R.id.continueButton:

navigateToDataActivity();

break;

case R.id.logoutButton:

navigateToLoginActivity();

break;

case R.id.flashButton:

setFlashMode(!useFlash);

updateFlashIcon();

break;

case R.id.settingsButton:

if (popupWindow.isShowing()) {

popupWindow.dismiss();

} else {

popupWindow.showAsDropDown(settingsButton);

}

break;

}

@Override

public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

setPictureSize(i);

}

//endregion

//region Navigation

private void navigateToLoginActivity() {

Intent intent = new Intent(this, LoginActivity.class);

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

startActivity(intent);

}

private void navigateToDataActivity() {

Intent intent = new Intent(this, DataActivity.class);

swapElementsVisibility();

startActivity(intent);

}

//endregion

//region SurfaceHolder.Callback implementation

@Override

public void surfaceCreated(SurfaceHolder surfaceHolder) {

resetCameraPreview(surfaceHolder);

}

@Override

public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {

camera.startPreview();

}

@Override

public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

closeCamera();

}

//endregion

//region Camera callbacks

@Override

public void onPictureTaken(byte[] bytes, Camera camera) {

ImageStore.storeImage(correctImage(bytes));

swapElementsVisibility();

}

rride

public void onAutoFocus(boolean b, Camera camera) {

camera.takePicture(null, null, this);

}

//endregion

private byte[] correctImage(byte[] data) {

try {

Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);

Bitmap bitmap = rotateImage(realImage, Math.abs(iconOrientation - 90));

ByteArrayOutputStream stream = new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);

byte[] newData = stream.toByteArray();

stream.close();

Log.d("Camera", String.format("Image size: %d", newData.length));

return newData;

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

private Bitmap rotateImage(Bitmap bitmap, int degree) {

int width = bitmap.getWidth();

int height = bitmap.getHeight();

Matrix matrix = new Matrix();

matrix.postRotate(degree);

return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

}

//region Visual state management

private boolean bottomPanelHidden = true;

private void swapElementsVisibility() {

bottomPanelHidden = !bottomPanelHidden;

settingsButton.setEnabled(bottomPanelHidden);

logOutButton.setEnabled(bottomPanelHidden);

cameraButton.setEnabled(bottomPanelHidden);

if (bottomPanelHidden) {

bottomPanel.setVisibility(View.GONE);

cameraButtonLayout.setVisibility(View.VISIBLE);

} else {

bottomPanel.setVisibility(View.VISIBLE);

cameraButtonLayout.setVisibility(View.GONE);

}

private void rotatePopup(int toOrientation) {

if (popupWindow != null) {

boolean needsToShow = popupWindow.isShowing();

popupWindow.dismiss();

View view = popupWindow.getContentView();

view.setPivotY(popupWindowCenter);

view.setPivotX(popupWindowCenter);

view.setRotation(toOrientation);

if (needsToShow) {

popupWindow.showAsDropDown(settingsButton);

}

private void tryStartRotation(View view, int toOrientation) {

if (view != null) {

RotateAnimation animation = getAnimation(toOrientation); // New animation object is needed to restore animation's center point

view.startAnimation(animation);

}

private void rotateImages(int toOrientation) {

tryStartRotation(logOutImageView, toOrientation);

tryStartRotation(flashImageView, toOrientation);

tryStartRotation(settingsImageView, toOrientation);

tryStartRotation(cameraIconImage, toOrientation);

}

private RotateAnimation getAnimation(int toOrientation) {

RotateAnimation animation = new RotateAnimation(

iconOrientation, toOrientation,

RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);

animation.setFillAfter(true);

animation.setDuration(600);

return animation;

}

private void updateFlashIcon() {

if (useFlash) {

flashImageView.setImageResource(R.drawable.ic_action_flash_on);

Toast.makeText(this, R.string.toast_flash_on, Toast.LENGTH_SHORT).show();

} else {

flashImageView.setImageResource(R.drawable.ic_action_flash_off);

Toast.makeText(this, R.string.toast_flash_off, Toast.LENGTH_SHORT).show();

}

//endregion

//region Setup methods

private void setUpOrientationEventListener() {

if (orientationObserver == null) {

orientationObserver = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {

@Override

public void onOrientationChanged(int i) {

int newOrientation = -100;

if (i >= 315 || i < 45) {

newOrientation = 0;

} else if (i >= 45 && i < 135) {

newOrientation = -90;

} else if (i >= 225 && i < 315) {

newOrientation = 90;

}

if (newOrientation > -100 && iconOrientation != newOrientation) {

rotatePopup(newOrientation);

rotateImages(newOrientation);

iconOrientation = newOrientation;

}

private PopupWindow setUpPopupWindow() {

if (popupWindow == null) {

LayoutInflater layoutInflater = (LayoutInflater)getBaseContext()

.getSystemService(LAYOUT_INFLATER_SERVICE);

View popupView = layoutInflater.inflate(R.layout.menu_camera_popup, null);

assert popupView != null;

ListView list = (ListView)popupView.findViewById(R.id.qualitiesListView);

TextView dummy = (TextView)popupView.findViewById(R.id.dummyTextView);

ArrayList<String> humanReadableHeaders = getHumanReadableHeaders();

setPopupListContent(list, humanReadableHeaders);

list.setOnItemClickListener(this);

list.setItemChecked(pictureSizeIndex, true);

// Measure is need to set PopupWindow width similar to WRAP_CONTENT behaviour

// Unfortunately this property of popupView is ignored and without this fix

// PopupWindow's width is equal to screen width.

popupView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

int side = popupView.getMeasuredWidth();

popupWindowCenter = side / 2;

popupWindow = getPopupWindow(popupView, side, side);

dummy.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

popupWindow.dismiss();

}

return popupWindow;

}

private ArrayList<String> getHumanReadableHeaders() {


Подобные документы

  • Исследование спецификации логической игры "Сапёр". Системное и функциональное проектирование приложения. Разработка программных модулей. Обзор классов, необходимых для создания интерфейса данного приложения. Инструменты для реализации логической игры.

    курсовая работа [1,2 M], добавлен 13.01.2016

  • Системное, функциональное проектирование. Классы, реализующие действия и фабрики моделей. Разработка программных модулей. Функция получения глосаризованных заголовков таблиц. Вычисление суммарной наценки. Ручное тестирование. Развертывание приложения.

    дипломная работа [2,6 M], добавлен 23.11.2016

  • Обзор технологий и систем геоинформационных систем. Системное и функциональное проектирование программного модуля, его разработка с использованием сред программирования Visual C++ 6.0, Qt 3.3.3. Технико-экономическое обоснование данного процесса.

    дипломная работа [1,2 M], добавлен 13.03.2011

  • Требования к аппаратным и операционным ресурсам. Логическая и физическая организация. Состав основных классов проекта. Технико-экономическое обоснование разработки программного средства. Задержки при обработке данных. Разработка интерфейса приложения.

    дипломная работа [4,4 M], добавлен 16.06.2017

  • Создание Win-приложения для библиотеки, которое позволяло бы осуществлять операции выдачи и сдачи книг в соответствии со сроками. Выбор программных и технических средств реализации проекта. Разработка интерфейса системы, описание реализованных классов.

    курсовая работа [3,1 M], добавлен 14.08.2015

  • Назначение и цели создания системы. Разработка логической модели данных, выбор хранилища. Диаграмма классов для диспетчера и контент-менеджера, схема взаимодействия объектов системы. Описание программных модулей. Тестирование веб-базированной системы.

    курсовая работа [5,4 M], добавлен 17.09.2013

  • Ознакомление с программой проведения сборки компьютера из деталей, имеющихся в базе данных. Рассмотрение правил создания иерархии классов. Описание основных методов и пользовательского интерфейса. Изучение системных требований и текстов основных классов.

    курсовая работа [710,2 K], добавлен 26.07.2014

  • Структурные подразделения и отделы организации, ее технические программные средства. Разработка приложений обработки данных на ассемблере, языке программирования высокого уровня. Тестирование и оптимизация программных модулей. Разработка документации.

    отчет по практике [175,0 K], добавлен 30.09.2022

  • Программная и техническая характеристика информационных систем предприятия. Требования к информационной и программной совместимости. Проектирование программного обеспечения с использованием специализированных программных пакетов. Разработка базы данных.

    отчет по практике [1,3 M], добавлен 11.04.2019

  • Разработка приложения "Программа по приему платежей и расчету по газу", которая послужит для учета и статистики платежей в расчетно-кассовом центре. Системное, функциональное проектирование. Разработка программных модулей. Программа и методика испытаний.

    дипломная работа [806,2 K], добавлен 13.02.2016

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.