Пример создания мобильного приложения в 1С с нуля

Аватар пользователя mykib.org
Файлы для скачивания: 

В данной статье мы создадим мобильное приложение для ОС Android и ОС iOS.

По ходу создания, мы реализуем таймер средствами , реализуем программный вывод анимированной диаграммы на форму («Поле диаграммы» управляемой формы), также работу с PUSH-уведомлениями на мобильном устройстве, показ рекламы в приложении и работа со встроенными покупками.

Приложение для повышения продуктивности по «помидорной» технологии.

Позволю напомнить - метод Pomodoro заключается в делении вашего рабочего времени на 25-минутные отрезки, называемые «помидорами», между которыми вы можете позволить себе отдых в течение 5 минут. Вы должны работать без отвлечения 25 минут, затем 5 минут отдохнуть и приниматься за следующий рабочий «помидор». После четырёх таких отрезков — отдых на целых 15 минут.

 

Мобильное приложение Pomodoro

Описание «Помидорной» техники несколько странное, но стоит её попробовать, и Вы убедитесь, что это отличный способ повышения продуктивности работы.

Ссылка на приложение Скачать приложение для Android для повышения продуктивности по «помидорной» технологии

Создание конфигурации для мобильного приложения

Создадим новую «пустую» базу. Дадим имя конфигурации «Pomodoro». Обязательно укажем свойство «назначение использования» - «Мобильное приложение»

 

Укажем свойство «назначение использования» - «Мобильное приложение»

а в свойстве «Требуемые разрешения мобильного приложения» установим флажки «Локальные уведомления» и «Встроенные покупки»

 

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

Создадим регистр сведений, в котором будет храниться информация о «полученных» помидорах (количество законченных отрезков времени, в течение которого пользователь продуктивно работал)

 

Создадим регистр сведений, в котором будет храниться информация о «полученных» помидорах

Таймер средствами 1С

В обработке можно запустить таймер и дождаться окончания его работы, либо остановить таймер. В первом случае пользователь получит PUSH-уведомление о том, что он заработал очередной помидор (запись в регистр сведений «Помидоры»), во втором случае PUSH-уведомление о том, что помидор не получен (запись в регистр не производится).

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

Создадим обработку Таймер и основную форму

 

Обработка Таймер

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

 

&НаКлиенте
Процедура ЗапуститьТаймер(Команда)
	
	Элементы.ФормаОстановитьТаймер.Доступность = Истина;
	Элементы.ФормаЗапуститьТаймер.Доступность = Ложь;
	
	КоличествоМинут = 25;
	
	МаксимальноеЗначение = КоличествоМинут * 60;
	
	Элементы.Индикатор.МинимальноеЗначение = 0;
	Элементы.Индикатор.МаксимальноеЗначение = ЭтотОбъект.МаксимальноеЗначение;
	
	ЭтотОбъект.Начало = ТекущаяДата();
	ЭтотОбъект.Конец = Начало + МаксимальноеЗначение;
	
	ЭтотОбъект.ТекущаяДата = 		ТекущаяДата();
	
	ПодключитьОбработчикОжидания("ВыполнитьОтсчет",1);
	
КонецПроцедуры

 

И команду «ОстановитьТаймер», обработчик действия (нажатие):

&НаКлиенте
Процедура ОстановитьТаймер(Команда)
	
	Элементы.ФормаОстановитьТаймер.Доступность = Ложь;
	Элементы.ФормаЗапуститьТаймер.Доступность = Истина;
	
	ОтключитьОбработчикОжидания("ВыполнитьОтсчет");
	
	#Если МобильноеПриложениеКлиент Тогда
	Уведомление = Новый ДоставляемоеУведомление;
	Уведомление.Заголовок = "К сожалению, Вы не получите помидор.";
	Уведомление.Текст = "К сожалению, Вы не получите помидор.";
	Уведомление.ЗвуковоеОповещение = ЗвуковоеОповещение.ПоУмолчанию;
	ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
	ДоставляемыеУведомления.ПодключитьОбработчикУведомлений("ПриПолученииУведомления");
	#Иначе
	Сигнал();
	Сообщение = Новый СообщениеПользователю;
	Сообщение.Текст = "К сожалению, Вы не получите помидор.";
	Сообщение.Сообщить();
	#КонецЕсли
	
