Школа Инженерная школа информационных технологий и робототехники
Направление подготовки 09.03.01 Информатика и вычислительная техника
Отделение школы (НОЦ) Отделение информационных технологий
БАКАЛАВРСКАЯ РАБОТА
Тема работы
Разработка клиент-серверного приложения для обработки маршрутов движения
мобильных устройств
УДК 004.455.2:004.382.76
Студент
Группа
ФИО
8В6Б
Савченко Софья Михайловна
Подпись
Дата
Подпись
Дата
Подпись
Дата
Руководитель ВКР
Должность
ФИО
Ученая степень,
звание
Доцент ОИТ
Стоянов Александр
Кириллович
к.т.н.
Должность
ФИО
Ученая степень,
звание
Старший
преподаватель ОИТ
Дорофеев Вадим
Анатольевич
-
Консультант ВКР
КОНСУЛЬТАНТЫ ПО РАЗДЕЛАМ:
По разделу «Финансовый менеджмент, ресурсоэффективность и ресурсосбережение»
Должность
ФИО
Доцент ОСГН
Конотопский
Владимир Юрьевич
По разделу «Социальная ответственность»
Ученая степень,
звание
Подпись
Дата
Подпись
Дата
Подпись
Дата
к.т.н.
Должность
ФИО
Ученая степень,
звание
Ассистент ООТД
Матвиенко Владимир
Владиславович
-
ДОПУСТИТЬ К ЗАЩИТЕ:
Руководитель ООП
ФИО
Ученая степень,
звание
Доцент ОИТ
Погребной Александр
Владимирович
к.т.н.
Томск – 2020 г.
ПЛАНИРУЕМЫЕ РЕЗУЛЬТАТЫ ОБУЧЕНИЯ ПО ООП
Код
Результат обучения
результата
(выпускник должен быть готов)
Р1
Применять базовые и специальные естественнонаучные и математические
знания в области информатики и вычислительной техники, достаточные для
комплексной инженерной деятельности
Р2
Применять базовые и специальные знания в области современных
информационных технологий для решения инженерных задач
Р3
Ставить и решать задачи комплексного анализа, связанные с созданием
аппаратно-программных средств информационных и автоматизированных
систем, с использованием базовых и специальных знаний, современных
аналитических методов и моделей
Р4
Разрабатывать аппаратные и программные средства (системы, устройства,
блоки, программы, базы данных и т.п.) в соответствии с техническим
заданием и с использованием средств автоматизации проектирования
Р5
Проводить теоретические и экспериментальные исследования в области
создания аппаратных и программных средств информационных и
автоматизированных систем, включающие поиск и изучение необходимой
научно-технической
информации,
математическое
моделирование,
проведение эксперимента, анализ и интерпретацию полученных данных
Р6
Внедрять, эксплуатировать и обслуживать современные программноаппаратные комплексы, обеспечивать их высокую эффективность,
соблюдать правила охраны здоровья, безопасность труда, выполнять
требования по защите окружающей среды
Р7
Использовать базовые и специальные знания в области проектного
менеджмента для ведения комплексной инженерной деятельности
Р8
Владеть иностранным языком на уровне, позволяющем работать в
иноязычной среде, разрабатывать документацию, презентовать и защищать
результаты комплексной инженерной деятельности
Р9
Эффективно работать индивидуально и в качестве члена группы, состоящей
из специалистов различных направлений и квалификаций, демонстрировать
ответственность за результаты работы и готовность следовать
корпоративной культуре организации
Р10
Демонстрировать знания правовых, социальных, экономических и
культурных аспектов комплексной инженерной деятельности
Р11
Демонстрировать способность к самостоятельному обучению в течение всей
жизни и непрерывному самосовершенствованию в инженерной профессии
2
Инженерная школа информационных технологий и робототехники
Направление подготовки 09.03.01 Информатика и вычислительная техника
Отделение информационных технологий
УТВЕРЖДАЮ:
Руководитель ООП
09.03.01
Информатика
вычислительная техника
_____ _______ ____________
и
(Ф.И.О.)
ЗАДАНИЕ
на выполнение выпускной квалификационной работы
В форме:
Бакалаврской работы
(бакалаврской работы, дипломного проекта/работы, магистерской диссертации)
Студенту:
Группа
ФИО
8В6Б
Савченко Софье Михайловне
Тема работы:
Разработка клиент-серверного приложения для обработки маршрутов движения
мобильных устройств
Утверждена приказом директора (дата, номер)
28.02.2020, 5.9-501с
Срок сдачи студентом выполненной работы:
04.06.2020
ТЕХНИЧЕСКОЕ ЗАДАНИЕ:
Исходные данные к работе
Литературные
данные
по
разработке
приложений
под
платформу
Android,
техническая документация Android SDK.
Техническая документация по работе с Google
Maps Platform.
3
принципов
работы
Перечень подлежащих исследованию, 1) Исследование
архитектуры «клиент-сервер»;
проектированию
и
разработке
2)
Обзор
способов
определения
вопросов
местоположения;
3) Обзор существующих на рынке приложений
для отслеживания мобильных устройств;
оценка
их
популярности
и
конкурентоспособности;
4) Выбор кодовой базы и инструментария для
разработки мобильного приложения;
5) Разработка мобильного приложения;
6) Тестирование мобильного приложения;
7) Оценка и анализ готового продукта.
Скриншоты готового приложения
Перечень графического материала
Консультанты по разделам выпускной квалификационной работы
Раздел
Консультант
Финансовый менеджмент,
ресурсоэффективность и
ресурсосбережение
Социальная ответственность
Техническое задание, Обзор
литературы, Реализация
модуля
Конотопский Владимир Юрьевич
Матвиенко Владимир Владиславович
Дорофеев Вадим Анатольевич
Дата
выдачи
задания
на
выполнение
выпускной
квалификационной работы по линейному графику
01.02.2020
Задание выдал руководитель:
Должность
ФИО
Ученая степень,
звание
Доцент ОИТ
Стоянов А.К.
к.т.н
Подпись
Дата
Подпись
Дата
Задание принял к исполнению студент:
Группа
ФИО
8В6Б
Савченко Софья Михайловна
4
Инженерная школа информационных технологий и робототехники
Направление подготовки 09.03.01 Информатика и вычислительная техника
Уровень образования бакалавриат
Отделение информационных технологий
Период выполнения весенний семестр 2019/2020 учебного года
Форма представления работы:
бакалаврская работа
(бакалаврская работа, дипломный проект/работа, магистерская диссертация)
КАЛЕНДАРНЫЙ РЕЙТИНГ-ПЛАН
выполнения выпускной квалификационной работы
Срок сдачи студентом выполненной работы:
Дата
контроля
10.02.2020
08.03.2020
21.05.2020
04.06.2020
04.06.2020
Название раздела (модуля) /
вид работы (исследования)
Максимальный
балл раздела (модуля)
Сбор и анализ информации для раздела «Обзор
литературы»
Поиск инструментов для разработки приложения
Проектирование приложения и его реализация
Оформление и представление ВКР
15
25
40
20
Составил преподаватель:
Должность
ФИО
Ученая степень,
звание
Доцент ОИТ
Стоянов А.К.
к.т.н
Руководитель ООП
ФИО
Ученая степень,
звание
Доцент ОИТ
Погребной А.В.
к.т.н
Подпись
Дата
Подпись
Дата
СОГЛАСОВАНО:
5
ЗАДАНИЕ ДЛЯ РАЗДЕЛА
«ФИНАНСОВЫЙ МЕНЕДЖМЕНТ, РЕСУРСОЭФФЕКТИВНОСТЬ И
РЕСУРСОСБЕРЕЖЕНИЕ»
Студенту:
Группа
ФИО
8В6Б
Школа
Уровень образования
Савченко Софье Михайловне
ИШИТР
Отделение школы (НОЦ)
Направление/специальность
Бакалавриат
ОАР
09.03.01
Информатика
вычислительная техника
и
Исходные данные к разделу «Финансовый менеджмент, ресурсоэффективность и
ресурсосбережение»:
1. Стоимость ресурсов научного исследования (НИ):
материально-технических, энергетических,
финансовых, информационных и человеческих
2. Нормы и нормативы расходования ресурсов
3. Используемая система налогообложения, ставки
налогов, отчислений, дисконтирования и кредитования
Использовать
действующие
ценники
и
договорные цены на потребленные материальные
и информационные ресурсы, а также указанную в
МУ величину тарифа на эл. энергию
―
Действующие ставки единого социального налога
и НДС (см. МУ)
Перечень вопросов, подлежащих исследованию, проектированию и разработке:
1. Планирование процесса управления НТИ: структура и
график проведения, бюджет, риски и организация
закупок
Построение плана-графика выполнения ВКР,
составление соответствующей сметы затрат,
расчет величины НДС и цены результата ВКР
Перечень графического материала (с точным указанием обязательных чертежей):
1.
2.
3.
4.
Оценка конкурентоспособности технических решений
Матрица SWOT
Альтернативы проведения НИ
График проведения и бюджет НИ - выполнить
Оценка ресурсной, финансовой и экономической эффективности НИ- выполнить
Дата выдачи задания для раздела по линейному графику
Задание выдал консультант:
Должность
ФИО
Ученая степень,
звание
Доцент
Конотопский
Владимир Юрьевич
к. э. н.
Подпись
Дата
26.02.2020 г.
Задание принял к исполнению студент:
Группа
8В6Б
ФИО
Подпись
Савченко Софья Михайловна
6
Дата
26.02.2020 г.
ЗАДАНИЕ ДЛЯ РАЗДЕЛА
«СОЦИАЛЬНАЯ ОТВЕТСТВЕННОСТЬ»
Студенту:
Группа
8В6Б
ФИО
Савченко Софье Михайловне
Школа
Уровень образования
ИШИТР
Отделение (НОЦ)
Направление/специальность
бакалавриат
ОИТ
09.03.01 Информатика и
вычислительная техника
Тема ВКР:
Разработка клиент-серверного приложения для обработки маршрутов движения мобильных устройств
Исходные данные к разделу «Социальная ответственность»:
1. Характеристика объекта исследования (вещество,
материал, прибор, алгоритм, методика, рабочая зона) и
области его применения
Объект исследования – разработка клиентсерверного приложения для обработки
маршрутов
движения
мобильных
устройств.
Область применения – сфера бизнеса,
курьерские службы и контроль детей.
Рабочая зона разработчика – КЦ НИ ТПУ.
Перечень вопросов, подлежащих исследованию, проектированию и разработке:
1. Правовые и организационные вопросы обеспечения
безопасности:
специальные (характерные при эксплуатации
объекта исследования, проектируемой
рабочей зоны) правовые нормы трудового
законодательства;
организационные мероприятия при
компоновке рабочей зоны.
2. Производственная безопасность:
2.1. Анализ вредных и опасных факторов при проведении
исследований и при использовании объекта исследования и
обоснование мероприятий по защите исследователя
3. Экологическая безопасность:
4. Безопасность в чрезвычайных ситуациях:
– Трудовой кодекс Российской Федерации
от 30.12.2001 N 197-ФЗ (ред. от 16.12.2019)
[11];
– СанПиН 2.2.2/2.4.1340-03 ―Гигиенические
требования к персональным электронновычислительным машинам и организации
работы‖ [12];
– ССБТ ГОСТ 12.2.032-78 ―Рабочее место
при выполнении работ сидя. Общие
эргономические требования‖ [13]
Возможные вредные и опасные факторы:
– электромагнитное поле;
– электростатическое поле;
– шум;
– нарушения микроклимата;
– нарушение освещенности;
– психофизиологические факторы.
Факторы,
влияющие
на
состояние
окружающей среды:
– повышенное энергопотребление;
– отсутствие утилизации ПЭВМ
и сопутствующей оргтехники;
–отсутствие
утилизации
батарей
смартфонов;
– отсутствие утилизации макулатуры.
Основной вид ЧС техногенного характера
в процессе работы с ПЭВМ – пожар.
Дата выдачи задания для раздела по линейному графику
Задание выдал консультант:
Должность
ФИО
Ученая степень,
звание
ассистент ООТД
Матвиенко Владимир
Владиславович
7
Подпись
Дата
26.02.2020 г.
Задание принял к исполнению студент:
Группа
ФИО
8В6Б
Савченко Софья Михайловна
Подпись
8
Дата
26.02.2020 г.
Реферат
Выпускная квалификационная работа содержит 111 страниц, 35
рисунков, 12 таблиц, 16 литературных источников и 2 приложения.
Ключевые слова: мобильная разработка, базы данных, отслеживание
местоположения, Android Studio, GPS, Google Maps, Firebase.
Цель работы – проектирование и разработка клиент-серверного
приложения для обработки маршрутов движения мобильных устройств.
Данная
цель
обусловлена
необходимостью
точного
определения
географического местоположения владельцев мобильных устройств для их
последующей координации.
Объект исследования – разработка клиент-серверного приложения для
обработки маршрутов движения мобильных устройств.
Область применения – сфера бизнеса, курьерские службы и контроль
детей.
Приложение применяется для контроля перемещений частично или
полностью недееспособных людей (пенсионеры, инвалиды, дети), а также
сотрудников служб логистики и доставки.
9
Определения и сокращения
В данной работе используются следующие термины:
JAVA: объектно-ориентированный язык программирования;
БД (база данных): структура взаимосвязанных, хранящихся вместе
данных,
организованная
таким
образом,
что
обеспечивается
безызбыточное хранение данных, их комплексное использование и
независимость программ обработки от физической структуры;
GPS: спутниковая система навигации, обеспечивающая измерение
расстояния,
времени
и
определяющая
местоположение
во
всемирной системе координат WGS 84;
ГЛОНАСС: глобальная навигационная спутниковая система;
GSM: глобальный стандарт цифровой мобильной сотовой связи с
разделением каналов по времени и частоте;
LBS: программный сервис, использующий данные о локации для
управления какими-либо функциями;
XML: расширяемый язык разметки документов;
URL: единообразный указатель местонахождения ресурса;
API: описание способов (набор классов, процедур, функций,
структур или констант), которыми одна компьютерная программа
может взаимодействовать с другой программой;
ОС: операционная система.
10
Оглавление
Введение ................................................................................................... 14
1 Техническое задание ........................................................................... 15
1.1 Основные задачи и цели ............................................................... 15
1.2 Требования к модулю ................................................................... 15
2 Обзор литературы ............................................................................... 16
2.1 Основные сведения о клиент-серверных приложениях ............. 16
2.1.1 Front-end ................................................................................... 16
2.1.2 Back-end .................................................................................... 16
2.1.3 Преимущества и недостатки клиент-серверной архитектуры
17
2.2 Способы определения местоположения ...................................... 18
2.2.1 Точное местонахождение по GPS ........................................... 18
2.2.2 Примерное
местоположение
по
вышкам сотовой
связи
GSM/LBS 18
3 Обзор аналогов .................................................................................... 18
3.1 Где мои дети .................................................................................. 19
3.2 Zoemob ........................................................................................... 19
3.3 Sygic Family ................................................................................... 20
4 Реализация модуля .............................................................................. 21
4.1 Построение архитектуры приложения ........................................ 21
4.2 Выбор инструментария................................................................. 22
4.3 Структура БД ................................................................................ 22
4.4 Описание работы приложения ..................................................... 25
5 Финансовый
менеджмент,
ресурсоэффективность
и
ресурсосбережение ............................................................................................. 47
5.1 Организация и планирование работ............................................. 47
5.1.1 Продолжительность этапов работ ........................................... 48
11
5.2 Расчет сметы затрат на выполнение проекта .............................. 52
5.2.1 Расчет затрат на материалы ..................................................... 52
5.2.2 Расчет заработной платы ......................................................... 53
5.2.3 Расчет затрат на социальный налог ........................................ 53
5.2.4 Расчет затрат на электроэнергию ............................................ 54
5.2.5 Расчет амортизационных расходов ......................................... 55
5.2.6 Расчет расходов, учитываемых непосредственно на основе
платежных (расчетных) документов (кроме суточных) ............................ 56
5.2.7 Расчет прочих расходов ........................................................... 56
5.2.8 Расчет общей себестоимости разработки ............................... 57
5.2.9 Расчет прибыли ........................................................................ 57
5.2.10 Расчет НДС ............................................................................. 57
5.2.11 Цена разработки НИР ............................................................ 57
5.3 Оценка экономической эффективности проекта ........................ 58
6 Социальная ответственность .............................................................. 59
6.1 Правовые
и
организационные
вопросы
обеспечения
безопасности ................................................................................................... 59
6.1.1 Специальные (характерные для проектируемой рабочей зоны)
правовые нормы трудового законодательства ........................................... 59
6.1.2 Организационные мероприятия при компоновке рабочей
зоны. 61
6.2 Профессиональная социальная безопасность ............................. 62
6.2.1 Анализ вредных и опасных факторов, которые может создать
объект исследования и которые могут возникнуть на рабочем месте при
проведении исследования ........................................................................... 62
6.2.2 Обоснование мероприятий по защите исследователя от
действия опасных и вредных факторов ...................................................... 70
12
6.3 Экологическая безопасность ........................................................ 71
6.3.1 Анализ влияния объекта и процесса исследования на
окружающую среду ..................................................................................... 71
6.3.2 Обоснование мероприятий по защите окружающей среды .. 72
6.4 Безопасность в чрезвычайных ситуациях.................................... 73
6.4.1 Анализ вероятных ЧС, которые может инициировать объект
исследований и которые могут возникнуть на рабочем месте при
проведении исследований ........................................................................... 73
6.4.2 Обоснование
мероприятий
по
предотвращению
ЧС
и
разработка порядка действий в случае возникновения ЧС. ...................... 74
Заключение ............................................................................................... 75
Список использованных источников ...................................................... 76
Приложение А .......................................................................................... 78
SplashScreen.java ................................................................................... 78
MainActivity.java ................................................................................... 78
MapActivity.java .................................................................................... 82
UsersActivity.java ................................................................................... 90
AllUsersFragment.java............................................................................ 91
ProfileActivity.java ................................................................................. 93
Приложение Б ......................................................................................... 101
splashscreen.xml ................................................................................... 101
activity_main.xml ................................................................................. 102
activity_map.xml .................................................................................. 104
users_activity.xml ................................................................................. 106
row_users.xml ....................................................................................... 107
fragment_all_users.xml ......................................................................... 109
profile_activity.xml ............................................................................... 109
13
Введение
В современном мире большинство людей придерживаются активного
образа жизни, когда в каждом дне много дел и перемещений. В связи с
постоянной занятостью работающих граждан им становится тяжело нести
ответственность за людей, находящихся под их опекой, без какой-либо
помощи. Так, дети остаются предоставлены самим себе и рискуют оказаться
не в том месте и не в то время; пенсионеры, страдающие какими-либо
заболеваниями, в частности обладающие проблемами с памятью, могут,
покинув дом, заблудиться и не вернуться обратно.
Также в настоящее время очень хорошо развита система обслуживания
клиентов
посредством
доставки.
Обеспечение
людей
необходимыми
товарами требует наличия свободных курьеров, находящихся максимально
близко к нужному адресу. Здесь службы, связанные с логистикой,
сталкиваются со сложностями грамотного распределения человеческих,
технических и временных ресурсов.
В сфере бизнеса тоже является необходимым контроль сотрудников, в
обязанности которых входит проведение различных деловых встреч в
заданное время в подходящем месте. Работодателю важно знать, что
сотрудник в рабочие часы находится действительно в каком-либо из
установленных рабочих мест.
Решением вышеизложенных проблем является создание приложения,
позволяющего определять точное местоположение мобильных устройств для
последующей координации и контроля действий их владельцев.
14
1
Техническое задание
1.1 Основные задачи и цели
Целью проекта является разработка клиент-серверного приложения для
обработки маршрутов движения мобильных устройств.
Для реализации главной цели необходимо выполнить ряд следующих
задач:
1) Исследование принципов работы архитектуры «клиент-сервер»;
2) Обзор способов определения местоположения;
3) Обзор существующих на рынке приложений для отслеживания
мобильных
устройств;
оценка
их
популярности
и
конкурентоспособности;
4) Выбор кодовой базы и инструментария для разработки мобильного
приложения;
5) Разработка мобильного приложения;
6) Тестирование мобильного приложения;
7) Оценка и анализ готового продукта.
1.2 Требования к модулю
В рамках индивидуального задания по разработке проекта выделены
следующие пункты:
1) Реализация интерфейса мобильного приложения;
2) Организация взаимодействия активностей приложения;
3) Обеспечение взаимодействия приложения с пользователем;
4) Внедрение инструментов получения координат местоположения
устройств и вывода на карту.
15
2
Обзор литературы
2.1 Основные сведения о клиент-серверных приложениях
Написание программного кода любого клиент-серверного приложения
делится на FRONT-end программирование и BACK-end программирование
[1].
2.1.1 Front-end
Front-end программирование – это разработка клиентской части
приложения, то есть реализация взаимодействия между пользователем и
серверной частью приложения. Данная часть отвечает за ввод входной
информации от пользователя, а также ее первичную обработку и отправку на
сервер по соответствующему API.
Клиентская часть делится на 2 типа: нативная и кроссплатформенная.
Нативные приложения — это приложения, разрабатываемые на
«родном» языке платформы (приложения для iOS, Android и др.);
Кроссплатформенные приложения – это приложения, разрабатываемые
с помощью различных «фреймворков» (например, Adobe AIR, PhoneGap,
IBM Worklight).
2.1.2 Back-end
Back-end программирование – это разработка серверной части
приложения, которая отвечает за передачу данных между пользователями
или ресурсами.
Составляющие серверной части:
1. Серверная архитектура.
Проектируется и разрабатывается развернутая серверная архитектура:
алгоритмы загрузки данных, методы авторизации, кеширования и многое
другое.
2. API.
16
API (application programming interface) – это интерфейс прикладного
программирования, то есть набор запросов к серверу, который последний
понимает и может дать корректный ответ.
3. Административная панель.
Административная панель – это главный инструмент управления
мобильным приложением. Для каждого проекта создаѐтся отдельный Webинтерфейс управления. Функционал панели разрабатывается исходя из целей
и задач проекта. Все изменения, произведѐнные в административной панели,
моментально применяются к мобильному приложению.
4. Метрики.
Метрики – это статистические данные по приросту пользователей,
активности (лайки, комментарии, сообщения, просмотры, конверсии),
ежедневной посещаемости проекта в целом и его отдельных разделов.
2.1.3 Преимущества и недостатки клиент-серверной архитектуры
Преимуществом модели взаимодействия клиент-сервер является то, что
программный код клиентского приложения и серверного разделен [2].
К
преимуществам
архитектуры
клиент-сервер
можно
отнести
пониженные требования к машинам клиентов, так как большая часть
вычислительных операций будет производиться на сервере, а также
архитектура клиент-сервер довольно гибкая и позволяет администратору
сделать локальную сеть более защищенной.
К недостаткам модели взаимодействия клиент-сервер можно отнести
то, что стоимость серверного оборудования значительно выше клиентского.
Сервер должен обслуживать специально обученный и подготовленный
человек. Если в локальной сети возникают сбои на сервере, то и клиенты не
смогут работать.
Также стоит отметить, что архитектура «клиент-сервер» не делит
машины на «только клиент» или «только сервер», а скорее позволяет
распределить нагрузку и разделить функционал между клиентской частью и
серверной.
17
2.2 Способы определения местоположения
Для
определения
местонахождения
человека
применяются
две
основные технологии: GPS и LBS [3].
2.2.1 Точное местонахождение по GPS
Сигналы
спутниковой
навигации
покрывают
всю
планету
и
обеспечивают высочайшую точность. Остается лишь передать информацию о
местоположении человека наблюдателю. По этому принципу работают как
специальные GPS-маячки или GPS-трекеры, так и мобильные приложения
для телефонов и планшетов, оборудованных GPS-приемником. Главным
достоинством этого способа является высокая точность, поэтому на фоне
снижения стоимости устройств и гаджетов, он становится все более
популярным.
2.2.2 Примерное
местоположение
по
вышкам сотовой
связи
GSM/LBS
Вычисление местоположения человека на основе сигналов GSM/LBS
тоже широко распространено, однако точность заметно меньше, чем у GPS.
Суть технологии в том, чтобы анализировать информацию о тех базовых
станциях сотовой связи, которые находятся поблизости. На сегодня этот
метод применяется, в основном, как резервный, дополнительный к
GPS/ГЛОНАСС. GPS-трекеры и мобильные приложения передают эти
данные, и если GPS/ГЛОНАСС сигнал недоступен (в метро, в здании без
окон), то определение местонахождения выполняется по базовым станциям.
3
Обзор аналогов
На сегодняшний день уже существуют реализации приложений,
обеспечивающих отслеживание мобильных устройств. Для исследования
выберем ТОП-3 по оценке пользователей Google Play и App Store [4]: Где
мои дети, Zoemob и Sygic Family.
18
3.1
Где мои дети
Разработчики мобильного локатора «Где мои Дети» [5] предлагают
программы для смартфонов или смарт-часов.
Программа предоставляет следующую информацию:
карту перемещений;
посещение безопасных зон из списка (например, школы);
звуки с микрофона;
анализ разговоров и использования приложений, в том числе
подробную статистику.
Также ребенок сможет нажать тревожную кнопку при возникновении
сложной ситуации.
Разработчики
предлагают
три
варианта
лицензии
«Контроль
местоположения ребенка онлайн»:
месячная на 1 устройство за 169 рублей;
годовая на 3 устройства за 990 рублей;
вечная на 3 устройства за 1490 рублей.
Прослушивание окружения ребенка также разделено на 3 варианта:
30 минут за 59 рублей;
180 минут за 279 рублей;
безлимит на месяц за 990 рублей.
3.2 Zoemob
В отличие от предыдущего варианта, данное приложение не является
именно детским локатором, а отображает местоположение и скорость всех
членов семьи.
Кроме этого мобильная программа Zoemob [6] предлагает:
внутренний мессенджер с закрытым каналов для общения;
семейный календарь, чтобы строить общие планы;
тревожную кнопку для вызова родственников.
19
Zoemob получает точные данные GPS-приемника смартфона, но, если
сигнала нет или приемник выключен, приложение будет ориентироваться на
местоположение ближайшей вышки базовой станции сотового оператора или
Wi-Fi роутеры.
Программа доступна для ОС IOS и Android.
3.3
Sygic Family
Приложение Sygic Family [7] позволяет:
Показывать положение членов семьи на карте;
Создавать список безопасных и опасных геозон;
Оповещать о том, что кто-то в них зашел или из них вышел;
Отправлять сигнал SOS остальным членам семьи;
Показывать историю перемещения близких;
Премиум версия предлагает следующие платные функции:
Отслеживание в реальном времени;
Неограниченное количество геозон;
Недельную историю маршрутов;
Отслеживание рейсов с сообщениями о взлете и посадке.
Доступны 2 подписки, — годовая за 586,89 рубля и бесконечная за 990
рублей.
Среди недостатков исследуемых приложений выявлены следующие:
Отсутствие бесплатной версии, что повлечет за собой денежные
затраты;
Узкая направленность приложений, обеспечивают исключительно
контроль внутри семьи.
20
4
Реализация модуля
4.1 Построение архитектуры приложения
На основе анализа существующих аналогов приложения определена
схема реализации проекта.
Основными функциями приложения определены:
Регистрация и авторизация пользователя с использованием адреса
электронной почты и пароля;
Определение текущего местоположения вошедшего пользователя с
последующим отображением на карте;
Получение списка всех пользователей, зарегистрированных в
системе, с возможностью отправки им заявок на отслеживание;
Обработка входящих и исходящих заявок на отслеживание;
Получение списка всех пользователей, разрешивших отслеживание;
Возможность удаления отслеживаемых пользователей из списка;
Получение списка всех пользователей, которым вошедший в
приложение пользователь разрешил отслеживание;
Возможность отмены разрешения на отслеживание конкретным
пользователям;
Отображение на карте пользователей, принявших заявку на
отслеживание;
Возможность поиска мест на карте;
Возможность приближения, отдаления и возврата к текущему
местоположению на карте;
Отображение
данных
профиля
вошедшего
пользователя
возможностью их редактирования;
Возможность выхода из профиля вошедшего пользователя.
21
с
4.2 Выбор инструментария
В качестве инструмента для разработки мобильного приложения
выбрана среда Android Studio. Функционал реализуется с помощью языка
программирования Java. Разметка интерфейса осуществляется посредством
создания XML-файлов. Для определения местоположения используется GPS,
для отображения на карте – Google Maps Platform.
Android Studio [8] – это интегрированная среда разработки для работы с
платформой Android. Предоставляет возможность работы с сервисами Google
и
широким
спектром
графических
библиотек,
а
также
позволяет
конвертировать проект в готовый установочный APK-файл.
Java [9] – это строго типизированный объектно-ориентированный язык
программирования.
Является
официальным
языком
для
разработки
мобильных приложений под Android, поддерживается средой Android Studio
и поддерживается компанией Google.
Google Maps Platform [10] – это набор приложений, построенных на
основе
бесплатного
картографического
сервиса
и
технологии,
предоставляемых компанией Google. Сервис предоставляет разработчикам
бесплатное использование карт для зарегистрированных в системе Google
Maps Platform проектов при условии, что количество запросов пользователей
к приложению не будет превышать 1000 единиц в день.
4.3 Структура БД
Приведенные ниже рисунки отражают структуру базы данных
мобильного приложения.
22
Рисунок 1 – Аутентификация пользователей
При регистрации пользователей в приложении введенные адрес
электронной почты и пароль сохраняются во встроенной в Firebase системе
аутентификации пользователей для подключенного проекта. Каждому
пользователю присваивается уникальный ключ в зашифрованном виде,
который будет хранить всю добавляемую о пользователе информацию.
Рисунок 2 – Структура базы данных проекта
База данных проекта включает в себя три таблицы:
1.
Users
–
хранящая
данные
о
всех
зарегистрированных
пользователях;
2.
Requests – хранящая данные о входящих и исходящих заявках
пользователей на отслеживание;
3.
Devices
–
хранящая
данные
пользователей на отслеживание.
23
о
подтвержденных
заявках
Все таблицы создаются программно при вызове в приложении
соответствующих методов. При создании данных поля таблиц окрашиваются
в зеленый цвет, при обновлении - в желтый, при удалении - в красный.
Рисунок 3 – Таблица Users
Данная
таблица
хранит
всю
получаемую
в
процессе
работы
приложения информацию о каждом конкретном пользователе. Поскольку БД
работает
в режиме
реального
времени,
данные
о местоположении
пользователя постоянно обновляются. В БД обновления регистрируются
изменением цвета соответствующих полей на желтый.
Рисунок 4 – Таблица Requests
Данная таблица создается при отправлении пользователями заявок на
отслеживание друг друга. В таблице появляется поле идентификатора
пользователя,
отправившего
заявку,
затем
поле
идентификатора
пользователя, получившего заявку и поле ―request_type‖ у пользователя,
получившего заявку, имеющее значение ―received‖.
24
Рисунок 5 – Таблица Devices
В данную таблицу помещаются пользователи, одобрившие заявки на
отслеживание. Таблица заполняется симметрично с противоположными
значениями. Пользователь, разрешивший отслеживание, получает статус
―Saved‖ в поле ―Device‖ у пользователя, которому одобрил заявку. Тот, кому
заявка одобрена, получает статус ―Keep‖ в поле ―Keeper‖ того пользователя,
который разрешил его отслеживать. При этом отслеживание может быть
односторонним.
4.4 Описание работы приложения
Приведенные
ниже
рисунки
демонстрируют
функционирование
разработанного приложения. Программный код представлен в Приложениях
А и Б.
25
Рисунок 6 – Ярлык приложения на реальном устройстве пользователя
Разработанное
приложение
носит
название
KeepTrack.
Ярлык
приложения представляет собой первую букву названия, помещенную внутрь
лупы зеленого цвета. Логотип выполнен на белом фоне.
Рисунок 7 – Заставка приложения
26
После нажатия на ярлык приложения начинается его запуск, во время
которого на экране мобильного устройства появляется заставка (код
активности представлен в классе SplashScreen.java Приложения A, код
разметки в файле splash_screen.xml Приложения Б).
Рисунок 8 – Стартовая страница приложения
На стартовой странице приложения располагаются кнопки авторизации
и регистрации (код активности представлен в классе MainActivity.java
Приложения A, код разметки в файле activity_main.xml Приложения Б).
27
Рисунок 9 – Форма регистрации
Регистрационная форма включает в себя такие поля, как адрес
электронной почты, пароль, имя пользователя и номер телефона. На каждое
поле установлены ограничения и соответствующая обработка. Имеются
кнопки отмены и подтверждения регистрации.
28
Рисунок 10 – Сообщение об ошибке регистрации
В
случае,
если
пользователь
пытается
зарегистрировать
имеющиеся данные, выведется сообщение об ошибке.
Рисунок 11 – Сообщение об успешной регистрации
29
уже
Если все поля заполнены и пользователь регистрируется впервые,
появится сообщение о том, что он зарегистрирован, а все полученные данные
запишутся в БД.
Рисунок 12 – Форма авторизации
Авторизация пользователя происходит посредством ввода адреса
электронной почты и пароля, зарегистрированных в базе.
30
Рисунок 13 – Запрос разрешения на определение местоположения
После авторизации пользователю выводится запрос на разрешение
приложению доступа к данным о местоположении устройства (код
активности представлен в классе MapActivity.java Приложения A, код
разметки в файле activity_map.xml Приложения Б).
31
Рисунок 14 – Уведомление о работе приложения
Рисунок 15 – Основная страница приложения
После
получения
разрешения
на
определения
местоположения
устройства текущие координаты пользователя записываются в БД, а на
32
основной странице приложения открывается карта и в панели уведомлений
появляется сообщение о работе приложения в фоновом режиме (Рисунок 14).
В месте нахождения пользователя отображается синий маячок. На
странице предусмотрены функции приближения, отдаления карты, а также
возвращения объектива камеры на текущее местоположение пользователя.
Рисунок 16 – Поиск мест на карте
В верхней части основной страницы находится панель поиска мест.
Поиск можно осуществлять как на русском, так и на английском языках.
33
Рисунок 17 – Отображение всех пользователей
При нажатии на кнопку ―ALL USERS‖ в левом нижнем углу
открывается новая страница, содержащая три вкладки. Первая отображает
всех пользователей, зарегистрированных в системе, с возможностью
отправки им заявок на отслеживание (код активности представлен в классе
UsersActivity.java, код фрагмента в классе AllUsersFragment.java Приложения
A, код разметки в файлах users_activity.xml и row_users.xml Приложения Б).
34
Рисунок 18 – Отображение входящих заявок на отслеживание
Вторая вкладка отображает входящие заявки на отслеживание. Каждую
заявку
можно
принять
или
отклонить
посредством
нажатия
соответствующие кнопки.
Рисунок 19 – Окно подтверждения входящей заявки на отслеживание
35
на
После
нажатия
на
кнопку принятия
заявки
появляется
окно,
уточняющее намерения пользователя.
Рисунок 20 – Сообщение о принятии входящей заявки
После подтверждения принятия входящей заявки на отслеживание,
карточка пользователя, отправившего запрос, перемещается на другую
вкладку (Рисунок 26).
36
Рисунок 21 – Окно отклонения входящего запроса на отслеживание
После нажатия на кнопку отклонения заявки появляется окно,
уточняющее намерения пользователя.
Рисунок 22 – Сообщение об успешном отклонении входящей заявки
37
В случае, если пользователь подтвердил отклонение входящей заявки,
соответствующая карточка исчезает и появляется сообщение о том, что
заявка отклонена.
Рисунок 23 – Отображение исходящих заявок на отслеживание
Третья вкладка отображает исходящие заявки пользователя на
отслеживание. Каждая карточка содержит кнопку отмены заявки.
38
Рисунок 24 – Окно отмены исходящего запроса на отслеживание
После нажатия на кнопку отмены заявки появляется окно, уточняющее
намерения пользователя.
Рисунок 25 – Сообщение об успешной отмене исходящей заявки
39
В случае, если пользователь подтвердил отмену исходящей заявки,
соответствующая карточка исчезает и появляется сообщение о том, что
заявка отменена.
Рисунок 26 – Отображение пользователей, которым одобрена заявка на
отслеживание
При нажатии на кнопку ―DEVICES‖ основной страницы (Рисунок 15)
открывается новая, содержащая две вкладки.
Вкладка ―KEERERS‖ отображает всех пользователей, кому текущий
пользователь разрешил себя отслеживать.
40
Рисунок 27 – Сообщение об отмене данного разрешения на отслеживание
Для
отмены
данного
разрешения
необходимо
нажать
кнопку
―CANCEL‖, и выбранный пользователь больше не сможет отслеживать
местоположение текущего. Также появится сообщение об этом.
Рисунок 28 – Список отслеживаемых устройств
41
На вкладке ―TRACKED DEVICES‖ отображаются пользователи,
которые разрешили текущему их отслеживать. Удалить можно нажатием на
кнопку.
Рисунок 29 – Отображение отслеживаемых пользователей на карте
После того, как текущий пользователь получил разрешение других
пользователей на отслеживание, на карте появляется маркер в том месте, где
находится пользователь. При нажатии на маркер можно увидеть имя
отслеживаемого пользователя.
42
Рисунок 30 – Профиль пользователя
При нажатии на иконку в левом верхнем углу основной страницы
открывается страница редактирования профиля текущего пользователя,
отображающая фоновую картинку, фото, имя, почту и номер телефона
пользователя. Также имеется кнопка выхода в центре страницы и круглая
кнопка редактирования профиля в правом нижнем углу (код активности
представлен в классе ProfileActivity.java Приложения A, код разметки в
файле profile_activity.xml Приложения Б).
43
Рисунок 31 – Меню редактирования профиля
При нажатии на круглую кнопку открывается меню редактирования
профиля. Здесь пользователь может изменить фоновую картинку, фото
профиля, имя, номер телефона или пароль.
Рисунок 32 – Редактирование фонового изображения или фото пользователя
44
Загрузка изображения осуществляется с использованием камеры или
галереи.
Рисунок 33 – Запрос разрешения на доступ к камере
Рисунок 34 – Запрос разрешения на доступ к галерее
45
При попытке изменить изображение появляется окно, запрашивающее
разрешение приложению снимать фото и видео (Рисунок 33), а также
разрешение на доступ к галерее (Рисунок 34).
Рисунок 35 – Окно изменения пароля
Для изменения пароля необходимо ввести новую комбинацию.
Аналогичным образом осуществляется редактирование имени пользователя и
номера телефона.
При выходе из приложения посредством нажатия на кнопку ―Log out‖
выполняется переход на стартовую страницу (Рисунок 8).
Выводы
В ходе выполнения основной части бакалаврской работы были изучены
принципы разработки мобильных приложений. Улучшены навыки работы со
средой Android Studio и языком программирования Java. Приобретѐн опыт
работы с GPS и Google Maps Platform.
Выполнены все
требования
к модулю разработки мобильного
приложения.
46
5
Финансовый
менеджмент,
ресурсоэффективность и ресурсосбережение
Введение
В данном разделе производится комплексное описание и анализ
финансово-экономических аспектов выполненной работы. Оцениваются
полные денежные затраты на проект и дается приближенна экономическая
оценка результатов его внедрения.
5.1 Организация и планирование работ
В данном пункте составляется полный перечень проводимых работ,
определяются их исполнители и рациональная продолжительность. В
качестве наглядного результата выступает линейный график реализации
проекта. Данные для построения графика приведены в Таблица 1.
Таблица 1. Перечень работ и продолжительность их выполнения
Этапы работы
Постановка целей и задач, получение
исходных данных
Исполнители
Загрузка
исполнителей
НР
НР – 100%
Разработка и утверждение задания (ТЗ)
НР, И
Подбор и изучение материалов по тематике
НР, И
Разработка календарного плана
НР, И
Проектирование архитектуры приложения
НР, И
Разработка клиентской части приложения
И
НР – 100%
И – 10%
НР – 30%
И – 100%
НР – 100%
И – 10%
НР – 10%
И – 100%
И – 100%
Тестирование готового приложения
И
И – 100%
Согласование выполненной работы с научным
руководителем
Оформление расчетно-пояснительной записки
Оформление графического материала
Подведение итогов
НР, И
И
И
НР, И
47
НР – 100%
И – 100%
И – 100%
И – 100%
НР – 60%
И – 100%
5.1.1 Продолжительность этапов работ
Расчет продолжительности этапов работ осуществляется экспертным
способом опытно-статистического метода.
Для определения вероятных значений продолжительности работ tож
применяется следующая формула:
(1)
где:
tожi – ожидаемая трудоемкость выполнения i-ой работы чел.-дн.;
tmin
i
– минимально возможная трудоемкость выполнения
заданной i-ой работы (оптимистическая оценка: в предположении
наиболее благоприятного стечения обстоятельств), чел.-дн.;
tmax
i
– максимально возможная трудоемкость выполнения
заданной
i-ой
предположении
работы
(пессимистическая
наиболее
неблагоприятного
оценка:
в
стечения
обстоятельств), чел.-дн.
Для выполнения перечисленных в таблице 1 работ требуются
специалисты:
инженер – в его роли действует исполнитель НИР (ВКР);
научный руководитель.
Для
построения
линейного
графика
необходимо
рассчитать
длительность этапов в рабочих днях, а затем перевести ее в календарные дни.
Расчет продолжительности выполнения каждого этапа в рабочих днях
(
) ведется по формуле:
(2)
где:
– продолжительность работы, дн.;
48
– коэффициент выполнения работ, учитывающий влияние
внешних факторов на соблюдение предварительно определенных
длительностей, в частности, возможно Kвн = 1;
коэффициент, учитывающий дополнительное время на
компенсацию непредвиденных задержек и согласование работ
(
= 1–1,2; в этих границах конкретное значение принимает сам
исполнитель).
Расчет продолжительности этапа в календарных днях ведется по
формуле:
(3)
где:
– продолжительность выполнения этапа в календарных днях;
– коэффициент календарности, позволяющий перейти от
длительности работ в рабочих днях к их аналогам в календарных
днях, и рассчитываемый по формуле:
(4)
где:
– календарные дни (
– выходные дни (
– праздничные дни (
= 365);
= 52);
= 10).
(5)
С помощью указанных расчетных формул вычислим для каждой
работы ее трудоемкость и длительность (Таблица 2). По полученным
результатам построим график работ (Таблица 3).
49
Таблица 2. Трудозатраты на выполнение проекта
Этап
1
Постановка задачи
Разработка и утверждение
технического задания (ТЗ)
Подбор и изучение
материалов по тематике
Разработка календарного
плана
Проектирование архитектуры
приложения
Разработка мобильного
приложения
Тестирование готового
приложения
Согласование выполненной
работы с научным
руководителем
Оформление расчетнопояснительной записки
Оформление графического
материала
Подведение итогов
Исполнители
Продолжительность работ, дни
Трудоемкость работ по исполнителям чел.-дн.
TРД
TКД
НР
И
НР
И
6
7
8
9
3,84
–
4,63
–
2
НР
t min
3
2
t max
4
5
t ож
5
3,2
НР, И
2
5
3,2
3,2
3,2
3,8
3,8
НР, И
12
15
13,2
1,58
15,84
1,9
19,09
НР, И
2
4
2,8
3,36
0,34
4,05
0,41
НР, И
7
14
9,8
1,18
11,76
1,42
14,17
И
20
60
36
–
43,2
–
52,06
И
3
7
4,6
–
5,52
–
6,65
НР, И
3
10
5,8
6,96
6,96
8,39
8,39
И
6
9
7,2
–
8,64
–
10,41
И
5
6
5,4
–
6,48
–
7,81
НР, И
5
6,2
97,4
4,46
24,58
7,44
109,38
5,37
29,56
8,97
131,76
8
Итого:
50
Таблица 3. Линейный график работ (график Ганта)
Этап
НР
И
1
4,63
–
2
3,8
3,8
3
1,9
19,09
4
4,05
0,41
5
1,42
14,17
6
–
52,06
7
–
6,65
8
8,39
8,39
9
–
10,41
10
–
7,81
11
5,37
8,97
10
Февраль
20
30
Март
40
50
51
60
Апрель
70
80
90
Май
100
110
120
Июнь
130
140
5.2 Расчет сметы затрат на выполнение проекта
В состав затрат на создание проекта включается величина всех
расходов, необходимых для реализации комплекса работ, составляющих
содержание данной разработки.
Расчет сметной стоимости ее выполнения производится по следующим
статьям затрат:
материалы и покупные изделия;
заработная плата;
социальный налог;
расходы на электроэнергию (без освещения);
амортизационные отчисления;
командировочные расходы;
оплата услуг связи;
арендная плата за пользование имуществом;
прочие услуги (сторонних организаций);
прочие (накладные расходы) расходы.
5.2.1 Расчет затрат на материалы
В данном пункте производится расчет затрат на материальные ресурсы,
которые
необходимы
проектирования.
в
процессе
Например,
выполнения
специально
работ
над
приобретенное
объектом
оборудование
стоимостью до 40 000 руб. включительно.
Таблица 4. Расчет затрат на материалы
Наименование материалов
Бумага для принтера формата А4
Картридж для принтера
Цена за ед.,
руб.
190
1550
52
Кол-во
1 уп.
1 шт.
Итого:
Сумма, руб.
150
1550
4510
5.2.2 Расчет заработной платы
Данная статья расходов включает заработную плату научного
руководителя и инженера (в его роли выступает исполнитель проекта). Оклад
инженера принимается равным окладу инженера кафедры.
Среднедневная тарифная заработная плата (ЗПдн-т) рассчитывается по
формуле:
ЗПдн-т = МО/25,083
(6)
учитывающей, что в году 301 рабочий день и, следовательно, в месяце в
среднем 25,083 рабочих дня (при шестидневной рабочей неделе).
Для учета в составе зарплаты премий, дополнительной зарплаты и
районной надбавки используется следующий ряд коэффициентов: К ПР = 1,1;
Кдоп.ЗП = 1,188; Кр = 1,3. Таким образом, для перехода от тарифной (базовой)
суммы заработка исполнителя, связанной
с участием в проекте, к
соответствующему полному заработку (зарплатной части сметы) необходимо
первую умножить на интегральный коэффициент К и = 1,1* 1,188*1,3 = 1,699.
Вышеуказанное значение Кдоп.ЗП применяется при шестидневной рабочей
неделе. Для пятидневной недели Кдоп.ЗП равно 1,62.
Таблица 5. Затраты на заработную плату
Исполнитель
Дорофеев В.А.
(старший
преподаватель)
Савченко С.М.
(инженер
кафедры)
Оклад,
руб./мес.
Среднедневная
ставка,
руб./раб.день
Затраты
времени,
раб.дни
Коэффициент
Фонд
з/платы,
руб.
24 960
1040
25
1,699
44 174
9 489
431,32
110
1,62
76 861
Итого:
121 035
5.2.3 Расчет затрат на социальный налог
Данный пункт направлен на расчет затрат на единый социальный налог
(ЕСН), включающий в себя отчисления в пенсионный фонд, на социальное и
медицинское страхование, что составляет 30 % от полной заработной платы
по проекту, т.е. Ссоц. = Cзп*0,3.
53
В нашем случае: Ссоц. = 121 035 * 0,3 = 36 310,5 руб.
5.2.4 Расчет затрат на электроэнергию
Данный вид расходов включает в себя затраты на электроэнергию,
потраченную в ходе выполнения проекта на работу используемого
оборудования, рассчитываемые по формуле:
Сэл.об. = Pоб ∙ tоб ∙ ЦЭ
(7)
где:
PОБ – мощность, потребляемая оборудованием, кВт;
ЦЭ – тариф на 1 кВт∙час (для ТПУ ЦЭ = 6,59 руб./квт∙час (с
НДС));
tоб – время работы оборудования, час.
Время работы оборудования вычисляется на основе итоговых данных
таблицы 2 для инженера (TРД) из расчета, что продолжительность рабочего
дня равна 8 часов.
где Кt
tоб = TРД* Кt
(8)
1– коэффициент использования оборудования по времени,
равный отношению времени его работы в процессе выполнения проекта к
TРД, определяется исполнителем самостоятельно.
В ряде случаев возможно определение tоб
особенно
при
ограниченном
путем прямого учета,
использовании
соответствующего
оборудования.
Мощность, потребляемая оборудованием, определяется по формуле:
PОБ = Pном. * КС
(9)
где:
Pном. – номинальная мощность оборудования, кВт;
KС 1 – коэффициент загрузки, зависящий от средней степени
использования номинальной мощности. Для технологического
оборудования малой мощности KС = 1.
Пример расчета затраты на электроэнергию для технологических целей
приведен в Таблица 6.
54
Таблица 6. Затраты на технологическую электроэнергию
Наименование
оборудования
Персональный
компьютер
Струйный принтер
Время работы
оборудования tОБ, час
Потребляемая
мощность PОБ, кВт
Затраты ЭОБ, руб.
110*8*0,6
0,3
1 043,856
1
0,1
0,659
1 044,515
Итого:
5.2.5 Расчет амортизационных расходов
В статье «Амортизационные отчисления» рассчитывается амортизация
используемого оборудования за время выполнения проекта, по формуле:
(10)
где:
НА – годовая норма амортизации единицы оборудования;
ЦОБ – балансовая стоимость единицы оборудования с учетом ТЗР.
При невозможности получить соответствующие данные из
бухгалтерии она может быть заменена действующей ценой,
содержащейся в ценниках, прейскурантах и т.п.;
FД
–
действительный
соответствующего
годовой
оборудования,
фонд
времени
берется
из
работы
специальных
справочников или фактического режима его использования в
текущем календарном году. При этом второй вариант позволяет
получить более объективную оценку С АМ;
tрф – фактическое время работы оборудования
в ходе
выполнения проекта, учитывается исполнителем проекта;
n – число задействованных однотипных единиц оборудования.
При использовании нескольких типов оборудования расчет по формуле
делается соответствующее число раз, затем результаты суммируются.
Согласно постановлению
основных
средств,
правительства
включенных
в
РФ
«О
амортизационные
амортизации для ПК составляет 2 3 года.
55
классификации
группы»,
срок
Примем значение СА = 2,5 года. НА определяется как величина
обратная СА, в данном случае это 1 2,5 = 0,4.
Стоимость ПК 65000 руб., время использования 110 (дней) * 8 (часов) =
880 часов, тогда для него:
САМ(ПК) = (0,4*65000*880*1)/2408 = 9 501,66 руб.
Стоимость принтера 12000 руб., его FД = 500 час.; НА = 0,5; tрф = 1 час.,
тогда его:
САМ(Пр) = (0,5*12000*1*1)/500 = 12 руб.
Итого начислено амортизации: 9 513,66 руб.
5.2.6 Расчет расходов, учитываемых непосредственно на основе
платежных (расчетных) документов (кроме суточных)
Сюда относятся:
командировочные расходы, в т.ч. расходы по оплате суточных,
транспортные расходы, компенсация стоимости жилья;
арендная плата за пользование имуществом;
оплата услуг связи;
услуги сторонних организаций.
Норма оплаты суточных – 100 руб./день.
Во время выполнения проекта командировки не осуществлялись,
услуги сторонних организаций не требовались.
Итого по данному пункту: Снр = 0 руб.
5.2.7 Расчет прочих расходов
Расходы на выполнение проекта, которые не учтены в предыдущих
статьях, следует принять равными 10% от суммы всех предыдущих расходов,
т.е.
Спроч. = (Смат + Сзп + Ссоц + Сэл.об. + Сам + Снп) ∙ 0,1
Тогда получаем: Спроч. = (4510 + 121 035 + 36 310,5 + 1 044,515 + 9
513,66 + 0) ∙ 0,1 = 17 241,37 руб.
56
5.2.8 Расчет общей себестоимости разработки
Проведя расчет по всем статьям сметы затрат на разработку (Таблица
7), можно определить общую себестоимость проекта.
Таблица 7. Смета затрат на разработку проекта
Статья затрат
Условное обозначение
Сумма, руб.
Материалы и покупные изделия
Cмат
4510
Основная заработная плата
Cзп
121 035
фонды
Cсоц
36 310,5
Расходы на электроэнергию
Сэл.
1 044,515
Амортизационные отчисления
Cам
9 513,66
Cнр
0
Cпроч
17 241,37
Отчисления в социальные
Непосредственно учитываемые
расходы
Прочие расходы
Итого:
189 655,045
Таким образом, затраты на разработку составили: C = 189 655,045 руб.
5.2.9 Расчет прибыли
Поскольку
исполнитель
работы
не
располагает
данными
для
применения «сложных» методов, прибыль принимается в размере 5 20 %
от полной себестоимости проекта, т.е. 37 931,009 руб. (20 %) от расходов на
разработку проекта.
5.2.10 Расчет НДС
НДС составляет 20% от суммы затрат на разработку и прибыли.
В нашем случае: (189 655,045 + 37 931,009) * 0,2 = 45 517,2108 руб.
5.2.11 Цена разработки НИР
Цена равна сумме полной себестоимости, прибыли и НДС.
В нашем случае: ЦНИР(КР) = 189 655,045 + 37 931,009+ 45 517,2108 = 273
103,265 руб.
57
5.3 Оценка экономической эффективности проекта
Поскольку проект изначально не был ориентирован на экономический
результат, приведем только краткое систематизированное описание эффекта,
ожидаемого от проекта в случае его реализации.
Созданное
приложение
позволяет
упростить
процесс
контроля
местоположения частично недееспособных лиц (детей; пенсионеров с
потерей памяти и т.д.), а также сотрудников различных служб (логистики,
сфер бизнеса и других, где важно местонахождение в определенном месте в
конкретное время).
Наглядным
примером
может
служить
спецавтохозяйство,
осуществляющее вывоз различных отходов. При внедрении приложения в
деятельность данной организации, руководитель сможет отслеживать
передвижение
уборочных
машин,
тем
самым
предотвращая
несвоевременный вывоз мусора и образование несанкционированных свалок.
Разработанное программное обеспечение является универсальным (т.е.
подходит одновременно отдельным людям и целым организациям) и
предоставляется всем желающим на безвозмездной основе (бесплатно).
В
качестве
экономического
эффекта
реализации
проекта
рассматривается такой вид прибыли, как экономия ресурсов. Использование
приложения позволит сократить расходы фирм на ликвидацию свалок, найм
сотрудников-сопроводителей.
Частным
лицам,
в
свою
очередь,
предоставляется возможность контролировать перемещение нуждающихся в
наблюдении родственников без дополнительных затрат на услуги няни и
другого персонала по уходу.
Таким образом, можно сделать вывод, что реализация проекта и выпуск
созданного программного продукта являются выгодными с точки зрения
финансового менеджмента и ресурсоэффективности.
58
6
Социальная ответственность
Введение
Данный раздел освещает вопросы обеспечения безопасности в
процессе проектирования объекта исследования и его последующей
эксплуатации.
В ходе данной работы осуществляется разработка клиентской части
для
обработки
маршрутов
движения
мобильных
устройств,
что
обуславливает необходимость изучения специфики работы с ПЭВМ со
стороны влияния на здоровье пользователя и окружающую среду.
Разработка приложения происходит в г. Томск на домашнем
персональном
ноутбуке,
а
также
на
стационарном
компьютере
Кибернетического центра НИ ТПУ (ул. Советская, д.84/3). Средняя
температура рабочей зоны в зимний период года -20 градусов, в летний +21.
В роли пользователей выступают: разработчик, непосредственно
взаимодействующий
с
ПЭВМ
(при
написании
кода,
тестировании,
проектировании интерфейса и связей между внутренними модулями
взаимодействия и т.д.) и люди, использующие готовый программный
продукт на своѐм устройстве (персональном компьютере или смартфоне).
6.1 Правовые и организационные вопросы обеспечения
безопасности
6.1.1 Специальные (характерные для проектируемой рабочей
зоны) правовые нормы трудового законодательства
В соответствии с гигиеническими критериями оценки тяжести и
напряженности трудового процесса пользователей ПЭВМ (Раздел 1
Приложения 7 к СанПиНу 2.2.2/2.4.1340-03 [12]) описываемый проект
относится к трудовой деятельности «группы В» (творческой работе в режиме
диалога с ПЭВМ).
59
Для
данной
категории
определены
следующие
нормативные
требования:
За основную работу с ПЭВМ принимается та, что занимает не
менее 50% времени в течении рабочей смены;
Суммарное время непосредственной работы с ПЭВМ должно
быть не более 6 часов за смену;
Рекомендуется делать перерывы на 10-15 мин. Через каждые 45-
60 минут работы. При работе с ПЭВМ в ночную смену (с 22:00 до 6:00)
продолжительность регламентированных перерывов желательно увеличивать
на 30%;
Продолжительность
непрерывной
работы
без
регламентированного перерыва не должна превышать 1 часа;
Рекомендуемое суммарное время регламентированных перерывов
при 8-часовой смене составляет 50 минут;
Во
время
регламентированных
перерывов
целесообразно
выполнять комплексы упражнений (Приложения 8-10 к Санитарным
правилам
к
СанПиНу
2.2.2/2.4.1340-03)
и
комплексы
упражнений
физкультурных пауз (Приложение 10 к СанПиНу 2.2.2/2.4.1340-03).
Государственный контроль (надзор) за соблюдением трудового
законодательства и иных нормативных правовых актов, содержащих нормы
трудового права, осуществляется:
Федеральной инспекцией труда;
Министерством
труда
и
социальной
защиты
Российской
Федерации (Минтруд России);
Федеральной службой по труду и занятости (Роструд);
Государственной
экспертизой
условий
труда
Федеральной
службы по труду и занятости населения;
Федеральной службой по надзору в сфере защиты прав
потребителей и благополучия человека и другими.
60
6.1.2 Организационные мероприятия при компоновке рабочей
зоны.
От правильности организации рабочего места зависит эффективность
работы и состояние здоровья человека.
Согласно СанПиН 2.2.2/2.4.1340-03 площадь на одно рабочее место
должна составлять:
Не менее 6 кв. м – при использовании компьютеров с
мониторами на базе электронно-лучевой трубки;
Не менее 4,5 кв. м – при использовании компьютеров с
жидкокристаллическими/плазменными мониторами.
При
планировке
рабочего
места
необходимо
соблюдать
следующие нормы:
Рабочие столы должны быть размещены таким образом, чтобы
видеомониторов были обращены боковой стороной к световым проѐмам;
Рекомендованный проход слева, справа и спереди от стола – 500
Расстояние между рабочими столами должно быть не менее 2 м;
Расстояние между боковыми поверхностями мониторов не менее
Рекомендуется установка между рабочими зонами перегородок
мм;
1,2 м;
высотой 1,5-2,0 м при выполнении творческой работы, требующей высокого
умственного напряжения и особой концентрации внимания;
Дизайн ПЭВМ должен быть выполнен в спокойных тонах с
диффузным рассеиванием света; корпус и сопутствующая оргтехника должна
иметь матовую поверхность с коэффициентом отражения 0,4-06;
Конструкция рабочего стола должна обеспечивать оптимальное
размещения на рабочей поверхности необходимого оборудования с учѐтом
его количества, конструктивных особенностей и характера выполняемой
работы;
61
Оптимальные размеры поверхности рабочего стола: ширина 800-
1400 мм, глубина 800-1000 мм, высота – 725 мм;
Расстояние от глаз пользователя до экрана должно составлять
600-700 мм;
Расстояние от клавиатуры до края стола, обращенного к
пользователю: 100-300 мм; Так же возможно расположение клавиатуры на
специальной регулируемой рабочей поверхности, отделенной от основной
столешницы;
Стул (кресло) должен обеспечивать поддержку рациональной
рабочей позы и позволять изменять еѐ для снижения напряжения с мышц
спины и шейно-плечевой области. Регулировка каждого из параметров
должна осуществляться легко и независимо, а также иметь надежную
фиксацию;
Рекомендуется оборудовать рабочее место подставкой для ног
имеющей ширину не менее 300 мм и глубину не менее 400 мм, с
регулировкой по высоте (до 150 мм) и по углу наклона опорной поверхности
(до 20 градусов).
Соблюдение
работоспособности
перечисленных
и
позволяет
норм
избежать
способствует
проблем
повышению
со
здоровьем,
возникающих при длительной работе с ПЭВМ (например, боли в
позвоночнике, венозная недостаточность, ухудшение зрения и др.).
6.2 Профессиональная социальная безопасность
6.2.1 Анализ вредных и опасных факторов, которые может создать
объект исследования и которые могут возникнуть на рабочем месте при
проведении исследования
Вредные производственные факторы (ВПФ) – это факторы, которые,
действуя на трудящегося, могут привести к возникновению у него различных
заболеваний или снижению его работоспособности. При изменении времени
62
и
уровня
воздействия
вредные
производственные
факторы
могут
переквалифицироваться в группу опасных факторов.
Опасные производственные факторы (ОПР) – это факторы, которые в
результате своего длительного или кратковременного воздействия на
трудящегося приводят к резкому ухудшению его здоровья или к травме.
На
основании
производственные
ГОСТ
факторы.
12.0.003-2015
Классификация»
«Опасные
[14]
и
были
вредные
выделены
следующие факторы, которые могут причинить вред пользователю при
взаимодействии с ПЭВМ (Таблица 8).
Таблица 8. Возможные опасные и вредные факторы
Разработка
Эксплуатация
Этапы
работ
1. Электромагнитные поля
+
+
2. Электростатические поля
+
+
3. Шум
+
4. Нарушение
микроклимата помещения
+
5. Нарушение
освещенности рабочей
зоны
+
6. Психофизиологические
факторы
+
Факторы
(ГОСТ 12.0.003-2015)
Нормативные документы
СанПиН 2.2.2/2.4.1340-03
―Гигиенические требования к персональным
электронно-вычислительным машинам и
организации работы‖;
ССБТ ГОСТ 12.1.045–84
―Электростатические поля.
Допустимые уровни на рабочих местах и
требования к проведению контроля‖
СН 2.2.4/2.1.8.562-96 ―Шум на рабочих
местах, в помещениях жилых, общественных
зданий и на территории жилой застройки‖
СанПиН 2.2.4.548-96 ―Гигиенические
требования к микроклимату
производственных помещений‖, ССБТ ГОСТ
12.1.005-88 ―Общие санитарно-гигиенические
требования к воздуху рабочей зоны (с
Изменением N 1)‖
СанПиН 2.2.12.1.1.1278-03
―Гигиенические требования к естественному,
искусственному и совмещенному освещению
жилых и общественных зданий‖
Трудовой кодекс Российской Федерации от
30.12.2001 N 197-ФЗ (ред. от 16.12.2019),
СанПиН 2.2.2/2.4.1340-03 ―Гигиенические
требования к персональным электронновычислительным машинам и организации
работы‖
63
Анализ опасных и вредных факторов, характерных для проектируемой
производственной среды:
Электромагнитные поля;
1.
Электромагнитное поле – это особая форма материи, возникающая при
взаимодействии движущихся частиц с электрическими зарядами.
При работе с ПЭВМ основными источниками электромагнитного поля
могут являться:
мониторы;
системный блок;
оргтехника (принтер, сканер, измельчитель макулатуры и др.).
При постоянном воздействии на пользователя слабых, низкочастотных
излучений происходит их накапливание и постепенное увеличение уровня,
что может повлечь ухудшение репродуктивной функции, учащению
заболеваемости,
эмоциональной
нестабильностью
и
снижению
работоспособности.
Согласно СанПиН 2.2.2/2.4.1340-03, временные допустимые уровни
ЭМП, создаваемых ПЭВМ на рабочих местах пользователей следующие
(Таблица 9).
Таблица 9. Временные допустимые нормы ЭМП, создаваемых ПЭВМ
Наименование параметров
В диапазоне частот 5 Гц-2 кГц
Напряженность
электрического поля
В диапазоне частот 2 кГц-400 кГц
В диапазоне частот 5 Гц-2 кГц
Плотность магнитного
потока
В диапазоне частот 2 кГц-400 кГц
Электростатический потенциал экрана видеомонитора
Для
снижения
уровня
воздействия
возникающих
ВДУ ЭМП
25 В/м
2,5 В/м
250 нТл
25 нТл
500 В
от
ПЭВМ
электромагнитных излучений рекомендуется использование следующих мер
защиты:
использование мониторов с пониженным уровнем излучения
(например, MPR-II, TCO-92, TCO-99 и др.);
64
установка защитных экранов;
соблюдения режима труда и отдыха.
2.
Электростатические поля;
Электростатическое поле – это особая форма материи, исходящая от
неподвижных в пространстве и неизменяющихся во времени электрических
зарядов при отсутствии электрических токов.
При отключении ПЭВМ от электрической сети основными местами
накопления электростатических зарядов являются:
экраны мониторов;
клавиатура;
компьютерная мышь.
Скопление
электростатических
зарядов
делает
поверхности
благоприятными для распространения на них пыли, что при длительном
непрерывном взаимодействии с ПЭВМ может привести к попаданию
вредных веществ на слизистые оболочки глаз и в дыхательные пути.
Повышенный уровень электростатического излучения может повлечь
ухудшение общего эмоционального фона пользователя, сопровождающегося
нарушением сна, появлением раздражительности и потерей аппетита.
Удар электрическим током, спровоцированный искровым разрядом
статического электричества от источников ПЭВМ является незначительным
и не причинит вред пользователю.
Согласно
ССБТ
ГОСТ
12.1.045–84
―Электростатические
поля.
Допустимые уровни на рабочих местах и требования к проведению
контроля‖
[15],
предельно
допустимый
уровень
напряженности
электростатических полей устанавливается равным 60 кВ/м в течение 1 часа.
Для снижения уровня возникающих от ПЭВМ электромагнитных
излучений рекомендуется использование следующих мер защиты:
Для снижения уровня воздействия электростатических излучений
рекомендуется использование следующих мер защиты:
65
заземление оборудования;
использование мониторов с антибликовыми, контрастирующими
фильтрами на экранах;
использование
на
экранах
внешних
защитных
фильтров
с
заземляющим проводящим покрытием;
увлажнение окружающего воздуха;
использование
полов
преимущественно
из
антистатических
материалов.
3.
Шум;
Производственный шум – это комплекс звуков разных частот и
насыщенности, исходящий от различного вида технических устройств.
При работе с ПЭВМ основными источниками акустического шума
могут являться следующие детали системного блока:
Вентиляторы (кулер на процессоре и корпусе);
Накопители памяти (твердотельные и жесткие диски);
Интегрированная система охлаждения видеокарты;
Дисководы (CD-ROM).
Также источником шума может служить дополнительная оргтехника,
установленная на рабочем месте (например, принтер, сканер, измельчитель
макулатуры и др.).
Шум,
исходящий
от
техники,
привычен
для
современного
пользователя, но имеет накопительный эффект. Постоянный звуковой поток
может привести к ухудшению здоровья и появлению таких проблем, как
нарушение слухового аппарата, головокружение, гипертония и других.
последствиям относятся головокружение, оглушение, рассеянность.
Согласно СН 2.2.4/2.1.8.562-96 ―Шум на рабочих местах, в помещениях
жилых, общественных зданий и на территории жилой застройки. Санитарные
нормы‖ [16], предельно допустимые урони звука и эквивалентные уровни
звука на рабочих местах с учѐтом различных категорий напряженности
66
трудового процесса при легкой и средней физической нагрузке следующие
(Таблица 10).
Таблица 10. Предельно допустимые уровни звука и эквивалентные уровни звука
на рабочих местах для трудовой деятельности разных категорий напряженности в дБА
Категория
напряженности
трудового
процесса
Напряженность легкой степени
Напряженность средней степени
Напряженный труд 1 степени
Напряженный труд 2 степени
Предельно допустимый уровень звука, дБА
80
70
60
50
Для снижения уровня возникающих от ПЭВМ шумов рекомендуется
использование следующих мер защиты:
расположение
вентиляторов
внутри
системного
блока
в
специальном защитном кожухе;
покрытие
стен
и
потолков
помещения
звукопоглощающими
материалами с максимальными коэффициентами звукопоглощения
(рекомендованная область частот: 63 – 8000 Гц).
4.
Нарушения микроклимата в помещении;
Микроклимат рабочих помещений – это комплекс физических
факторов, оказывающих влияние на теплообмен человека с окружающей
средой, на тепловое состояние человека и определяющих самочувствие,
работоспособность, здоровье и производительность труда.
Нормы оптимальных (Таблица 11) и допустимых (Таблица 12)
показателей микроклимата при работе с ПЭВМ установлены следующими
документами:
СанПиН 2.2.4.548-96 ―Гигиенические требования к микроклимату
производственных помещений‖;
ССБТ
ГОСТ
12.1.005-88
―Общие
санитарно-гигиенические
требования к воздуху рабочей зоны (с Изменением N 1)‖.
Категории работ принято разграничивать на основе интенсивности
энергозатрат организма в ккал/ч (Вт). Работа, производимая в положении
67
сидя и сопровождающаяся незначительным физическим напряжением,
относится к категории Iа (работа с интенсивностью энергозатрат до 120
ккал/ч (до 139 Вт)).
Допустимый уровень микроклимата помещения обеспечивается при
помощи использования системы водяного центрального отопления и
естественной вентиляции.
В случае, если помещение не позволяет поддерживать рекомендуемые
нормы микроклимата, необходимо введение следующих дополнительных
мер по защите работников от возможного перегрева и охлаждения:
Системы местного кондиционирования воздуха;
Индивидуальные средства защиты от повышенных/пониженных
температур;
Установка режима работы и отдыха в соответствии с условиями
помещения
таким
образом,
чтобы
нормализовать
тепловое
состояние трудящегося;
Сокращение рабочих смен и др.
Таблица 11. Оптимальные величины показателей микроклимата на рабочих местах
производственных помещений
Период
года
Холодный
Теплый
Категория работ по Температура,
уровню энергозатрат,
°С
Вт
Iа
Iа
(22÷24)
(23÷25)
Относительная
влажность, %
(40÷60)
(40÷60)
Скорость
движения
воздуха,
м/с
0,1
0,1
Таблица 12. Допустимые величины показателей микроклимата на рабочих местах
производственных помещений
Период
года
Категория
Относительна
Скорость
работ по
я влажность,
движения
Температура, °С
уровню
%
воздуха, м/с
энергозатрат Диапазон
Диапазон
Для
Для
, Вт
ниже
выше
диапазона диапазона
оптимальны оптимальны
температур температур
х величин х величин
ниже
выше
оптимальны оптимальны
х величин, х величин,
не более
не более
68
Холодны
й
Теплый
5.
Iа
(20,0÷21,9) (24,1÷25,0)
(15÷75)
0,1
0,1
Iа
(21,0÷22,9) (25,1÷28,0)
(15÷75)
0,1
0,2
Нарушения освещенности рабочей зоны;
Освещенность – это световая величина, равная отношению падающего
на определенный участок поверхности светового потока к площади этого
участка. К понятию освещения относятся получение, распределение и
использование световой энергии для обеспечения благоприятных условий
видения предметов и объектов.
От правильности освещения зависит работоспособность и здоровье
трудящихся.
Недостаток
возникновение
света
хронического
может
повлечь
переутомления
и
ухудшение
усталости,
зрения,
а
также
головокружения.
Каждая
установка
нормативным
―Гигиенические
системы
требованиям.
требования
освещения
Согласно
к
должна
СанПиН
естественному,
соответствовать
2.2.12.1.1.1278-03
искусственному
и
совмещенному освещению жилых и общественных зданий‖, нормируемый
показатель искусственного освещения в помещениях с ПЭВМ составляет 300
лк.
Для
ликвидации
недостаточности
освещенности
в
качестве
дополнительного источника света применяется настольная лампа. Также,
ноутбук, за которым производится работа, размещается вблизи окна,
выходящего на солнечную сторону.
6.
Психофизиологические факторы.
Психофизиологические
факторы
опасности
–
это
факторы,
обусловленные особенностями физиологии и психологии человека, которые
могут нанести ему вред при определенных обстоятельствах.
К психофизиологическим факторам при работе с ПЭВМ можно отнести
следующие:
умственное перенапряжение;
69
напряжение зрения;
длительное статическое напряжение;
относительно большой объем информации, обрабатываемый в
единицу времени;
монотонность труда в отдельных случаях;
нерациональная организация рабочего места.
Отсутствие регламентированных перерывов или их несоблюдение
способно вызывать умственное перенапряжение, потерю внимания и
появлению раздражительности с головной болью. Длительная непрерывная
работа перед экраном монитора сопровождается напряжением глаз, что
может
привести
к
значительному
снижению
зрения.
Неграмотно
организованное рабочее место вызывает мышечные спазмы и усталость.
Режим труда и отдыха трудящихся регламентируют следующие
документы:
ТК РФ;
СанПиН 2.2.2/2.4.1340-03 и другие.
Режим труда и отдыха трудящегося: при вводе данных, редактировании
программ, чтении информации с экрана непрерывная продолжительность
работы не должна превышать 4-х часов при 8-часовом рабочем дне. Через
каждый час работы необходимо делать, перерыв на 5-10 минут, а через два
часа – на 15 минут.
Для исключения состояния переутомления рекомендуется соблюдать
все регламентированные перерывы и выполнять на них небольшую
физическую нагрузку (разминку).
6.2.2 Обоснование мероприятий по защите исследователя от
действия опасных и вредных факторов
Воздействие каждого из перечисленных выше факторов или их
совокупности способствует снижению работоспособности трудящегося, а
70
при
накоплении
может
повлечь
возникновение
профессионального
заболевания.
Для
предотвращения
неблагоприятных
последствий
необходимо
соблюдать все принятые государственными стандартами правила по
организации рабочего места, труда и отдыха.
По степени опасности поражения электрическим током помещение
относится к категории помещений без повышенной опасности, так как
отсутствуют высокая температура, токопроводящая пыль, особая сырость и
другие условия, создающие повышенную или особую опасность.
Провода используемых в процессе разработки устройств должны быть
тщательно изолированы, а при повреждении должны быть заменены на
новые. Электроаппаратура должна быть защищена от воздействия керосина,
масла,
охлаждающих
жидкостей,
стружки,
пыли
и
возможного
механического повреждения. При подключении к одному источнику сразу
нескольких устройств, их суммарная мощность не должна превышать
допустимую.
Рабочая зона (комната) полностью соответствует всем перечисленным
требованиям, дополнительные мероприятия не нужны.
6.3 Экологическая безопасность
6.3.1 Анализ влияния объекта и процесса исследования на
окружающую среду
Любая производственная деятельность человека оказывает негативное
действие на окружающую природную среду, ее ресурсы и процессы.
Процесс
исследования
и
дальнейшая
эксплуатация
объекта
исследования так же имеет влияние на природу.
Основными
источниками
неблагоприятных
воздействий
окружающую среду при работе с ПЭВМ могут служить:
повышенное энергопотребление;
отсутствие утилизации ПЭВМ и сопутствующей оргтехники;
71
на
отсутствие утилизации батарей смартфонов;
отсутствие утилизации макулатуры.
6.3.2 Обоснование мероприятий по защите окружающей среды
Процесс
разработки
исследуемого
модуля
(клиентской
части
приложения) подразумевает постоянное взаимодействие с ПЭВМ, что
сопровождается непрерывным потреблением электроэнергии.
Обеспечение высокой потребности установки в электроэнергии
сопровождается
увеличением
мощности
и
количества
используемых
электростанций, которые потребляют природные ресурсы и выбрасывают
вредные вещества в атмосферу.
Согласно ГОСТ Р 51768-2001 ―Ресурсосбережение. Обращение с
отходами. Методика определения ртути в ртутьсодержащих отходах‖,
утилизация ПЭВМ влечет за собой особо вредные выбросы. Компьютеры и
оргтехника, вышедшие из строя, подлежат списанию и перемещению на
специальный склад для последующей утилизации. На данный момент в
Томской области действуют два предприятия, занимающиеся утилизацией:
городской полигон и ООО НПП «Экотом». Утилизацию опасных бытовых
отходов обеспечивают компании: ООО «Торем» и ООО «СибМеталлГрупп».
Готовое
приложение
будет
эксплуатироваться
на
смартфонах.
Использование приложения увеличивает потребление энергии батареи, как
следствие, телефоны будут быстрее выходить из строя. Аккумуляторные
батареи мобильных телефонов включают в свой состав крайне опасные для
живых существ химические элементы, которые, по истечению срока службы
батареи, могут просачиваться во внешнее пространство. Особенно опасны
вздувшиеся батареи. Батареи сдаются в специальные пункты приѐма, после
чего подлежат специальной переработке, включающей следующие этапы:
вскрытие источника питания;
вымывание электролита;
отделение пластин;
72
передача составляющих на переплавку.
В Томске приѐм бытовой техники и электроники ведется в магазинах
―Эльдорадо‖, ―М.Видео‖, ―Техносила‖, а также в специальных пунктах
приема
организаций:
―Ведущая
Утилизирующая
Компания‖,
ООО
―Утилизация-Томск‖ и ООО ―Кварцит‖.
Процесс разработки так же сопровождается накоплением мусора такого
вида, как печатные отходы, использованная бумага, черновики, коробки от
техники и так далее. Отходы такого типа принято сдавать в специальные
пункты приема макулатуры, которых в Томске и области достаточно много.
За время разработки ПЭВМ, оргтехника и мобильные телефоны не
вышли из строя, соответственно, их утилизация не требуется. Основным
видом
отходов
выступает
накопившаяся
макулатура,
сбор
которой
производится непосредственно в помещении рабочей зоны, а при накоплении
вывозится в пункт приема макулатуры компании ―Чистый мир‖.
6.4 Безопасность в чрезвычайных ситуациях
6.4.1 Анализ вероятных ЧС, которые может инициировать объект
исследований и которые могут возникнуть на рабочем месте при
проведении исследований
Наиболее вероятной ЧС в рассматриваемом случае является пожар в
здании.
Согласно ГОСТ 12.1.044-89 «Система стандартов безопасности труда.
Пожаровзрывоопасность веществ и материалов. Номенклатура показателей и
методы их определения», основными источниками возгорания могут стать:
внутренние рабочие элементы ПЭВМ (при перегреве, дефектах);
электропроводка
(неисправность
может
замыкание);
взрывоопасные предметы в помещении.
73
повлечь
короткое
6.4.2 Обоснование
мероприятий
по
предотвращению
ЧС
и
разработка порядка действий в случае возникновения ЧС.
В
целях
предупреждения
возникновения
пожаров
необходимо
выполнение следующих мер:
установка схем здания с планами эвакуации;
обеспечение помещения средствами пожаротушения;
установка
систем
звукового
и
визуального
оповещения
об
опасности;
инструктаж
всех
работников
по
соблюдению
требований
безопасности.
При угрозе возникновения ЧС необходимо:
отключить электропитание;
вызвать пожарную команду;
эвакуировать людей из помещения согласно плану эвакуации.
При наличии небольшого очага пламени можно воспользоваться
подручными средствами (например, углекислотные огнетушители ОУ-5
высокого давления с зарядом жидкой двуокиси углерода) с целью
прекращения доступа воздуха к объекту возгорания.
Выводы
Посредством анализа приведенных правил и норм, регламентирующих
процесс работы с ПЭВМ и организацию рабочего места трудящегося, была
проведена
проверка
соответствия
имеющихся
условий
необходимым
дальнейшая
эксплуатация
требованиям.
Установлено,
что
исследование
и
разрабатываемого продукта не причинит вред здоровью трудящегося и
окружающей его среды.
74
Заключение
В результате выполнения выпускной квалификационной работы
бакалавра было разработано клиент-серверное приложение для обработки
маршрутов движения мобильных устройств.
В приложении реализованы все утвержденные в техническом задании
функции. Тестирование успешно проведено на мобильных устройствах
Xiaomi Redmi Note 8 Pro и Redmi Note 8T.
Проведена оценка финансовой ресурсоэффективности, подтвердившая
выгодность реализации проекта и выпуска созданного программного
продукта.
Посредством
анализа
проекта
с
точки
зрения
социальной
ответственности установлено, что исследование и дальнейшая эксплуатация
разрабатываемого продукта не причинит вред здоровью трудящегося и
окружающей его среды.
75
Список использованных источников
Структура клиент-серверных приложений [Электронный ресурс]
1.
(дата
// synset.com URL: http://fixapp.ru/programmirovanie-front-back-end/
обращения: 05.02.2020).
Преимущества и недостатки клиент-серверной архитектуры
2.
[Электронный
ресурс]
//
zametkinapolyah.ru
URL:
https://zametkinapolyah.ru/servera-i-protokoly/o-modeli-vzaimodejstviya-klient(дата
server-prostymi-slovami-arxitektura-klient-server-s-primerami.html
обращения: 05.02.2020).
Определение
3.
местоположения
человека
по
GPS/LBS
[Электронный ресурс] // gdemoi.ru URL: https://www.gdemoi.ru/res/gpsmestonahozhdenie-cheloveka/ (дата обращения: 06.02.2020).
Как отследить ребенка по мобильному телефону [Электронный
4.
ресурс]
//
KakOperator.ru
URL:
https://kakoperator.ru/collect/kak-otsledit-
rebenka-po-mobilnomu-telefonu (дата обращения: 07.02.2020).
5.
Где мои дети [Электронный ресурс] // watch.findmykids.org URL:
https://watch.findmykids.org/?utm_source=landing&utm_medium=seo&utm_cam
paign=ru%2F&utm_content=fast_delivery_B (дата обращения: 07.02.2020).
6.
Zoemob
[Электронный
ресурс]
//
zoemob.com
URL:
https://www.zoemob.com/ (дата обращения: 07.02.2020).
7.
Sigyc Family [Электронный ресурс] // family-locator.com URL:
https://family-locator.com/ (дата обращения: 07.02.2020).
8.
Documentation [Электронный ресурс] // developer.android.com
URL: https://developer.android.com/docs (дата обращения: 12.02.2020).
9.
Java Documentation [Электронный ресурс] // docs.oracle.com URL:
https://docs.oracle.com/en/java/ (дата обращения: 20.02.2020).
10.
Google Maps Platform Documentation
[Электронный ресурс] //
developers.google.com URL: https://developers.google.com/maps/documentation
(дата обращения: 01.03.2020).
76
11.
"Трудовой кодекс Российской Федерации" от 30.12.2001 N 197-
ФЗ (ред. от 16.12.2019) [Электронный ресурс] // НПА Нормативно-правовые
акты URL: https://bazanpa.ru/tk/ (дата обращения: 02.03.2020).
12.
СанПиН
2.2.2/2.4.1340-03
Гигиенические
требования
к
персональным электронно-вычислительным машинам и организации работы
[Электронный ресурс] // Электронный фонд правовой и нормативнотехнической документации URL: http://docs.cntd.ru/document/901865498 (дата
обращения: 04.03.2020).
13.
ГОСТ 12.2.032-78 Система стандартов безопасности труда
(ССБТ). Рабочее место при выполнении работ сидя. Общие эргономические
требования [Электронный ресурс] // Электронный фонд правовой и
нормативно-технической
документации
URL:
http://docs.cntd.ru/document/1200003913 (дата обращения: 07.03.2020).
14.
ГОСТ 12.0.003-2015 Система стандартов безопасности труда
(ССБТ). Опасные и вредные производственные факторы. Классификация
[Электронный ресурс] // Электронный фонд правовой и нормативнотехнической документации URL:
http://docs.cntd.ru/document/1200136071
(дата обращения: 07.03.2020).
15.
ССБТ ГОСТ 12.1.045–84 ―Электростатические поля. Допустимые
уровни на рабочих местах и требования к проведению контроля‖
[Электронный ресурс] // Электронный фонд правовой и нормативнотехнической документации URL: http://docs.cntd.ru/document/9051575 (дата
обращения: 08.03.2020).
16.
СН 2.2.4/2.1.8.562-96 ―Шум на рабочих местах, в помещениях
жилых, общественных зданий и на территории жилой застройки. Санитарные
нормы‖ [Электронный ресурс] // Электронный фонд правовой и нормативнотехнической документации URL: http://docs.cntd.ru/document/901703278 (дата
обращения: 08.03.2020).
77
Приложение А
SplashScreen.java
package com.example.keeptrack;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;
public class SplashScreen extends AppCompatActivity {
private final int SPLASH_DISPLAY_LENGHT = 3000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splashscreen);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent mainIntent = new Intent(SplashScreen.this,
MainActivity.class);
SplashScreen.this.startActivity(mainIntent);
SplashScreen.this.finish();
}
}, SPLASH_DISPLAY_LENGHT);
}
@Override
public void onBackPressed(){
super.onBackPressed();
}
}
MainActivity.java
package com.example.keeptrack;
import
import
import
import
import
import
import
import
import
import
import
android.content.DialogInterface;
android.content.Intent;
android.os.Bundle;
android.text.TextUtils;
android.view.LayoutInflater;
android.view.View;
android.view.animation.Animation;
android.view.animation.AnimationUtils;
android.widget.Button;
android.widget.RelativeLayout;
android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.example.keeptrack.Models.User;
78
import
import
import
import
import
import
import
import
import
com.google.android.gms.tasks.OnFailureListener;
com.google.android.gms.tasks.OnSuccessListener;
com.google.android.material.snackbar.Snackbar;
com.google.firebase.auth.AuthResult;
com.google.firebase.auth.FirebaseAuth;
com.google.firebase.auth.FirebaseUser;
com.google.firebase.database.DatabaseReference;
com.google.firebase.database.FirebaseDatabase;
com.rengwuxian.materialedittext.MaterialEditText;
public class MainActivity extends AppCompatActivity {
Button btnSignIn, btnRegister;
FirebaseAuth auth;//для авторизации
FirebaseDatabase db;//для подключения к БД
DatabaseReference users;//для работы с таблицами БД
RelativeLayout root;
final int ALPHA = 1;
TextView tv;
TextView tv1;
TextView text_bottom;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSignIn = findViewById(R.id.btnSignIn);
btnRegister = findViewById(R.id.btnRegister);
auth = FirebaseAuth.getInstance();
db = FirebaseDatabase.getInstance();
users = db.getReference("Users");
root = findViewById(R.id.root_element);
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showRegisterWindow();
}
});
btnSignIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showSignInWindow();
}
});
tv = (TextView) findViewById(R.id.tv);
tv1 = (TextView) findViewById(R.id.tv1);
text_bottom = (TextView) findViewById(R.id.text_bottom);
btnSignIn = (Button) findViewById(R.id.btnSignIn);
btnRegister = (Button) findViewById(R.id.btnRegister);
Animation anim = null;
anim = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
79
tv.startAnimation(anim);
tv1.startAnimation(anim);
text_bottom.startAnimation(anim);
btnSignIn.startAnimation(anim);
btnRegister.startAnimation(anim);
}
private void showSignInWindow(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Log In");
dialog.setMessage("Please, fill in all the fields below");
LayoutInflater inflater = LayoutInflater.from(this);
View sign_in_window = inflater.inflate(R.layout.sign_in_window,
null);
dialog.setView(sign_in_window);
final MaterialEditText email =
sign_in_window.findViewById(R.id.emailField);
final MaterialEditText pass =
sign_in_window.findViewById(R.id.passField);
dialog.setNegativeButton("Cancel", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
dialogInterface.dismiss();
}
});
//Проверка введенных параметров
dialog.setPositiveButton("Log in", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
if(TextUtils.isEmpty(email.getText().toString())){
Snackbar.make(root, "Enter your mail",
Snackbar.LENGTH_SHORT).show();
return;
}
if(pass.getText().toString().length()<6){
Snackbar.make(root, "Password must contain 6 or more
characters", Snackbar.LENGTH_SHORT).show();
return;
}
auth.signInWithEmailAndPassword(email.getText().toString(),
pass.getText().toString())
.addOnSuccessListener(new
OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
startActivity(new Intent(MainActivity.this,
MapActivity.class));
finish();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Snackbar.make(root, "Authorisation Error." +
e.getMessage(), Snackbar.LENGTH_SHORT).show();
}
});
}
80
});
dialog.show();
}
private void showRegisterWindow() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Register");
dialog.setMessage("Please, fill in all the fields below");
LayoutInflater inflater = LayoutInflater.from(this);
View register_window = inflater.inflate(R.layout.register_window,
null);
dialog.setView(register_window);
final MaterialEditText email =
register_window.findViewById(R.id.emailField);
final MaterialEditText pass =
register_window.findViewById(R.id.passField);
final MaterialEditText name =
register_window.findViewById(R.id.nameField);
final MaterialEditText phone =
register_window.findViewById(R.id.phoneField);
dialog.setNegativeButton("Cancel", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
dialogInterface.dismiss();
}
});
dialog.setPositiveButton("Register", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
if(TextUtils.isEmpty(email.getText().toString())){
Snackbar.make(root, "Enter your email",
Snackbar.LENGTH_SHORT).show();
return;
}
if(pass.getText().toString().length()<6){
Snackbar.make(root, "Password must contain 6 or more
characters", Snackbar.LENGTH_SHORT).show();
return;
}
if(TextUtils.isEmpty(name.getText().toString())){
Snackbar.make(root, "Enter your name",
Snackbar.LENGTH_SHORT).show();
return;
}
if(TextUtils.isEmpty(phone.getText().toString())){
Snackbar.make(root, "Enter your phone number",
Snackbar.LENGTH_SHORT).show();
return;
}
auth.createUserWithEmailAndPassword(email.getText().toString(),
pass.getText().toString())
.addOnSuccessListener(new
OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
81
final User user = new User();
user.setEmail(email.getText().toString());
user.setPass(pass.getText().toString());
user.setName(name.getText().toString());
user.setPhone(phone.getText().toString());
user.setLatitude("56.4653819");
user.setLongitude("84.95016091256596");
FirebaseUser currentFirebaseUser =
FirebaseAuth.getInstance().getCurrentUser();
user.setUid(currentFirebaseUser.getUid());
users.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user)
.addOnSuccessListener(new
OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid)
{
Snackbar.make(root, "You are
registered!", Snackbar.LENGTH_SHORT).show();
user.setUid(FirebaseAuth.getInstance().getCurrentUser().getUid());
}
});
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Snackbar.make(root, "Registration Error." +
e.getMessage(), Snackbar.LENGTH_SHORT).show();
}
});
}
});
dialog.show();
}
}
MapActivity.java
package com.example.keeptrack;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.Manifest;
android.app.Dialog;
android.content.Intent;
android.content.pm.PackageManager;
android.location.Address;
android.location.Geocoder;
android.location.Location;
android.os.Bundle;
android.util.Log;
android.view.KeyEvent;
android.view.View;
android.view.WindowManager;
android.view.inputmethod.EditorInfo;
android.widget.Button;
android.widget.EditText;
android.widget.ImageView;
android.widget.TextView;
android.widget.Toast;
import androidx.annotation.NonNull;
82
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
com.google.android.gms.common.ConnectionResult;
com.google.android.gms.common.GoogleApiAvailability;
com.google.android.gms.location.FusedLocationProviderClient;
com.google.android.gms.location.LocationServices;
com.google.android.gms.maps.CameraUpdateFactory;
com.google.android.gms.maps.GoogleMap;
com.google.android.gms.maps.OnMapReadyCallback;
com.google.android.gms.maps.SupportMapFragment;
com.google.android.gms.maps.model.LatLng;
com.google.android.gms.maps.model.MarkerOptions;
com.google.android.gms.tasks.OnCompleteListener;
com.google.android.gms.tasks.Task;
com.google.firebase.auth.FirebaseAuth;
com.google.firebase.database.DataSnapshot;
com.google.firebase.database.DatabaseError;
com.google.firebase.database.DatabaseReference;
com.google.firebase.database.FirebaseDatabase;
com.google.firebase.database.ValueEventListener;
com.google.firebase.database.annotations.NotNull;
import
import
import
import
import
java.io.IOException;
java.util.ArrayList;
java.util.List;
java.util.Timer;
java.util.TimerTask;
public class MapActivity extends AppCompatActivity implements
OnMapReadyCallback {
@Override
public void onMapReady(GoogleMap googleMap) {
Toast.makeText(this, "Map is ready", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onMapReady: map is ready");
nMap = googleMap;
if (mLocationPermissionGranted) {
getDeviceLocation();
startTrackerService();
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
return;
}
nMap.setMyLocationEnabled(true);
nMap.getUiSettings().setMyLocationButtonEnabled(false);
init();
ProcessingUnit processingUnit = new ProcessingUnit();
long interval = 1000;
Timer processingUnitTimer = new Timer();
processingUnitTimer.scheduleAtFixedRate(processingUnit, 0,
interval);
83
}
}
public class ProcessingUnit extends TimerTask {
public ProcessingUnit() {
}
@Override
public void run() {
final DatabaseReference usersRef =
FirebaseDatabase.getInstance().getReference().child("Users");
final DatabaseReference DevicesRef =
FirebaseDatabase.getInstance().getReference().child("Devices");
DevicesRef.child(currentUser).addValueEventListener(new
ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
{
for (DataSnapshot ds : dataSnapshot.getChildren()) {
if (ds.child("Device").exists()) {
String type = ds
.child("Device")
.getValue().toString();
if (type.equals("Saved")) {
final String list_user_id = ds.getKey();
nMap.clear();
usersRef.child(list_user_id).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull
DataSnapshot dataSnapshot) {
final String latitude_Display =
dataSnapshot.child("latitude").getValue().toString();
final String longitude_Display =
dataSnapshot.child("longitude").getValue().toString();
final String name_Display =
dataSnapshot.child("name").getValue().toString();
String latLng = latitude_Display;
String latLng1 = longitude_Display;
double latitude =
Double.parseDouble(latLng);
double longitude =
Double.parseDouble(latLng1);
LatLng currentLocation = new
LatLng(latitude, longitude);
MarkerOptions markerOptions = new
MarkerOptions();
markerOptions.position(currentLocation);
84
nMap.addMarker(new MarkerOptions()
.position(new
LatLng(latitude, longitude))
.title(name_Display)
);
}
@Override
public void onCancelled(@NonNull
DatabaseError databaseError) {
}
});
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
}
final String currentUser =
FirebaseAuth.getInstance().getCurrentUser().getUid();
private static final String TAG = "MapActivity";
private static final int ERROR_DIALOG_REQUEST = 9001;
private static final String FINE_LOCATION =
Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COARSE_LOCATION =
Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
private static final float DEFAULT_ZOOM = 15f;
private
private
private
private
EditText mSearchText;
ImageView mGps;
ImageView mZoomIn;
ImageView mZoomOut;
private boolean mLocationPermissionGranted = false;
private GoogleMap nMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
Button btnUsers, btnDevices;
ImageView viewProfile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
mSearchText = findViewById(R.id.input_search);
mGps = findViewById(R.id.ic_gps);
mZoomIn = findViewById(R.id.ic_zoom_in);
mZoomOut = findViewById(R.id.ic_zoom_out);
btnUsers = findViewById(R.id.btnUsers);
btnDevices = findViewById(R.id.btnDevices);
85
viewProfile = findViewById(R.id.view_profile);
if (isServicesOK()){
initMap();
}
getLocationPermission();
}
private void startTrackerService() {
startService(new Intent(this, TrackerService.class));
}
public boolean isServicesOK(){
Log.d(TAG, "isServicesOK: checking google services version");
int available =
GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(MapActivity
.this);
if(available == ConnectionResult.SUCCESS){
Log.d(TAG, "isServicesOK: Google Play Services is working");
return true;
}else if
(GoogleApiAvailability.getInstance().isUserResolvableError(available)){
Dialog dialog =
GoogleApiAvailability.getInstance().getErrorDialog(MapActivity.this,
available, ERROR_DIALOG_REQUEST);
dialog.show();
}else {
Toast.makeText(this, "You can't make map requests",
Toast.LENGTH_SHORT).show();
}
return false;
}
private void init() {
Log.d(TAG, "init: initializing");
mSearchText.setOnEditorActionListener(new
TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int actionId,
KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_DONE
|| keyEvent.getAction() == KeyEvent.ACTION_DOWN
|| keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {
geoLocate();
}
return false;
}
});
86
mGps.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: clicked gps icon");
getDeviceLocation();
}
});
mZoomIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: clicked zoom in icon");
nMap.animateCamera(CameraUpdateFactory.zoomIn());
}
});
mZoomOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: clicked zoom out icon");
nMap.animateCamera(CameraUpdateFactory.zoomOut());
}
});
btnUsers.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MapActivity.this,
UsersActivity.class);
startActivity(intent);
}
});
btnDevices.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MapActivity.this,
DevicesActivity.class);
startActivity(intent);
}
});
viewProfile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MapActivity.this,
ProfileActivity.class);
startActivity(intent);
}
});
hideSoftKeyboard();
}
private void geoLocate() {
Log.d(TAG, "geoLocate: geolocating ");
String searchString = mSearchText.getText().toString();
Geocoder geocoder = new Geocoder(MapActivity.this);
List<Address> list = new ArrayList<>();
try {
87
list = geocoder.getFromLocationName(searchString, 1);
} catch (IOException e) {
Log.e(TAG, "geoLocate: IOException " + e.getMessage());
}
if (list.size() > 0) {
Address address = list.get(0);
Log.d(TAG, "geoLocate: found a location: " + address.toString());
moveCamera(new LatLng(address.getLatitude(),
address.getLongitude()), DEFAULT_ZOOM,
address.getAddressLine(0));
}
}
private void getDeviceLocation() {
Log.d(TAG, "getDeviceLocation: getting the devices current
location");
mFusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(this);
try {
if (mLocationPermissionGranted) {
final Task location =
mFusedLocationProviderClient.getLastLocation();
location.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NotNull Task task) {
if (task.isSuccessful()) {
Log.d(TAG, "onComplete: found location!");
Location currentLocation = (Location)
task.getResult();
moveCamera(new
LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),
DEFAULT_ZOOM,
"My Location");
} else {
Log.d(TAG, "onComplete: current location is
null");
Toast.makeText(MapActivity.this, "Unable to get
current location", Toast.LENGTH_SHORT).show();
}
}
});
}
} catch (SecurityException e) {
Log.e(TAG, "getDeviceLocation: SecurityException: " +
e.getMessage());
}
}
private void moveCamera(LatLng latLng, float zoom, String title) {
Log.d(TAG, "moveCamera: moving the camera to: lat: " +
latLng.latitude + ", lng: " + latLng.longitude);
nMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
88
if(!title.equals("My Location")){
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title(title);
nMap.addMarker(options);
}
hideSoftKeyboard();
}
private void initMap() {
Log.d(TAG, "initMap: initializing map");
SupportMapFragment mapFragment = (SupportMapFragment)
getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
}
private void getLocationPermission() {
Log.d(TAG, "getLocationPermission: getting location permissions");
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if
(ContextCompat.checkSelfPermission(this.getApplicationContext(),
COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
initMap();
} else {
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
} else {
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NotNull String[]
permissions, @NotNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult: called");
mLocationPermissionGranted = false;
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE: {
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] !=
PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "onRequestPermissionsResult:
permission failed");
return;
}
}
89
Log.d(TAG, "onRequestPermissionsResult: permission
granted");
mLocationPermissionGranted = true;
initMap();
}
}
}
}
private void hideSoftKeyboard(){
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE
_ALWAYS_HIDDEN);
}
}
UsersActivity.java
package com.example.keeptrack;
import android.os.Bundle;
import
import
import
import
import
import
import
import
androidx.annotation.NonNull;
androidx.annotation.Nullable;
androidx.appcompat.app.AppCompatActivity;
androidx.appcompat.widget.Toolbar;
androidx.fragment.app.Fragment;
androidx.fragment.app.FragmentManager;
androidx.fragment.app.FragmentPagerAdapter;
androidx.viewpager.widget.ViewPager;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.List;
public class UsersActivity extends AppCompatActivity
{
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private AllUsersFragment allUsersFragment;
private InboxFragment inboxFragment;
private OutboxFragment outboxFragment;
private AppBarLayout appBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.users_activity);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = findViewById(R.id.tab_layout);
viewPager = findViewById(R.id.view_pager);
allUsersFragment = new AllUsersFragment();
90
inboxFragment = new InboxFragment();
outboxFragment = new OutboxFragment();
tabLayout.setupWithViewPager(viewPager);
ViewPagerAdapter viewPagerAdapter = new
ViewPagerAdapter(getSupportFragmentManager(), 0);
viewPagerAdapter.addFragment(allUsersFragment, "All Users");
viewPagerAdapter.addFragment(inboxFragment, "Inbox");
viewPagerAdapter.addFragment(outboxFragment, "Outbox");
viewPager.setAdapter(viewPagerAdapter);
tabLayout.getTabAt(0).setIcon(R.drawable.ic_users);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_inbox);
tabLayout.getTabAt(2).setIcon(R.drawable.ic_outbox);
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments = new ArrayList<>();
private List<String> fragmentTitle = new ArrayList<>();
private ViewPagerAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
public void addFragment(Fragment fragment, String title){
fragments.add(fragment);
fragmentTitle.add(title);
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitle.get(position);
}
}
}
AllUsersFragment.java
package com.example.keeptrack;
import
import
import
import
android.os.Bundle;
android.view.LayoutInflater;
android.view.View;
android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
91
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import
import
import
import
import
import
import
import
com.example.keeptrack.Models.User;
com.google.firebase.auth.FirebaseAuth;
com.google.firebase.auth.FirebaseUser;
com.google.firebase.database.DataSnapshot;
com.google.firebase.database.DatabaseError;
com.google.firebase.database.DatabaseReference;
com.google.firebase.database.FirebaseDatabase;
com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class AllUsersFragment extends Fragment {
RecyclerView recyclerView;
AdapterUsers adapterUsers;
List<User> userList;
private DatabaseReference UsersRef, UsersRef2;
private FirebaseAuth mAuth;
private String currentUserID;
public AllUsersFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_all_users, container,
false);
recyclerView = view.findViewById(R.id.users_list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new
LinearLayoutManager(getActivity()));
userList = new ArrayList<>();
getAllUsers();
return view;
}
private void getAllUsers() {
final FirebaseUser firebaseUser =
FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference ref =
FirebaseDatabase.getInstance().getReference("Users");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot ds: dataSnapshot.getChildren()){
User user = ds.getValue(User.class);
92
userList.add(user);
adapterUsers = new AdapterUsers(getActivity(),userList);
recyclerView.setAdapter(adapterUsers);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
ProfileActivity.java
package com.example.keeptrack;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.Manifest;
android.app.AlertDialog;
android.app.ProgressDialog;
android.content.ContentValues;
android.content.DialogInterface;
android.content.Intent;
android.content.pm.PackageManager;
android.net.Uri;
android.os.Bundle;
android.provider.MediaStore;
android.text.TextUtils;
android.view.View;
android.widget.Button;
android.widget.EditText;
android.widget.ImageView;
android.widget.LinearLayout;
android.widget.TextView;
android.widget.Toast;
import
import
import
import
androidx.annotation.NonNull;
androidx.appcompat.app.AppCompatActivity;
androidx.core.app.ActivityCompat;
androidx.core.content.ContextCompat;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
com.firebase.ui.auth.AuthUI;
com.google.android.gms.tasks.OnCompleteListener;
com.google.android.gms.tasks.OnFailureListener;
com.google.android.gms.tasks.OnSuccessListener;
com.google.android.gms.tasks.Task;
com.google.android.material.floatingactionbutton.FloatingActionButton;
com.google.firebase.auth.FirebaseAuth;
com.google.firebase.auth.FirebaseUser;
com.google.firebase.database.DataSnapshot;
com.google.firebase.database.DatabaseError;
com.google.firebase.database.DatabaseReference;
com.google.firebase.database.FirebaseDatabase;
com.google.firebase.database.Query;
com.google.firebase.database.ValueEventListener;
com.google.firebase.storage.FirebaseStorage;
com.google.firebase.storage.StorageReference;
com.google.firebase.storage.UploadTask;
com.squareup.picasso.Picasso;
93
import java.util.HashMap;
import de.hdodenhof.circleimageview.CircleImageView;
public class ProfileActivity extends AppCompatActivity {
FirebaseAuth firebaseAuth;
FirebaseUser user;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
FirebaseStorage storage;
StorageReference storageReference;
String storagePath = "Users_Profile_Cover_Images/";
CircleImageView profileImg;
ImageView profileCover;
TextView prName, prEmail, prPhone;
FloatingActionButton fab;
ProgressDialog pd;
private
private
private
private
static
static
static
static
final
final
final
final
int
int
int
int
CAMERA_REQUEST_CODE = 100;
STORAGE_REQUEST_CODE = 200;
IMAGE_PICK_GALLERY_CODE = 300;
IMAGE_PICK_CAMERA_CODE = 400;
String cameraPermissions[];
String storagePermissions[];
Uri image_uri;
String profileOrCoverPhoto;
Button btnLogOut;
public ProfileActivity() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.profile_activity);
firebaseAuth = FirebaseAuth.getInstance();
user = firebaseAuth.getCurrentUser();
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("Users");
storage = FirebaseStorage.getInstance();
storageReference = storage.getReference();
cameraPermissions = new String[]{Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
storagePermissions = new
String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
profileImg = findViewById(R.id.profile_img);
94
profileCover = findViewById(R.id.profile_cover);
prName = findViewById(R.id.pr_name);
prEmail = findViewById(R.id.pr_email);
prPhone = findViewById(R.id.pr_phone);
fab = findViewById(R.id.fab);
pd = new ProgressDialog(this);
btnLogOut = findViewById(R.id.btn_log_out);
btnLogOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_log_out) {
AuthUI.getInstance()
.signOut(ProfileActivity.this)
.addOnCompleteListener(new
OnCompleteListener<Void>() {
public void onComplete(@NonNull Task<Void>
task) {
finish();
startActivity(new
Intent(ProfileActivity.this, MainActivity.class));
}
});
}
}
});
Query query =
databaseReference.orderByChild("email").equalTo(user.getEmail());
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String
String
String
String
String
name = "" + ds.child("name").getValue();
email = "" + ds.child("email").getValue();
phone = "" + ds.child("phone").getValue();
image = "" + ds.child("image").getValue();
cover = "" + ds.child("cover").getValue();
prName.setText(name);
prEmail.setText(email);
prPhone.setText(phone);
try {
Picasso.get().load(image).into(profileImg);
} catch (Exception e) {
Picasso.get().load(R.drawable.ic_add_img_p).into(profileImg);
}
try {
Picasso.get().load(cover).into(profileCover);
} catch (Exception e) {
95
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showEditProfileDialog();
}
});
}
private boolean checkStoragePermission(){
boolean result = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== (PackageManager.PERMISSION_GRANTED);
return result;
}
private void requestStoragePermission(){
ActivityCompat.requestPermissions(this, storagePermissions,
STORAGE_REQUEST_CODE);
}
private boolean checkCameraPermission(){
boolean result = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA)
== (PackageManager.PERMISSION_GRANTED);
boolean result1 = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== (PackageManager.PERMISSION_GRANTED);
return result && result1;
}
private void requestCameraPermission(){
ActivityCompat.requestPermissions(this, cameraPermissions,
CAMERA_REQUEST_CODE);
}
private void showEditProfileDialog() {
String options[] = {"Edit Profile Photo", "Edit Cover Picture", "Edit
Name", "Edit Phone", "Change Password"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose Action");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0){
96
pd.setMessage("Updating Profile Picture");
profileOrCoverPhoto = "image";
showImagePicDialog();
}else if(which == 1){
pd.setMessage("Updating Cover Photo");
profileOrCoverPhoto = "cover";
showImagePicDialog();
}else if(which == 2){
pd.setMessage("Updating Name");
showNamePhoneUpdateDialog("name");
}else if(which == 3){
pd.setMessage("Updating Phone");
showNamePhoneUpdateDialog("phone");
}else if(which == 4){
pd.setMessage("Updating Password");
showNamePhoneUpdateDialog("pass");
}
}
});
builder.create().show();
}
private void showNamePhoneUpdateDialog(final String key) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Update " + key);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setPadding(10,10,10,10);
final EditText editText = new EditText(this);
editText.setHint("Enter "+ key);
linearLayout.addView(editText);
builder.setView(linearLayout);
builder.setPositiveButton("Update", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String value = editText.getText().toString().trim();
if(!TextUtils.isEmpty(value)){
pd.show();
HashMap<String, Object> result = new HashMap<>();
result.put(key, value);
databaseReference.child(user.getUid()).updateChildren(result)
.addOnSuccessListener(new
97
OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
pd.dismiss();
Toast.makeText(ProfileActivity.this,
"Updated..."+ key, Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
pd.dismiss();
Toast.makeText(ProfileActivity.this, ""+
e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}else{
Toast.makeText(ProfileActivity.this, "Please, enter "+
key, Toast.LENGTH_SHORT).show();
}
}
});
builder.setNegativeButton("Cancel", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
private void showImagePicDialog() {
String options[] = {"Camera", "Gallery"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick Image From");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0){
//camera clicked
if(!checkCameraPermission()){
requestCameraPermission();
}else{
pickFromCamera();
}
}else if(which == 1){
//gallery
if(!checkStoragePermission()){
requestStoragePermission();
}else{
98
pickFromGallery();
}
}
}
});
builder.create().show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[]
permissions, @NonNull int[] grantResults) {
switch (requestCode){
case CAMERA_REQUEST_CODE:{
if (grantResults.length >0){
boolean cameraAccepted = grantResults[0] ==
PackageManager.PERMISSION_GRANTED;
boolean writeStorageAccepted = grantResults[1] ==
PackageManager.PERMISSION_GRANTED;
if (cameraAccepted && writeStorageAccepted){
pickFromCamera();
}
else {
Toast.makeText(this, "Please, enable camera and
storage permission", Toast.LENGTH_SHORT).show();
}
}
}
break;
case STORAGE_REQUEST_CODE:{
if (grantResults.length >0){
boolean writeStorageAccepted = grantResults[1] ==
PackageManager.PERMISSION_GRANTED;
if (writeStorageAccepted){
pickFromGallery();
}
else {
Toast.makeText(this, "Please, enable storage
permission", Toast.LENGTH_SHORT).show();
}
}
}
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
if (resultCode == RESULT_OK){
if (requestCode == IMAGE_PICK_GALLERY_CODE){
image_uri = data.getData();
uploadProfileCoverPhoto(image_uri);
99
}
if (requestCode == IMAGE_PICK_CAMERA_CODE){
uploadProfileCoverPhoto(image_uri);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void uploadProfileCoverPhoto(Uri uri) {
pd.show();
String filePathAndName = storagePath+ ""+ profileOrCoverPhoto +"_"+
user.getUid();
StorageReference storageReference2nd =
storageReference.child(filePathAndName);
storageReference2nd.putFile(uri)
.addOnSuccessListener(new
OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot
taskSnapshot) {
Task<Uri> uriTask =
taskSnapshot.getStorage().getDownloadUrl();
while (!uriTask.isSuccessful());
Uri downloadUri = uriTask.getResult();
if(uriTask.isSuccessful()){
HashMap<String, Object> results= new HashMap<>();
results.put(profileOrCoverPhoto,
downloadUri.toString());
databaseReference.child(user.getUid()).updateChildren(results)
.addOnSuccessListener(new
OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
pd.dismiss();
Toast.makeText(ProfileActivity.this, "Image Updated...",
Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new
OnFailureListener() {
@Override
public void onFailure(@NonNull
Exception e) {
pd.dismiss();
Toast.makeText(ProfileActivity.this, "Error Updating Image...",
Toast.LENGTH_SHORT).show();
}
});
}
else{
pd.dismiss();
Toast.makeText(ProfileActivity.this, "Some error
occured", Toast.LENGTH_SHORT).show();
100
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
pd.dismiss();
Toast.makeText(ProfileActivity.this, e.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
private void pickFromCamera() {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "Temp Pic");
values.put(MediaStore.Images.Media.DESCRIPTION, "Temp Description");
image_uri =
this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
private void pickFromGallery() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, IMAGE_PICK_GALLERY_CODE);
}
}
Приложение Б
splashscreen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<TextView
android:id="@+id/text_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
101
android:layout_marginBottom="40dp"
android:fontFamily="@font/fauna_one"
android:text="@string/app_by"
android:textColor="@color/text_bottom"
android:textSize="15sp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_centerHorizontal="true"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:fontFamily="@font/fauna_one"
android:text="@string/line"
android:textAlignment="center"
android:textColor="@android:color/black"
android:textSize="70sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:fontFamily="@font/fauna_one"
android:text="@string/line1"
android:textAlignment="center"
android:textColor="@android:color/black"
android:textSize="20sp" />
</LinearLayout>
<pl.droidsonroids.gif.GifImageView
android:layout_width="match_parent"
android:layout_height="310dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@drawable/start0" />
</RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_element"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
tools:context=".MainActivity" >
102
<pl.droidsonroids.gif.GifImageView
android:layout_width="match_parent"
android:layout_height="310dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@drawable/start0" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_centerHorizontal="true"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:fontFamily="@font/fauna_one"
android:text="@string/app_in_name"
android:textAlignment="center"
android:textColor="@android:color/black"
android:textSize="70sp" />
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:fontFamily="@font/fauna_one"
android:text="@string/app_in_name_after"
android:textAlignment="center"
android:textColor="@android:color/black"
android:textSize="20sp" />
</LinearLayout>
<TextView
android:id="@+id/text_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp"
android:fontFamily="@font/fauna_one"
android:text="@string/text_bottom"
android:textColor="@color/text_bottom"
android:textSize="15sp"
/>
<LinearLayout
android:layout_above="@+id/text_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
103
android:weightSum="2"
android:layout_margin="15dp"
android:layout_marginTop="25dp"
android:orientation="horizontal" >
<Button
android:id="@+id/btnSignIn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:layout_weight="1"
android:background="@drawable/btn_sign_in"
android:fontFamily="@font/fauna_one"
android:text="@string/btnSignIn"
android:textColor="@android:color/white"
android:textSize="20sp"/>
<Button
android:id="@+id/btnRegister"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:background="@drawable/btn_register"
android:fontFamily="@font/fauna_one"
android:text="@string/btnRegister"
android:textColor="@android:color/white"
android:textSize="20sp" />
</LinearLayout>
</RelativeLayout>
activity_map.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
<ImageView
android:id="@+id/view_profile"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="10dp"
104
android:src="@drawable/user"
android:scaleType="centerCrop"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="60dp"
android:elevation="10dp"
android:background="@drawable/white_border"
android:id="@+id/ralLayout1">
<ImageView
android:id="@+id/ic_magnify"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:src="@drawable/ic_magnify"/>
<EditText
android:id="@+id/input_search"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toEndOf="@+id/ic_magnify"
android:layout_marginStart="10dp"
android:layout_centerVertical="true"
android:textSize="15sp"
android:textColor="@android:color/black"
android:background="@null"
android:hint="Enter Address, City or Zip Code"
android:imeOptions="actionSearch" />
</RelativeLayout>
<ImageView
android:id="@+id/ic_zoom_in"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_below="@+id/ralLayout1"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp"
android:layout_marginTop="15dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_zoom_in"/>
<ImageView
android:id="@+id/ic_zoom_out"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_below="@+id/ic_zoom_in"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp"
android:layout_marginTop="15dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_zoom_out"/>
<ImageView
105
android:id="@+id/ic_gps"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_below="@+id/ic_zoom_out"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp"
android:layout_marginTop="15dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_gps"/>
<LinearLayout
android:layout_width="match_parent"
android:weightSum="2"
android:layout_marginBottom="30dp"
android:layout_marginTop="20dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/btnUsers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_weight="1"
android:background="@drawable/btn_users"
android:fontFamily="@font/fauna_one"
android:text="@string/btnUsers"
android:textColor="@android:color/white"
android:textSize="20sp"/>
<Button
android:id="@+id/btnDevices"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
android:layout_weight="1"
android:background="@drawable/btn_devices"
android:fontFamily="@font/fauna_one"
android:text="@string/btnDevices"
android:textColor="@android:color/white"
android:textSize="20sp"
android:src="@drawable/ic_zones"/>
</LinearLayout>
</RelativeLayout>
users_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".UsersActivity">
106
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:elevation="0dp">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/white" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Scrollin
gViewBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
row_users.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:outlineAmbientShadowColor="@android:color/black"
android:outlineSpotShadowColor="@android:color/black"
app:cardUseCompatPadding="true"
app:cardCornerRadius="10dp"
app:cardElevation="3dp"
app:cardBackgroundColor="@android:color/white"
app:contentPadding="4dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id = "@+id/user_ic"
android:layout_width="112dp"
android:layout_height="112dp"
android:src = "@drawable/ic_prof" />
107
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginTop="6dp">
<TextView
android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/fauna_one"
android:text="User name"
android:textAlignment="textStart"
android:textColor="@android:color/black"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/user_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/fauna_one"
android:text="User email"
android:textAlignment="textStart"
android:layout_marginBottom="7dp"
android:textColor="@color/email_color"
android:textSize="18sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_request_accept"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="Accept"
android:textSize="16sp"
android:textAllCaps="false"
android:background="@drawable/btn_sign_in"
android:textColor="@android:color/white"
android:visibility="invisible"/>
<Button
android:id="@+id/btn_request_decline"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="Decline"
android:layout_marginStart="15dp"
android:textSize="16sp"
android:textAllCaps="false"
android:background="@drawable/btn_register"
android:textColor="@android:color/white"
android:visibility="invisible"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
108
</androidx.cardview.widget.CardView>
fragment_all_users.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AllUsersFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/users_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
profile_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
tools:context=".ProfileActivity"
android:background="@android:color/white">
<ImageView
android:id="@+id/profile_cover"
android:layout_width="match_parent"
android:layout_height="310dp"
android:scaleType="fitXY"
android:background="@color/bg_profile"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/profile_img"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginTop="17dp"
android:src="@drawable/ic_add_img_p"
android:layout_centerHorizontal="true"
android:elevation="1dp"/>
109
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="90dp"
android:animateLayoutChanges="false"
android:animationCache="false"
android:elevation="2dp"
android:filterTouchesWhenObscured="false"
android:focusable="auto"
android:visibility="visible"
tools:visibility="visible"
android:outlineAmbientShadowColor="@android:color/black"
android:outlineSpotShadowColor="@android:color/black"
app:contentPaddingBottom="30dp"
app:contentPaddingLeft="30dp"
app:contentPaddingRight="30dp"
app:contentPaddingTop="30dp"
app:cardUseCompatPadding="true"
app:cardElevation="10dp"
app:cardCornerRadius="20dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/pr_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="60dp"
android:fontFamily="@font/fauna_one"
android:text="User Name"
android:textColor="@android:color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/pr_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:fontFamily="@font/fauna_one"
android:text="Email"
android:textColor="@android:color/black"
android:textSize="20sp" />
<TextView
android:id="@+id/pr_phone"
android:layout_width="wrap_content"
110
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:fontFamily="@font/fauna_one"
android:text="Phone Number"
android:textColor="@android:color/black"
android:textSize="20sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</RelativeLayout>
<Button
android:id="@+id/btn_log_out"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="100dp"
android:layout_marginEnd="100dp"
android:text="Log Out"
android:background="@drawable/btn_register"
android:fontFamily="@font/fauna_one"
android:textColor="@android:color/white"
android:textSize="20sp"
android:textAllCaps="false"
android:outlineAmbientShadowColor="@android:color/black"
android:outlineSpotShadowColor="@android:color/black"
android:elevation="10dp"
android:shadowColor="@android:color/black"
android:shadowRadius="100"/>
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="40dp"
android:layout_marginBottom="40dp"
android:background="@color/bg_profile"
android:src="@drawable/ic_edit"
app:rippleColor="@color/ripple_effect_btn_sign_in"/>
</RelativeLayout>
111
Отзывы:
Авторизуйтесь, чтобы оставить отзыви хорошего настроения
удачи
успехов в конкурсе
Наверное было затрачено много времени и труда на работу
Продолжай свое исследование
Админам респект
Как на счет взаимных комментариев под работами?)
Красиво написанная работа
Так держать
Молодец
Интересная работа!