КонецПроцедуры

В этих процедурах подключается (либо отключается) обработчик ожидания «ВыполнитьОтсчет», а также выполняется работа с PUSH-уведомлениями

Уведомление = Новый ДоставляемоеУведомление;

Код процедуры обработчика ожидания ВыполнитьОтсчет»:

&НаКлиенте
Процедура ВыполнитьОтсчет()
	
	Если ЭтотОбъект.ТекущаяДата <= ЭтотОбъект.Конец Тогда
		
		ЭтотОбъект.Индикатор = ЭтотОбъект.ТекущаяДата - ЭтотОбъект.Начало;
		
		ЭтотОбъект.ТекущаяДата = 		ТекущаяДата();
		
		ОсталосьАбсолютно = ЭтотОбъект.МаксимальноеЗначение - ЭтотОбъект.Индикатор;
		
		ЭтотОбъект.Осталось = "" + Формат(Цел(ОсталосьАбсолютно/60), "ЧЦ=2; ЧН=00; ЧВН=") + ":" + Формат(ОсталосьАбсолютно - Цел(ОсталосьАбсолютно/60)*60, "ЧЦ=2; ЧН=00; ЧВН=");
		
		ЭтотОбъект.ОбновитьОтображениеДанных();
		
	Иначе
	
		ЭтотОбъект.Индикатор = МаксимальноеЗначение;
		ЭтотОбъект.ТекущаяДата = ЭтотОбъект.Конец;
		ЭтотОбъект.Осталось = Формат(0, "ЧЦ=2; ЧН=00; ЧВН=") + ":" + Формат(0, "ЧЦ=2; ЧН=00; ЧВН=");
		
		#Если МобильноеПриложениеКлиент Тогда
		Уведомление = Новый ДоставляемоеУведомление;
		Уведомление.Заголовок = "Вы собрали еще один помидор.";
		Уведомление.Текст = "Вы собрали еще один помидор. Отдохните " + ПолучитьКоличествоМинутОтдыхаНаСервере(ЭтотОбъект.ТекущаяДата) + " минут.";
		Уведомление.ЗвуковоеОповещение = ЗвуковоеОповещение.ПоУмолчанию;
		ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
		ДоставляемыеУведомления.ПодключитьОбработчикУведомлений("ПриПолученииУведомления");
		#Иначе
		Сигнал();
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Вы собрали еще один помидор. Отдохните " + ПолучитьКоличествоМинутОтдыхаНаСервере(ЭтотОбъект.ТекущаяДата) + " минут.";
		Сообщение.Сообщить();
		#КонецЕсли
		
		
		Элементы.ФормаОстановитьТаймер.Доступность = Ложь;
		Элементы.ФормаЗапуститьТаймер.Доступность = Истина;
		
		ОтключитьОбработчикОжидания("ВыполнитьОтсчет");
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция ПолучитьКоличествоМинутОтдыхаНаСервере(Дата)
	
	//Занесем запись в регистр
	РС = РегистрыСведений.Помидоры.СоздатьМенеджерЗаписи();
	РС.Активность = Истина;
	РС.Количество = 1;
	РС.Период = Дата;
	РС.Записать();
	
	//по умолчанию 5 минут
	//после каждого 4-го помидора в день - 15 минут
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	СУММА(Помидоры.Количество) КАК Количество
	|ИЗ
	|	РегистрСведений.Помидоры КАК Помидоры
	|ГДЕ
	|	Помидоры.Период МЕЖДУ НАЧАЛОПЕРИОДА(&Период, ДЕНЬ) И КОНЕЦПЕРИОДА(&Период, ДЕНЬ)";
	
	Запрос.УстановитьПараметр("Период", Дата);
	
	Результат = Запрос.Выполнить().Выгрузить();
	
	Если Результат.Количество() > 0  Тогда
		
		Сумма = Результат[0].Количество;
		
		Если Цел(Сумма/4) = (Сумма/4) Тогда
			
			Возврат 15;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат 5;
	
КонецФункции

Вывод PUSH-уведомлений реализуется так:

&НаКлиенте
Процедура ПриПолученииУведомления(Уведомление, Локальное, Показано) Экспорт
	Если Локальное Тогда
		Сообщить(Уведомление.Текст);
	КонецЕсли;
КонецПроцедуры

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Элементы.ФормаОстановитьТаймер.Доступность = Ложь;
	Элементы.ФормаЗапуститьТаймер.Доступность = Истина;
	
КонецПроцедуры

Статистика – диаграмма

Создадим обработку Статистика и основную форму

 

Обработка Статистика

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

Инициализация:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Для Каждого Стр Из ТипДиаграммы Цикл
		Элементы.ВидДиаграммы.СписокВыбора.Добавить(Стр, Стр, , );//Статистика
		Элементы.ВидДиаграммыПродуктивность.СписокВыбора.Добавить(Стр, Стр, , );//Продуктивность
	КонецЦикла;
	
	//Статистика
	Период.Вариант = ВариантСтандартногоПериода.ЭтаНеделя;
	Периодичность = "ДЕНЬ";
	
	ВидДиаграммы = ТипДиаграммы.Изометрическая;
	
	ОбновитьДиаграмму();
	
	//Продуктивность
	ПериодПродуктивность.Вариант = ВариантСтандартногоПериода.ЭтаНеделя;
	ПериодичностьПродуктивность = "ДЕНЬНЕДЕЛИ";
	
	ВидДиаграммыПродуктивность = ТипДиаграммы.Изометрическая;
	ОбновитьДиаграммуПродуктивность();
	
	
КонецПроцедуры

Вывод диаграммы:

&НаКлиенте
Процедура ВидДиаграммыПриИзменении(Элемент)
	ОбновитьДиаграмму();
КонецПроцедуры

&НаСервере
Процедура ОбновитьДиаграмму()
	
	// Очистить диаграмму, возможно ранее в нее уже выводились данные.
	Диаграмма.Очистить();
	
	//Диаграмма.ОбластьЗаголовка.Текст = "Статистика собранных помидоров";
	
	//Диаграмма.МаксимумСерий = МаксимумСерий.Ограничено;
	//Диаграмма.МаксимумСерийКоличество = 7;
	
	// Запретить обновление диаграммы на время вывода данных.
	Диаграмма.Обновление = Ложь;
	
	//Диаграмма.Анимация = АнимацияДиаграммы.Использовать;
	Диаграмма.ТипДиаграммы = ?(ВидДиаграммы <> Неопределено, ВидДиаграммы, ТипДиаграммы.ГистограммаОбъемная);//ТипДиаграммы.ГистограммаОбъемная;
	
	// Установить единственную точку.
	Диаграмма.КоличествоТочек = 1;
	Диаграмма.Точки[0].Текст = "Количество";
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	               |	НАЧАЛОПЕРИОДА(Помидоры.Период, ДЕНЬ) КАК Период,
	               |	СУММА(Помидоры.Количество) КАК Количество
	               |ИЗ
	               |	РегистрСведений.Помидоры КАК Помидоры
	               |ГДЕ
	               |	Помидоры.Период МЕЖДУ &НачалоПериода И &КонецПериода
	               |
	               |СГРУППИРОВАТЬ ПО
	               |	НАЧАЛОПЕРИОДА(Помидоры.Период, ДЕНЬ)
	               |
	               |УПОРЯДОЧИТЬ ПО
	               |	Период";
				   
				   
	Запрос.Текст = СтрЗаменить(Запрос.Текст,"ДЕНЬ" , Периодичность);
	
	Запрос.УстановитьПараметр("НачалоПериода", Период.ДатаНачала);
	Запрос.УстановитьПараметр("КонецПериода", Период.ДатаОкончания);
	
	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();
	
	ФорматнаяСтрока = "ДФ=dd.MM.yyyy";
	
	Если Периодичность = "МЕСЯЦ" Тогда
		ФорматнаяСтрока = "ДФ=MMMM.yyyy";
	ИначеЕсли Периодичность = "ГОД" Тогда
		ФорматнаяСтрока = "ДФ=yyyy";
	КонецЕсли;
	
	Пока Выборка.Следующий() Цикл
		
		КоличествоСерий = Диаграмма.Серии.Количество();
		Диаграмма.КоличествоСерий = КоличествоСерий + 1;
		
		Диаграмма.Серии[КоличествоСерий].Текст = Формат(Выборка.Период, ФорматнаяСтрока);
		Диаграмма.УстановитьЗначение(0, КоличествоСерий, Выборка.Количество);
	
	КонецЦикла;
	
	Диаграмма.ОбластьЛегенды.Прокрутка = Истина;
	
КонецПроцедуры

Управление рекламой

Для управления рекламой используется свойство глобального контекста «ОтображениеРекламы»

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

 

Управление рекламой

Включение показа рекламного баннера реализуем в Модуле управляемого приложения в процедуре ПриНачалеРаботыСистемы():

Процедура ПриНачалеРаботыСистемы()
	
	Если СлужебныйВызовСервера.ПоказыватьРекламу() Тогда
		#Если МобильноеПриложениеКлиент ИЛИ МобильноеПриложениеСервер Тогда
		ОР = ОтображениеРекламы;
		ОР.УстановитьИспользование(Истина);
		ОР.SetAdBannerID("ca-app-pub-1356011826682846/4780285411");
		ОР.УстановитьОтображениеРекламногоБаннера(ОтображениеРекламногоБаннера.Верх);
		#КонецЕсли
	КонецЕсли;
	
КонецПроцедуры

В строке ОР.SetAdBannerID("ca-app-pub-1356011826682846/4780285411") в параметре процедуры SetAdBannerID укажите Идентификатор рекламного блока, полученный в AddMod (https://apps.admob.com)

 

Идентификатор рекламного блока, полученный в AddMod

Управление покупками

Управление покупками выполняется в следующей последовательности:

		ВП = ВстроенныеПокупки;
		ВП.НачатьПриобретение();
		ВП.ИзрасходоватьПокупку();
		ОплатаПроизведена = ВП.НачатьПриобретение();

Комментарии

Аватар пользователя Александр

Хочу получить код
Аватар пользователя mykib.org

В верху прикреплен файл конфигурации 1С. Вот ссылка на него http://www.mykib.org/sites/default/files/downloads/pomodoro.zip
Аватар пользователя Вячеслав

Спасибо за пример! Посмотреть, поразбираться самое то. А нет простого примера работы мобильного приложения с информационной базой расположенной на сервере?
Аватар пользователя mykib.org

Вячеслав, именно примера нет, но как вариант, рекомендую книгу "Знакомство с разработкой мобильных приложений на платформе "1С:Предприятие 8", автор Е. Ю. Хрусталева
Аватар пользователя Гость

Скажите, есть ли возможность в мобильном приложении создать форму списка, например справочника сотрудников в которой бы отражались фото каждого сотрудника?
Аватар пользователя mykib.org

Можно, например, сделать: при активации строки списка выводить картинку сотрудника в отдельном поле (не в списке)
Аватар пользователя Malemute AKA Евгений Мамонтов

Владимир, день! Большое спасибо за статью и за пример. Как раз ищу возможности расширения навыков, чтобы выйти за пределы 1С, и создание мобильного приложения тут очень кстати. А есть ли спрос на мобильную разработку под 1С, не осталась ли она технической игрушкой?
Аватар пользователя mykib.org

... если учесть, например, возможности монетизации, встроенные в платформу: 1. Одноразовая покупка 2. Многоразовая покупка (расходуемая) 3. Подписка 4. Банеры Кстати, на первом этапе разаработки рекомендую не продавать свои приложения за деньги, не встраивать в них внутренние покупки, а делать только подписки.
Аватар пользователя Денис

Владимир, день! Большое спасибо за статью и за пример. Но я попробовал изменить его, но у меня стала такая форма http://prntscr.com/vd3q2u сколько не перезаписывал базу, не помогло. Если можно объясните в чём дело. Это первая мобильная конфигурация что смотрю
Аватар пользователя mykib.org

Вы запускаете тонкий клиент (или веб-клиент) - поэтому форма такая, как на Вашем скриншоте. Если запустить готовое приложение на гаджете или в эмуляторе мобильной платформы, то форма будет другой.