Разработка мобильных
приложений на
1С:Предприятие 8.3
Модуль 3
Уникальные возможности мобильной
платформы
Проект Курсы-по-1С.рф
2016
Курсы-по-1С.рф Профессиональные курсы по 1С
по всей России, в любое время
Оглавление
Предисловие ........................................................................................................................................................... 4
Уникальные возможности мобильной платформы ............................................................................................. 6
Конфигурация «Тестирование возможностей» ................................................................................................... 6
Кейс «Запись фото и видео в базу данных» ......................................................................................................... 7
Работа с мультимедиа ........................................................................................................................................ 8
Работа с фото ....................................................................................................................................................... 9
Работа с видео................................................................................................................................................... 10
Работа с аудио ................................................................................................................................................... 10
Результат мультимедиа .................................................................................................................................... 10
Что такое MIME Type......................................................................................................................................... 11
Расширенный кейс «Фото- и видеозапись» на Android .................................................................................... 13
Работа с экосистемой Android ............................................................................................................................. 14
Устройство механизмов взаимодействия между приложениями ............................................................... 14
Что такое broadcast ........................................................................................................................................... 15
Что такое intent, и как с ними работать из 1С ................................................................................................ 15
ЗапускПриложенияМобильногоУстройства (MobileDeviceApplicationRun) ..................................................... 17
ЗапускПриложенияМобильногоУстройства. Действие (Action) ....................................................................... 19
Что такое URI, Content и типы данных в дополнительных параметрах ........................................................... 21
Что такое URI ..................................................................................................................................................... 22
Что такое content (provider) ............................................................................................................................. 24
Тип данных в дополнительных данных .......................................................................................................... 26
Android Manifest, или как узнать, какое приложение нам подойдет .............................................................. 29
Пример разбора AndroidManifest ................................................................................................................... 31
Итоги ...................................................................................................................................................................... 32
Дополнения к модулю.......................................................................................................................................... 33
Приложение 1. Веб-камера на виртуальном устройстве .............................................................................. 33
Приложение 2. Установка GAPPS на эмулятор Android ................................................................................. 34
Приложение 3. Структура AndroidManifest .................................................................................................... 36
Тег <manifest> ................................................................................................................................................ 37
Тег <uses-permission> .................................................................................................................................... 37
Тег <uses-sdk> ................................................................................................................................................ 38
Тег <uses-feature>.......................................................................................................................................... 39
Тег <supports-screens> .................................................................................................................................. 40
Тег <application> ............................................................................................................................................ 41
Тег <activity> .................................................................................................................................................. 41
Атрибуты ............................................................................................................................................................ 42
Изменение конфигурации во время выполнения программы, параметр configChanges .......................... 42
Описание поведения формы и клавиатуры. Параметр android:windowSoftInputMode............................. 43
Страница 2 из 47
Страница 3 из 47
Предисловие
Данный модуль в преимущественно посвящен именно мобильной ОС Android, так как
текущий функционал Windows Phone и iOS не позволяет сделать большую часть того, что
доступно на Android.
Те, кто пытался работать со стационарной 1С через RDP клиент на сервере при помощи мобильного
устройства, поняли один важный момент – программа, разработанная под управление мышкой,
никак не может комфортно использоваться на сенсорных панелях. И первое, на что нужно обратить
внимание и запомнить:
Что это значит, и почему это так важно? Все очень просто:
Точность позиционирования у мышки – 0.5 мм, а у пальца – 5 мм, т.е. разница в 10 раз
Когда вы работаете с мышкой – вы не закрываете нижнюю часть экрана, и не теряете из виду
элементы управления
На компьютере не используют жесты, и нет такого понятия как активные стороны (например,
свайп слева на право от левого края экрана вызывает меню функций). Хотя начиная с Windows
8 и появились активные углы, но они все же относятся больше к самой Windows, чем к разным
программам.
И еще много разного рода нюансов. Но самое важное – это плотная интеграция в мобильную среду,
т.е. возможность использования особенностей мобильной ОС, для взаимодействия с пользователем
или системой.
Все программисты привыкли, что если надо использовать некий функционал, который недоступен в
самой 1С (например, надо узнать IP компьютера), то можно написать свой скрипт на VBS или JS,
который выполнит эту задачу и вернет результат в 1С. Можно даже использовать внешние
компоненты, которые очень сильно могут расширить возможности 1С. А с другой стороны, в 1С есть
часть встроенного функционала, например, печать документов. И возможности мобильной
платформы можно расширить, но немного по другим принципам – за счет «общения» с другими
приложениями в системе.
Страница 4 из 47
То же самое касается и мобильной платформы 1С. И это надо четко запомнить. Замена ОС Windows
на Android еще не означает потерю возможности взаимодействовать с окружающим софтом, а
скорее даже наоборот.
Что это значит? Это значит, что можно, например, отправить сообщение в Skype или открыть Google
Maps на нужных координатах. Но кроме этого в мобильной платформе есть функция
взаимодействия с приложениями с ожиданием ответа от них. По аналогии с модальным и
немодальным открытием форм. Т.е. в первом случае – мы ждем закрытия формы и продолжаем код,
а во втором – открываем форму и продолжаем выполнять основной код.
Например, мы можем инициировать окно включения bluetooth, если он выключен, или gps. Или даже
сделать фото отдельным приложением, а не предустановленной камерой от 1С.
1. Выполнить() – данная функция доступна только на Android и WinPhone. А это значит, что
не получится выполнить произвольный код в среде iOS, а это иногда очень удобно. Но это не
такая значительная утрата, как в случае пункта 2.
2. ЗапускПриложенияМобильногоУстройства()– эта функция используется для запуска
внешних программ в среде Android и недоступна на других ОС.
Пока эти ограничения кажутся незначительными, однако далее вы увидите, как много полезного
можно сделать с их помощью.
Страница 5 из 47
За каждым из этих пунктов кроется целая новая система с новыми типами данных, механизмами и
возможностями.
Страница 6 из 47
Поэтому нет необходимости писать весь код вручную, просто установите у себя эту конфигурацию и
на основании нее мы будем исследовать все возможности. Кроме того, эту же конфигурацию можно
использовать в качестве шаблонов определенных функций.
Как уже было сказано, есть достаточно много различных возможностей у мобильной платформы,
однако в этом модуле рассмотрим только одну из них – работу с мультимедиа.
Но рассмотрим не просто сам принцип работы с этим новым объектом в 1С, а попробуем
разобраться, как можно сделать то же самое, что умеет 1С, только другими средствами, и углубимся
в особенности ОС Android.
Самый главный вопрос, на который вы должны ответить в самом начале проекта – будете вы
поддерживать только ОС Android, или и другие ОС тоже? Это очень важно, в процессе изучения
этого модуля вы убедитесь в том, что те возможности, которые дает мобильная платформа на ОС
Android, настолько значительны, что могут сразу отсечь другие системы.
На первый взгляд эти задачи выглядят очень и очень просто, но когда займемся их разбором
детально, мы будем вынуждены погрузиться уже в особенности экосистемы Android.
Но, прежде чем это сделать, посмотрим, как все выглядит на iOS, то же самое можно наблюдать и
на WinPhone. Так как 1С на этих ОС ограничена в своих расширениях и во взаимодействии между
приложениями, то мы рассмотрим вначале эту задачу с точки зрения того, как ее можно было бы
решить только средствами 1С, а потом посмотрим, как можно расширить возможности и получить
дополнительный функционал.
Страница 7 из 47
Работа с мультимедиа
Начнем наше путешествие в мир мобильного функционала с самой простой и легко тестируемой
функции, а именно – с мультимедиа.
В 1С появился новый объект СредстваМультимедиа, именно он и отвечает за функционал фото,
видео, аудио и сканирования камерой (этот пункт рассмотрим позже). В целом весь этот объект
можно разбить на 3 части:
1. Проверка доступа
2. Выполнение действия (видео, фото и др.)
3. Прочие служебные функции: закрытие окна сканирования и получение доступных разрешений
камеры.
Для дальнейшего изучения посмотрим пример создания фотографии:
1. Если СредстваМультимедиа.ПоддерживаетсяФотоснимок() Тогда
2. Результат = СредстваМультимедиа.СделатьФотоснимок();
3. Если Результат = Неопределено Тогда
4. Сообщить("Отказ от действия");
5. Возврат;
6. КонецЕсли;
7. ДДКартинки = Результат.ПолучитьДвоичныеДанные();
8. Иначе
9. Сообщить("Не поддерживается фото!");
10. КонецЕсли;
В первой строке мы с вами должны убедиться, что есть возможность сделать фото. А когда такой
возможности может не быть? Рассмотрим это:
1. Пользователь запретил приложению доступ к камере телефона. Для тех, кто работает с iOS,
это вполне обыденная ситуация, когда при первом обращении к камере система спрашивает
пользователя, согласен ли он дать доступ к камере устройства. Для Android – это тоже вскоре
будет актуально (с выходом 6-й версии Android, где будет точно такой же механизм)
2. Мы не указали в настройках конфигурации, что разрешаем приложению использовать
мультимедиа. В этом случае у приложения также будет запрет на доступ, система даже
запрашивать разрешение для него не будет
3. На устройстве просто нет камеры. Тогда ясно, что фотографировать нечем
4. На устройстве есть камера, однако по каким-то причинам 1С ее не смогла определить. В этом
случае нужно писать в техподдержку 1С.
Во второй строке мы уже вызываем саму программу для создания фотографии. И тут может быть
два варианта:
1. Пользователь отказался делать фото (нажал кнопку Назад), тогда в результате данные не
будут получены
2. Пользователь сделал фото, и после этого форма закрылась, вернув при этом в результат –
само фото в виде двоичных данных.
Страница 8 из 47
После выполнения этой функции мы получим или пустые данные, или же получим само фото.
Работа с фото
Теперь детально пройдемся по фотографиям. Готовый код вызова программы для создания фото
выглядит вот так:
Если СредстваМультимедиа.ПоддерживаетсяФотоснимок(Камера) Тогда
Результат = СредстваМультимедиа.СделатьФотоснимок(Камера, РазрешениеФото, Качество,
Монохромное);
Иначе
Сообщить("Не поддерживается фото!");
КонецЕсли;
Разберемся с параметрами:
Вопрос о том, какая камера будет считаться задней на устройстве, где есть всего одна камера,
остается открытым. Вероятно, надо будет использовать именно камеру Авто.
РазрешениеФото – это тоже новый объект, но конструктор, т.е. мы его можем создавать:
Новый РазрешениеКамерыУстройства(<Ширина>, <Высота>)
Где ширина и высота – это число. У каждой камеры есть свои разрешения, которые она
поддерживает. Если указать разрешение, которое не поддерживается камерой, то 1С возьмет
максимально приближенное разрешение камеры.
Это удобно: если у вас «зоопарк» устройств, и вам нужны фотографии разрешения 1920х1080, то вы
просто указываете его, и если вдруг камера такое разрешение не поддерживает, то будет взято
максимально близкое к нему. Это актуально на высоких разрешениях, ведь у большинства стоят
камеры 5 Мп, а у немногих есть и 8 Мп, и 13 Мп и больше. Если же вы хотите получить доступные
разрешения, то можно выполнить вот такую функцию:
РазрешенияКамеры = СредстваМультимедиа.ПолучитьПоддерживаемыеРазрешенияКамеры(Камера);
В данном случае вы получите массив всех доступных разрешений. Это удобно, если вы хотите дать
пользователю возможность выбора разрешения.
Однако этот параметр доступен только на Android. Поэтому вам будет возвращено значение
Неопределено, а сам параметр игнорируется, даже если вы его укажете.
У этого параметра есть одна особенность – если вы решите его вывести на форму, чтобы
пользователь сам выбирал разрешение, то не сможете заполнить этот элемент программно. Т.е.
если вывести на форму элемент, где есть список всех доступных разрешений, и попытаться указать
изначальное разрешение, то 1С вернет ошибку. Это, скорее всего, баг – надеемся, его скоро
исправят.
Страница 9 из 47
Качество – качество фотографий, это число от 1 до 100. Чем число больше, тем лучше качество и
тем больше будет объем занимаемого места. Этот параметр также используется только на
Android.
Монохромное – сделанное фото будет черно-белым.
Работа с видео
Если СредстваМультимедиа.ПоддерживаетсяВидеозапись(Камера) Тогда
Результат = СредстваМультимедиа.СделатьВидеозапись(Камера,КачествоВидео);
Иначе
Сообщить("Не поддерживается видео!");
КонецЕсли;
С видео все немного проще, тут только два параметра. С параметром Камера мы уже знакомы.
КачествоВидео – это предопределенный объект, а не число, как в случае с фото. И может
принимать только три значения – высокое качество или низкое, или режим авто.
КачествоВидео = КачествоВидеозаписи.Авто;
Работа с аудио
Тут вообще все просто.
Если СредстваМультимедиа.ПоддерживаетсяАудиозапись() Тогда
Результат = СредстваМультимедиа.СделатьАудиозапись();
Иначе
Сообщить("Не поддерживается аудио запись!");
КонецЕсли;
Результат мультимедиа
Но после того, как выполнена любая из этих функций, надо обработать их ответ. В этом ничего
сложного нет. В ответ от каждой из этих функций получим значение с типом ДанныеМультимедиа.
Если обратиться к справке 1С, то увидим структуру этих данных:
ДанныеМультимедиа (MultimediaData)
Свойства:
РасширениеФайла (FileExtention)
ТипСодержимого (MIMEType)
Методы:
ПолучитьДвоичныеДанные (GetBinaryData)
Описание:
Содержит данные мультимедиа.
Страница 10 из 47
Итак, у нас есть метод, выполнив его, получаем двоичные данные, которые впоследствии можно
записать в файл или поместить в хранилище и записать в регистр. Тут все, как и в случае со
стационарной конфигурацией.
Страница 11 из 47
Обозначим в таблице разными цветами группы типов в в зависимости от того, какие виды программ
используются для открытия файлов с указанным расширением. Т.е. синие типы мы бы открывали
видеопроигрывателем, оранжевые – текстовым редактором, зеленые – просмотрщиком
изображений, а красные – при помощи архиватора.
В чем же разница между обычными расширениями? А в том, что типы данных дают большую
гибкость. обратите внимание на расширение zip, у которого есть 4 типа данных: 3 типа говорят, что
его можно открыть при помощи приложения, а последний – о том, что это не целый файл, а всего
лишь его часть.
Итак, подведем краткий итог – MIME типы связаны с расширениями, чаще всего именно по ним и
определяется тип данных. Например, когда вы выбираете файл для загрузки в браузер и браузер
отправляет файл на сервер, то сервер проверяет тип данных файла не по расширению, а по типу.
Существует несколько основных типов и подтипов MIME, а именно:
text – текстовая информация. Основой подтип – plain соответствует обычному
неформатированному тексту и не требует специального программного обеспечения для
отображения этого. Другие подтипы, кроме plain, используются в случае, когда с помощью
специальной программы можно улучшить его отображение. Например, вы отправляете файлы
с исходниками 1С, xml и html.
Естественно, их все можно открыть просто в браузере как неразмеченный текст, а можно
открыть и при помощи синтаксической разметки. Тут же стоит обратить внимание на то, что xml
и html файл можно определить, как тип text/xml, а вот 1С – только как text/plain, так как у 1С
нет международного подтипа, который был бы зарегистрирован. Однако вы спокойно можете
создать свой личный подтип text/1C и прописать правила преобразования на сервере, но,
разумеется, это поймет только ваш сервер, а все остальные – не будут понимать подтип 1С и
будут просто выводить его по основному типу, т.е. как обычный текстовый документ
image – графические данные
audio – звуковая информация
video – видеоинформация
application – как правило, неинтерпретируемый двоичный код, который необходимо выполнять
в определенной среде или при помощи специализированного софта.
Конечный вариант типа выглядит как «тип»/«подтип». И что же это дает? А дальше увидим, что в
системе Android, можно (а в некоторых местах необходимо) указывать типы данных – для
упрощения выполняемых задач.
Страница 12 из 47
Подведем итог: MIME типы нужны для того, чтобы можно было делать отборы и указывать
программам, с каким типом данных мы хотим заставить их работать. Если программа не умеет с
этим типом работать, то она просто не будет отображаться в списке доступных вариантов открытия.
Например, в случае, когда хотим открыть фото внешней программой, указываем тип открываемых
данных, и Android предложит на выбор только те программы, которые поддерживают этот тип.
Теперь уже все стало немного сложнее, ведь 1С не поддерживает данный функционал, однако у 1С
есть возможность запускать внешние программы на устройстве, передавать в них параметры и
получать результат выполнения. Увы, но весь этот функционал недоступен на iOS и Windows
Phone.
Страница 13 из 47
Итак, теперь осталось только разобраться, как это все работает. А тут – практически все новое.
Все, о чем будем говорить в данном разделе, упрощено, поэтому некоторые вещи вы никогда не
увидите в реальной жизни в среде Android, а другие могут звучать не совсем корректно, так как мы
постараемся изучить это все с точки зрения программистов 1С и с точки зрения возможностей
фреймворка 1С на ОС Android.
Но если немного углубиться, то увидим, что механизмов взаимодействия очень много. К примеру,
рассмотрим один самый простой вариант – передачу файла из одной программы, в другую.
Например, мы получили файл по почте и хотим открыть в редакторе.
В среде Windows можно написать обработку, которая подключится к серверу и выгрузит файл «куда-
то» на диск D или во временную папку 1С, и запустить, к примеру, редактор изображений paint с
параметром, который позволит открыть этот файл. В Android – можем передать просто путь к файлу
или передать контент (content), а можем просто послать в другое приложение двоичные данные,
минуя файл.
Один из основных механизмов взаимодействия между приложениями – это работа через intent
(намерения), но есть еще и broadcast (только он не доступен). Рассмотрим эти два варианта
взаимодействия между приложениями и проведем аналогию с 1С.
Страница 14 из 47
Эта функция посылает во все формы оповещение. В Android то же самое, только в масштабах всей
системы в целом.
Страница 15 из 47
Кроме этого, намерения могут быть вызваны с целью получения результата ответа (например, при
закрытии), или же просто нас интересует сам запуск, например, если строим навигационный
маршрут. По аналогии с 1С – запуск происходит модально или немодально. Но чаще всего в Android
делается немодальный вызов намерения, а потом просто отлавливается глобальное событие, тот
самый broadcast, который не доступен на текущий момент в 1С. Т.е. асинхронный вызов. Это сейчас
становится популярным и в 1С.
Сравним код в Android с 1С и попробуем вызвать одно и то же намерение.
Вот так выглядит запуск браузера на Android, с переходом на конкретный адрес сайта:
1. URI address = Uri.parse("http://курсы-по-1с.рф/");
2. Intent openlink = new Intent("com.test.someact", address);
3. startActivity(openlink);
Т.е. с точки зрения выполнения кода эти два примера приведут к одному и тому же результату.
Обратите внимание: в данных примерах мы просто пытались вызвать намерение, причем без
обработки результата. А теперь посмотрим вариант, когда нам нужен результат выполнения,
например, выбор файла:
public void onClick(View arg0) {
//Создаем намерение для выбора файла
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
//Указываем тип выбираемых данных, тот самый MIME тип, о котором м ы говорили ранее
intent.setType("file/*");
//Запускаем намерение с желанием получить результат
startActivityForResult(intent,PICKFILE_RESULT_CODE);
//код уходит дальше, если он есть.
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode){
case PICKFILE_RESULT_CODE:
//если файл был выбран и обработка прошла без ошибок
if(resultCode == RESULT_OK){
//тогда получаем путь выбраного файла
String FilePath = data.getData().getPath();
//и пишем его в текстовый файл
textFile.setText(FilePath);
}
break;
}
}
Страница 16 из 47
Основное отличие тут в том, что нет возможности получать асинхронный ответ, т.е. мы обязаны
ждать, пока приложение закроется и вернет ответ в 1С.
Как вы уже могли догадаться – есть новый объект в 1С, который позволяет нам работать с
намерениями.
ЗапускПриложенияМобильногоУстройства
(MobileDeviceApplicationRun)
Свойства:
Данные (Data) – это строка (URI) к данным, которые мы хотим передать. Т.е. через этот
параметр мы можем передавать только ссылку на данные, а не сами данные
Действие (Action) – тут мы указываем, что именно мы хотим сделать, т.е. ради какой цели мы
создаем намерение. В нашем случае – это были android.intent.action.GET_CONTENT.
ИмяКласса (ClassName) – это имя класса, которое необходимо в случае, когда надо указать
конкретные параметры для запуска намерения. Обычно состоит из полного имени пакета
приложения (UID приложения) плюс имя самого класса
Категория (Category) – уточнение действия, дополнительный фильтр для намерений. Обычно
редко используется
Приложение (Package) – имя приложения, из которого мы хотим вызвать некое действие,
описанное в намерении. Например, у нас есть 10 редакторов картинок, а мы хотим
использовать только конкретный редактор, тогда пишем тут имя пакета этого приложения. Т.е.
именно тут мы указываем – хотим сделать явный вызов или неявный
Тип (Type) – это указание MIME типа, о нем мы уже говорили ранее. Иногда является
обязательным для успешного запуска намерения
ДополнительныеДанные (AdditionalData) – это набор элементов, вида Ключ+Значение+Тип
(тип именно значения, а не тип данных, т.е. не MIME тип). Используется в случае, если надо
передать дополнительные параметры.
Страница 17 из 47
Методы:
Запустить (Run) – это функция, она возвращает результат. Результат имеет тип число, если
результат равен нулю, то значит, произошла ошибка. Иначе – все закончилось хорошо. Обычно
удачный ответ это 1 или -1, т.е. не равен 0, но тут уже кто как напишет программу. Этот метод имеет
один параметр типа булево. Если параметр Истина, то мы ждем, пока запущенное намерение не
вернет ответ, если Ложь, то запускаем намерение и идем дальше.
Описание:
Доступность:
Мобильное приложение(клиент).
Это основные вводные данные, которые нужно знать. Все эти данные можно найти в файле
AndroidManifest.
AndroidManifest (далее просто манифест) – это самый главный файл в абсолютно каждом
приложении, он есть во всех приложениях, в том числе и в мобильной 1С. По структуре своей – это
xml файл. Манифест описывает всю структуру приложения. А именно:
Имя приложения – помните, мы создавали для нашего приложения 1С свой ID, например,
com.e1c.mobile.
SDK – минимальную версию Android, на которой это приложение может работать, чаще всего эта
версия определяется набором используемых функций.
Все права доступа. Т.е. каждое приложение должно в манифесте прописать все необходимые ему
доступы. Если, к примеру, у приложения нет в манифесте описания, что ему нужны права на чтение
SMS, то при попытке получить доступ к SMS будет вызвано исключение. Таким образом, если вы в
1С хотите иметь доступ к чтению SMS, но при этом не указали это в доступах:
Страница 18 из 47
При компиляции приложения из манифеста будет исключено это право, и Android вам не даст
возможности прочитать SMS или получить доступ к фотокамере.
ЗапускПриложенияМобильногоУстройства.
Действие (Action)
Итак, в Android есть аналоги форм в 1С, они называются activity или же просто – активности. Эти
активности все прописываются в файле AndroidManifest и могут быть публичными, т.е. реагировать
на вызов намерения (у таких активностей должен быть прописан фильтр намерений, на которые они
могут откликаться), или же быть приватными (обычно используются только внутри приложения).
Но если в случае 1С для открытия формы нужно указать путь к ней, то в случае Android требуется
указать действие, которое мы хотим совершить, а уже активность сама решит, может она
обработать это действие или нет.
Действия могут быть как «самоопределяемыми», так и «штатными». Т.е. можно создавать их
произвольно, но также в системе есть и ряд предопределенных действий.
Обычно все стандартные действия четко описаны в справке, и, по идее, все разработчики должны
следовать справке, если хотят обрабатывать стандартные действия. В реальности же все немного
не так, и часть разработчиков откровенно не следует этому пути, поэтому к каждой программе все
равно надо искать свой подход.
Страница 19 из 47
Что касается имен действий и переменных – надо запомнить, что в Android очень многое сделано в
виде констант. Т.е. действия, как они описаны в справке – это всего лишь константы, строковые,
помните, мы разбирали такие строки:
Какие же могут быть предопределенные действия? Все очень просто – большая часть из
стандартных действий доступна в Android SDK, а именно:
C:\SDK\platforms\android-17\data\activity_actions.txt
Обратите внимание, что на разных версиях Android доступны разные возможные действия,
например, у Android 4.2 (он же SDK 17, у разработчиков нет обычно понятия версии Android как
таковой, а есть версия SDK, и именно по ней ориентируются разработчики) есть набор из 90
предопределенных действий, а вот у Android 5.1 (SDK 22) – уже более 120.
Кроме того, чтобы каждый раз не искать и не вспоминать, какие из действий вам будут интересны,
часть из них можно просматривать в конфигурации, а также добавлять туда свои и тестировать их
там же.
Страница 20 из 47
Как обычно происходит настройка загрузки и сама загрузка файлов? Самым обычным способом:
выбираем каталог, после этого в 1С сохраняется путь, и в фоне 1С загружает данные.
Самый «скользкий» момент тут состоит именно в моменте выбора, а именно – мы под
пользователем выбрали каталог, нажали тестовую загрузку – все получилось, оставили настройки и
все. И через некоторое время узнаем, что обмен не делается – почему? А потому что у
пользователя, под которым выполняется загрузка, нет прав на эту папку, а иногда нет прав просто
на запись в эту папку, поэтому читать файл 1С может, а вот положить свой файл или изменить – нет.
И самое печальное тут то, что под вашим пользователем, если вы запустите выгрузку или загрузку,
все пройдет без ошибок. Через это должен пройти каждый начинающий программист, и на эту тему –
каждый программист должен отругать системного администратора, который не дал права
пользователю 1С, под которым работают фоновые задания. Но, как было бы хорошо, если бы 1С
получала доступ куда угодно, когда нам это надо, ведь правда? Тогда бы не было ошибок такого
рода.
Так вот, в Android так и есть. Конечно, мы рассмотрим слишком упрощенный вариант, но этого будет
достаточно для понимания основной идеи.
Страница 21 из 47
Итак, в Android есть два (основных) варианта указания пути к файлу, мы их могли видеть на примере
из видео, давайте этот пример посмотрим еще раз:
Но и сам по себе URI – это не просто строка, а объект, который может формироваться на основании
строки. Приблизительно так же, когда мы делаем некий веб-запрос из 1С, мы создаем http-
соединение на основании строки, но если откроем этот объект, то увидим, что там вся строка
разбита на части, есть отдельно схема (http), порт, адрес сайта, пользователь и т.д.
Если мы ссылку выше рассмотрим именно как объект URI, то он будет выглядеть вот так:
uri.getScheme(): http
uri.getSchemeSpecificPart(): //fs.kursy-po-1c.ru/files/ufm-player/uvfPlayer.exe
uri.getAuthority(): fs.kursy-po-1c.ru
uri.getHost(): fs.kursy-po-1c.ru
uri.getPath(): /files/ufm-player/uvfPlayer.exe
uri.getLastPathSegment(): uvfPlayer.exe
Страница 22 из 47
Свойство Значение
Scheme http
Scheme-specific part //username:password@host:8080/directory/file?query#fragment
Authority username:password@host:8080
User Info username:password
Host host
Port 8080
Path /directory/file
Query query
Fragment fragment
Главное – это то, что URI указывает местонахождение не только обычной информации (файл, папка
и т.д.), но и абстрактной. Например, у каждого контакта в записной книжке есть свой URI, с помощью
URI можно также указать координаты и так далее, вот несколько примеров:
tel: +7111111111
sms: +7111111111
sms: +7111111111,+555555555
geo:46.4984,30.7234?z=19
content://contacts/people/1
mailto:ggg@ggg.com,ffff@kkk.err
Все это URI. Как вы могли догадаться, по первой части (ее называют схемой или протоколом)
Android определяет, что это за тип данных, а по второй – ссылка ли это на данные, или сами
данные.
Однако нас интересуют две конкретные схемы, а именно:
File, после которого идет указание обычного пути, как мы привыкли в Windows
Content, а вот это уже другой тип ссылки.
Если вернуться к нашей «выдуманной» проблеме про доступы, то точно такая же проблема будет
присутствовать и в мобильной платформе при использовании схемы file. Чаще всего она
проявляется в случае, когда мы хотим сделать фото и указываем путь к фотографии, используя эти
конструкции:
ПолучитьИмяВременногоФайла()
КаталогВременныхФайлов()
Почему? Все просто: эти каталоги находятся внутри закрытого раздела, доступ к которому имеет
только 1С, ну и системные программы, а вот приложение, которое делает фото, не является
системным, и, естественно, оно не может ничего записать туда. Но можно воспользоваться другим
вариантом:
КаталогДокументов()
"//sdcard/Download/temp.png"
Страница 23 из 47
И фото будет сделано без проблем. Однако если первые функции удобны тем, что сам Android
может их почистить и удалить лишний мусор, то в этом случае придется делать это вручную.
Как видите, проблема, описанная выше, никуда не делась, но, как уже упоминалось ранее, на
Android все по-другому. И действительно, если мы будем использовать content, то тогда проблем с
доступами не будет.
Где, content – это схема данных, contacts – провайдер, people – имя таблицы, откуда мы хотим
получить данные, а 1 – это индекс самих данных.
Провайдеры есть стандартные, но вы можете создать и свои собственные. Набор стандартных
провайдеров выглядит вот так:
Browser
CallLog
Contacts
o People
o Phones
o Photos
o Groups
MediaStore
o Audio
o Albums
o Artists
o Genres
o Playlists
o Images
o Thumbnails
o Video
Settings
Страница 24 из 47
Т.е. если вы хотите получить доступ к контактам, то программа, при помощи которой вы выбираете
этот контакт, может вам вернуть ссылку на данные в виде стандартного провайдера contacts, а
может и в виде своего провайдера. Причем и в первом, и во втором случае ссылка может вести в
одно и то же место.
Что касается файлов, представим себе другую ситуацию. К примеру, у нас есть две базы данных, на
базе УТ11. И у них есть доступ к фотографиям, которые находятся на диске компьютера, на котором
эти базы установлены.
Итак, есть две базы (Б1 и Б2), в них есть две одинаковые номенклатуры (А1 и А2), и чтобы не
засорять диск одинаковыми данными, мы прикрепили к товару в каждой из баз одну и ту же
фотографию (Ф), оставим вопросы этичности такого подхода.
Прикрепляя эти фотоданные в базу, мы внесли в таблицы этих баз информацию о том, что
фотография находится по пути «C:\photo\A.png». Обратите внимание – путь к фото у базы Б1 и Б2
одинаковый, и это логично, ведь мы берем одно и то же фото. А задача наша заключается в том,
чтобы через обработку получить это фото, например, для того, чтобы его вывести в прайс-лист. Что
в данном случае происходит:
Во-первых, мы должны решить, в какой базе мы это будем делать? Т.е. это Б1 или Б2? В
аналогии с Android – выбираем приложение, при помощи которого мы хотим выбрать некий
файл (ES Explorer, Галерея, Яндекс Диск и т.д.)
Во-вторых, мы должны выбрать товар, фото которого мы хотим получить, а может, и просто
отрываем сразу список всех фото, и выбираем среди них, в самой базе. Аналогично в Android –
мы определяем нужный нам файл в приложении, которое мы выбрали
Ну и напоследок – мы в случае 1С получаем ссылку на элемент справочника, где есть
информация про это фото, а в случае Android – мы можем получить ссылку в виде контента.
Теперь самое интересное – нужно получить само фото, в случае 1С – мы просто обратимся к
реквизиту Путь элемента справочника и получим абсолютный путь, по которому мы можем
получить уже само фото. А в случае Android – мы можем сделать «резолв контента»
(getContentResolver), т.е. на основании контент-ссылки – мы получим абсолютный путь, если в этом
есть необходимость.
Ну и вот теперь мы приходим к решению проблемы с правами доступа, а именно, если мы получим в
1С абсолютный путь, это не факт, что мы сможем получить само фото, так как обработка получения
фото происходит в контексте сервера, а значит, и под пользователем 1С (в случае SQL версии). Т.е.
если попробовать выполнить процедуру поиска фото в контексте клиента, можно к нему и не
достучаться, так как у нашего пользователя не будет прав, но при этом – можно поместить данное
фото в хранилище и передать его на клиент, где возможно работать уже с самим объектом.
В Android происходит нечто аналогичное: когда мы пытаемся указать фотокамере, чтобы она
записала данные во временные файлы 1С, то ничего не выйдет, так как мы ей даем абсолютный
путь, доступ по которому закрыт для внешней программы, а вот если бы мы могли указать контент-
ссылку, то такого можно было бы избежать.
Страница 25 из 47
Итого: контент-провайдер – это объект, который позволяет обратиться к данным одного приложения
из другого, причем у второго приложения может не быть доступа к этим данным напрямую. Кроме
этого, контент-ссылки могут указывать не только на некий конкретный файл, но и на таблицу
(например, контакты) или на конкретный контакт.
Как видите, количество вариантов ссылок огромное, и при этом некоторые возвращают не только
контент-ссылку, но и абсолютный путь. Эта ссылка отличается от той, которую мы взяли за основу,
но все они ведут в одно и то же место.
//Тут указываем путь, при чем путь должен быть доступен всем программам, так что
временные файлы 1С не пойдут
ФайлКартинки =ПутьДляСохраненияФайлов + "FotoTestFrom1C.png";
НовВз = Новый
ЗапускПриложенияМобильногоУстройства("android.media.action.IMAGE_CAPTURE");
НовВз.ДополнительныеДанные.Добавить("output",ФайлКартинки,"Uri");
Здесь нас интересует часть, куда мы вставляем дополнительные данные (при разработке на Android
говорят: «добавить экстрасы», от команды putExtra). Однако в случае Android – это массив
соответствий, т.е. пара ключ и значение, где как ключ, так и значение могут быть разных типов, ну
так же, как и в 1С.
Страница 26 из 47
ЭлементДополнительныхДанныхЗапускаПриложенияМобильногоУстройства
(MobileDeviceApplicationRunAdditionalDataItem)
Свойства:
Значение (Value)
ИмяТипа (TypeName)
Ключ (Key)
Описание:
Доступность:
Мобильное приложение(клиент).
В нашем случае есть проблема, так как мы разрабатываем решение на фреймворке 1С, а у 1С есть
свои типы. В случае большинства других языков программирования примитивные типы данных
совпадают, и обмен информацией между этими языками не создает затруднений. В случае 1С – все
немного не так, а именно – с целью упрощения в 1С отказались от многих типов, например,
числовых типов, таких как int, byte, float и т.д.
Т.е. когда мы создаем переменную с типом число, мы можем указать только ее разрядность, т.е.
сколько нулей в ней будет, но не ее размерность. В других же языках это строго типизировано, т.е.
тип int – это ТОЛЬКО целые числа в диапазоне от -2147483648 до 2147483647, и кодирование
одного такого числа занимает 32 бита, а 1С обычно оперирует типом double, его разрядность 64
бита, и оно может иметь значения в диапазоне 1,7e-308 < |x| < 1,7e308. Т.е. теоретически, если бы
мы могли указывать типы, то в определенных моментах – можно было бы экономить оперативную
память и физическую, так как при создании переменной с определенным типом под нее выделяется
пространство в памяти.
Страница 27 из 47
На практике все не так гладко, поэтому в 1С, наверное, поступили правильно, что отказались от
типов, так как это не нагружает программистов дополнительными определениями каждый раз, и
эффективное использование типов наблюдалось бы только в небольшом проценте проектов, тем
более, сравнение чисел двух разных типов – еще та интересная задачка, которая создала бы просто
огромный полигон для ошибок, а числа в 1С – это чуть ли не самое важное.
Однако это создало нам проблему, теперь, когда мы хотим передать данные в некое приложение на
Android, мы должны передать map (т.е. соответствие), а тут очень важен тип данных, например,
передаем параметр:
file:///sdcard/Download/FotoTestFrom1C.png
Возникает вопрос – это URI (т.е. объект) или просто некая строка? Если бы мы передавали данные
между приложениями, которые написаны сразу под Android, то мы могли бы просто передать объект
URI или просто строку, и вопросов бы не было. Однако, в 1С нет типа URI. Поэтому существует
третий параметр – тип данных.
Типы, которые 1С умеет конвертировать из своих типов в типы Android – выглядят так:
byte, char, double, float, int, long, short, boolean, String, URI, Bitmap, Account, Address, Location
Но, автоматически, т.е. если мы не указываем тип вручную, конвертация будет такая:
Строка –> String,
Булево –> boolean,
Число –> double,
НавигационнаяСсылка –> String,
ДанныеМестоположения –> Location,
ДанныеАдреса –> Address,
Картинка –> Bitmap,
УчетнаяЗаписьКонтакта –> Account.
Т.е. если приложение, которое делает фото, ждет от меня URIссылку на файл картинки, и я не
указываю третий параметр (т.е. тип данных), и не говорю, что это именно URI, то 1С конвертирует
это как строку, и естественно – программа, которая ждет на вход тип URI, а получает тип String – не
сможет корректно обработать запрос.
То же самое касается, например, если мы хотим передать числовой параметр: если программа ждет
именно тип int, значит, мы это и должны указать.
Страница 28 из 47
Тезисно резюмируем:
1. Стандартные намерения – не такие уж и стандартные, так как есть много условий для того,
чтобы они работали, например: версия Android (точнее SDK), наличие Google сервисов,
наличие предустановленных приложений, способных обрабатывать эти стандартные
намерения, и т.д
2. 1С не умеет работать с URI типа content, но она может хранить ссылку на данные в виде строки
и передавать ее в другие приложения, которые умеют с ними работать
3. На слабых устройствах может быть проблема, которая проявляется в том, что после вызова
тех или иных действий Android может закрыть 1С, если у него не хватит памяти, например,
если вы планируете строить маршрут в навигаторе и открывать его через 1С, то лучше
ориентироваться на то, что с вероятностью 99% 1С в режиме ожидания проработает только
несколько секунд, а потом Android ее просто закроет.
android.intent.action.GET_CONTENT
С помощью него можно вызвать диалог выбора данных, и у нас есть MIME типы, и среди них есть
даже такой тип, как:
folder/*
И вроде все хорошо в теории, т.е. мы можем вызвать намерение, передать в него тип – каталог, и
тогда, чисто теоретически, мы должны иметь возможность выбора каталога. Но есть проблема,
которая связана с тем, что поддержка каждого типа лежит на совести разработчиков приложений.
Т.е. если разработчики предусмотрят в своей программе обработку этого типа, то все будет хорошо,
а если нет, то будет одно из двух: или просто не отработает вызов действия, или приложение
проигнорирует нестандартный для него тип и посчитает его аналогом типа «*/*» и позволит
выбирать, опять-таки, все файлы.
Но, на видео мы все-таки смогли открыть программу и вызвать при этом выбор каталогов, причем
мы использовали нестандартное действие, давайте посмотрим на данный код:
Страница 29 из 47
ДейтвиеВызова =
?(ВыборПапки,"com.estrongs.action.PICK_DIRECTORY","com.estrongs.action.PICK_FILE");
Давайте разберем этот код. Во-первых, мы с вами определяемся, что вызвать – диалог выбора
файла или же каталога. После этого фиксируем текущую дату и выполняем намерение, получив
результат, нам надо понять, был выбор данных или нет, т.е. выбрал пользователь каталог или нет.
И возникает проблема, которая заключается в том, что мы указываем действие, которое сможет
обработать только конкретное приложение. Суть проблемы заключается в ответе на вопрос:
пользователь сам отменил выбор, т.е. нажал кнопку «Назад», или же на данном устройстве просто
не установлено приложение? В случае нативной разработки под Android – мы бы могли обработать
ответ, и даже больше – при запуске программы просто проверить, установлено ли нужное нам
приложение или нет.
Поэтому нужно понять, что следует сделать: или обрабатывать результат = 0, как отмену
пользователя, или предложить пользователю установить необходимый софт. Так как этот софт сам
пользователь может спокойно удалить, если потребуется.
Страница 30 из 47
И вот для того, чтобы ответить на этот вопрос, фиксируем время запуска и время завершения
приложения. И если разница между запуском приложения и получением результата меньше 100 мс,
то считаем, что произошла ошибка, в нашем случае – это значит, что приложение не установлено,
так как пользователь просто не успеет так быстро нажать кнопку «Назад» и прорисовка интерфейса
займет явно больше 100 мс. И если такое произошло, то мы предлагаем пользователю установить
нужное приложение.
Путь = СтрЗаменить(НовВз.Данные,"file://","");
Т.е. 1С умеет принимать только path, без указания типа схемы, так как сама 1С при конвертации этих
данных составляет полный URI. Мы уже знаем, что URI должен обязательно содержать схему, но,
вероятно, 1С сама указывает схему file по умолчанию, и это одна из причин, по которой мы не
можем использовать в 1С URI, сформированные на базе content.
Далее мы проверяем, есть ли у нас доступ к выбранному файлу. Это важно, поскольку на этом этапе
мы сразу отсекаем все URI на базе схемы content. И сразу отсекаем файлы, к которым 1С не имеет
доступа, чтобы не случилось так, что пользователь выбрал файл, который доступен только этому
приложению (ведь мы помним, что в случае content’а, такой проблемы можно было бы избежать).
Но это все не дает нам ответ на вопрос – откуда мы взяли вот эти данные:
ДейтвиеВызова =
?(ВыборПапки,"com.estrongs.action.PICK_DIRECTORY","com.estrongs.action.PICK_FILE");
App Detective.
Страница 31 из 47
В этом же видео мы разобрали, откуда взялись нестандартные действия при выборе каталога или
файла через программу ES Explorer. Таким же образом можно искать разные приложения и,
анализируя их, делать выводы, подойдут они вам или нет.
Итоги
Данный модуль можно назвать введением в разработку под Android, так как немалая часть
исследуемого функционала может быть использована только тогда, когда есть понимание о том, как
устроены Android и его экосистема в целом.
Из этого модуля можно вынести больше, чем кажется на первый взгляд: так как 1С тоже является
мобильным приложением, значит, и на нее распространяются все те же правила, что и на остальной
софт. Например, при разборе AndroidManifest мы говорили о том, что можно указать ориентацию, а
это значит, что если мы сгенерируем манифест для 1С правильно, то сможем сделать так, чтобы 1С
по-другому реагировала на клавиатуру, или, например, не поворачивалась при повороте экрана и
т.д.
И необходимо уяснить, что мы уходим в экосистему Android, а значит, можем спокойно искать
информацию на Android форумах. Например, нужно отправить файл через Google Drive или Яндекс
диск, или Dropbox. Как это сделать? Ответ на этот вопрос лучше всего искать на форумах Android, а
не 1С. Но, к сожалению, мы весьма ограничены возможностями 1С, чего стоит только эта проблема
с контентом. Но, тем не менее, функционал будет расширяться, а значит, за ним надо следить.
Страница 32 из 47
Дополнения к модулю
Приложение 1. Веб-камера на виртуальном устройстве
Если вы используете Android эмулятор, и у вас есть веб-камера, то можно подключить эту камеру к
эмулятору. Делается это достаточно просто. В окне эмулятора нажмите на пиктограмму веб-камеры:
В открытом окне включите режим использования камеры и укажите вашу камеру в нужном поле,
выбрав, это будет камера фронтальная или задняя:
Страница 33 из 47
После этого можно нажать предпросмотр, и выбрать, какую камеру вы хотите протестировать.
Должно появится изображение с камеры. Конечно, работать с камерой очень сложно, и не всегда 1С
способна обработать изображения корректно, поэтому будет иногда появляться зеленый квадрат.
Но главное – можно протестировать все эти режимы.
Страница 34 из 47
Но это не так, для возможности работы Google Play необходимы специальные вспомогательные
сервисы, без них он работать не будет.
Итак, наша задача на текущий момент – установить Google Play, чтобы мы могли комфортно
устанавливать разные приложение с помощью этого сервиса.
Как мы уже определились выше, просто установить само приложение Google Play будет мало, нам
нужны именно gapps, т.е. набор сервисов. Эти сервисы различаются по двум основным
характеристикам:
В нашем случае, так как мы работаем с эмулятором, можно просто взять готовый набор, например
этот, для Android 5.1. На самом деле – очень много мест, где можно взять gapps, достаточно
воспользоваться поисковиком в интернете.
После скачивания файла по ссылке, приведенной выше, нужно установить его на эмулятор.
Делается это достаточно просто: просто перетягиваем сам файл gapps-L-4-21-15.zip в окно с
эмулятором, должна появится вот такая надпись:
По окончании должен появиться вот такой вопрос, который говорит о том, что эмулятор распознал в
данном файле файлы обновления системы и он может обновиться. Жмем ОК. Если такого диалога
не появилось, то или вы скачали не то, или файл оказался битым, попробуйте его скачать снова.
Страница 35 из 47
1. Эмулятор перезагрузится один или два раза, при первом запуске вы увидите одну ошибку, но
не обращайте внимание на нее
2. Вы постоянно будете видеть вот такие ошибки и не сможете их закрыть.
Это значит, что установка прошла неудачно, и почему именно – выяснить сложно, иногда это бывает
из-за локали, иногда – по другим причинам. Поэтому просто создайте другое устройство, например,
на базе Nexus 4, и, ничего не меняя в эмуляторе, даже не меняя английский язык, повторите всю
установку.
Когда установите gapps, появится Google Play – регистрируйтесь там и устанавливайте все
приложения, которые вам нужны.
<manifest>
<uses-permission />
<permission />
<uses-sdk />
<uses-configuration />
<uses-feature />
<supports-screens />
<compatible-screens />
<supports-gl-texture />
<application>
<activity>
Страница 36 из 47
<intent-filter>
<action />
<category />
<data />
</intent-filter>
</activity>
</application>
</manifest>
Тег <manifest>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="50"
android:versionName="8.3.6.205"
android:installLocation="preferExternal"
package="com.e1c.mobile"
platformBuildVersionCode="22"
platformBuildVersionName="5.1.1-1819727">
android:versionCode – версия сборки приложения, целое число, мы его указываем при компиляции
приложения в конфигурации.
android:versionName – указывает номер версии для пользователя. Т.е. может быть любого вида,
это просто строка.
Тег <uses-permission>
Этот тег имеет атрибут android:name. В нем и описывается имя разрешения, например:
android:name="android.permission.CAMERA"
android:name="android.permission.READ_CONTACTS"
Страница 37 из 47
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission
android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<permission android:name="com.e1c.mobile.permission.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.e1c.mobile.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<permission android:name="com.e1c.mobile.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.e1c.mobile.permission.C2D_MESSAGE"/>
Тег <uses-sdk>
Тег <uses-sdk> определяет, какую версию Android’a должно иметь конечное устройство для
возможности работы этого приложения на нем.
android:minSdkVersion – это версия Android’a (точнее версия API или SDK), на которую еще можно
поставить приложение, если версия Android будет меньше, чем версия минимального SDK, то
приложение нельзя будет установить.
Страница 38 из 47
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="22"/>
Тег <uses-feature>
<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.front"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus"
android:required="false"/>
<uses-feature android:name="android.hardware.microphone"
android:required="false"/>
<uses-feature android:name="android.hardware.location"
android:required="false"/>
<uses-feature android:name="android.hardware.location.network"
android:required="false"/>
<uses-feature android:name="android.hardware.location.gps"
android:required="false"/>
<uses-feature android:name="android.hardware.wifi"
android:required="false"/>
<uses-feature android:name="android.hardware.bluetooth"
android:required="false"/>
<uses-feature android:name="android.hardware.telephony"
android:required="false"/>
<uses-feature android:glEsVersion="0x20000"
android:required="true"/>
Страница 39 из 47
В данном случае второй атрибут required="false" говорит нам о том, что данные возможности не
требуются. А последний – говорит о том, что требуется устройство с поддержкой OpenGL версии 2.0,
это обычное требование к играм, т.е. без этого требования – Google даже может не пустить игру в
раздел игр.
Тег <supports-screens>
Тег <supports-screens> определяет разрешение экрана, как в виде кодов, так и в абсолютном виде.
Относительно указанных поддерживаемых разрешений – система будет определять, что ей делать –
растягивать приложение или масштабировать.
Варианты:
Т.е. можно указать, под какой экран вы разработали ваше приложение 1С. И в случае, если у вас
внешний вид «заточен» под конкретные размеры, то вы можете это прямо указать. Это удобно, так
как в нашем случае возможности управления интерфейсом весьма ограничены. Например:
<supports-screens android:smallScreens="false"
android:normalScreens="true"
android:largeScreens="true"
android:requiresSmallestWidthDp="480"
android:compatibleWidthLimitDp="600"
android:largestWidthLimitDp="720" />
<supports-screens
android:largeScreens="true"
android:xlargeScreens="true"/>
Страница 40 из 47
Тег <application>
Тег <application> описывает данное приложение, в том числе иконки, заголовки и т.д.
<application
android:label="@2131230767"
android:icon="@2130837547"
allowBackup="true"
largeHeap="true">
Тег <activity>
Элемент <activity> объявляет активность, или формы, если говорить в терминах 1С, они же и
откликаются на действия, которые вызываются из 1С.
Т.е. в случае 1С можно открыть любую форму, указав конкретный путь к ней. Но в случае Android –
нельзя вызвать любую форму (активность, активити), а только ту, которая описана в манифесте. В
манифесте обязана присутствовать хотя бы одна активность, если это приложение предполагает
работу с формами.
<activity
android:theme="@16973830"
android:label="@2131230767"
android:icon="@2130837547"
android:name="com.e1c.mobile.App"
android:screenOrientation="nosensor"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden|adjustResize"
android:hardwareAccelerated="false">
<intent-filter>
<action
android:name="android.intent.action.MAIN"/>
<category
android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
Страница 41 из 47
Атрибуты
android:name – имя класса. Может опускаться левая часть, если она определена в начале
манифеста (та что содержит UID приложения).
Кроме этого, есть много разных атрибутов, которые отвечают за поведение формы в момент
работы.
android:label="@2131230767"
android:icon="@2130837547"
Все, что в кавычках, – это ссылка на ресурсы. Ресурсы находятся в отдельной папке, там могут быть
иконки, текстовые данные и т.д. Т.е. если в 1С для поддержки языка мы вводим отдельный язык и
подписываем каждый объект в нескольких языках, то в случае Android это выглядит по-другому, а
именно – есть xml файл, в котором описываются все эти данные, в виде ключ – значение. И самое
удобное тут то, что мы можем создать много таких файлов под каждый язык и при смене языка
просто менять адрес к файлу с нужными значениями.
В противном случае даже в момент простого поворота экрана, если не произойдет перехват
события, то Android просто уничтожит форму и пересоздаст ее снова. И, скорее всего, такое
поведение нас не удовлетворит.
Вот список некоторых значений, с помощью которых можно описать изменения конфигурации:
Страница 42 из 47
keyboard — изменился тип клавиатуры, т.е. появилась специальная панель набора номера, а
при повороте экрана появляется полноценная клавиатура
screenSize – изменились размеры экрана, например, при повороте этот параметр не
отработает на устройствах с квадратными экранами
и др.
Ясное дело, что мы можем подписаться как на одно событие, так и на все сразу, что показано в
примере:
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden|adjustResize"
Страница 43 из 47
Как вы могли заметить, есть два вида параметров – state (управление видимостью клавиатуры) и
adjust (управлением поведением формы относительно клавиатуры). Вот эти два типа параметров
можно друг с другом компоновать, как в нашем примере выше.
Остальные параметры
Кроме описанных выше параметров, есть и другие, например:
android:screenOrientation="nosensor"
В данном случае параметр говорит о том, в какой ориентации будет открыта форма. Можно открыть
в портретной, ландшафтной или же в текущей, а можно и открыть в родной ориентации устройства,
для телефонов это портрет, а планшетов – ландшафт. Что, собственно, и сделано.
android:hardwareAccelerated="false"
Есть и другие, про них можно почитать на официальной странице. Однако нас они особо не
интересуют.
Тег <intent-filter>
Как уже упоминалось на примере создания намерения, требуется указывать обязательно действие.
И мы с вами изучали набор предопределенных действий, открывали редакторы фото и т.д. Но
откуда Android знает, что эта программа может обработать конкретное действие?
Все просто: в манифесте каждой программы есть фильтр намерений, в котором это описывается.
Например, рассмотрим такой фильтр:
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
Этот фильтр намерений находится внутри тега описания активити (формы). Как видно, данную
форму мы сможем вызвать только при помощи действия:
android.intent.action.MAIN
А это действие аналогично простому запуску программы, т.е. если мы просто хотим открыть
приложение, тогда можем вызвать это действие. Но это действие не предполагает никакой передачи
параметров или ответа.
Страница 44 из 47
<intent-filter>
<action android:name="android.intent.action.EDIT"/>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="image/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
И более того, эти два фильтра могут находиться в теге одного активити. Данный фильтр отличается
тем, что он описывает уже два действия, и одно из действий (edit), может предполагать получение
ответа в результате редактирования, но это только теоретически – если разработчик написал такой
механизм возврата.
Тег <action>
Тег <action> – описывает действие. Может быть описано как одно, так и несколько действий через
несколько тегов. Кроме этого, тут можно описать дополнительно свои действия, а не общие, и тогда
вы сможете вызывать конкретную программу только по действию, не указывая при этом приложение
для запуска. Так, как мы ранее делали, вызывая выбор каталога ES Explorer.
<action android:name="android.intent.action.MAIN">
Тег <category>
<category android:name="android.intent.category.LAUNCHER">
Тег <data>
В данном теге описывается информация о том, ожидает ли данное намерение входящие данные, и
если ожидает, то какого типа:
<data android:mimeType="image/*"/>
Т.е. при попытке запуска действия редактирования данных, требуется указать тип, если не укажем,
то программы с таким фильтром не отобразятся.
Страница 45 из 47
Тег <meta-data>
Практические задания
Задание 3.1 Запрет поворота экрана
Сделайте так, чтобы в скомпилированной версии 1С (результат модуля №2) нельзя было повернуть
приложение 1С на устройстве, но при этом должна быть включена возможность поворота экрана у
других приложений.
При этом на мобильных телефонах 1С всегда должна быть в портретной ориентации, а в планшетах
– в альбомной.
В качестве отчета по заданию – предоставьте измененный код манифеста (только то место, которое
меняли).
Страница 46 из 47
В данной задаче вы можете попробовать реализовать любой функционал. Засчитаны будут два
варианта решений:
1. Готовый результат: т.е. все получилось, сделано вот так, и исходный код.
2. Не получилось решить задачу до конца.
Во втором случае необходимо указать описание решения задачи, что именно вы хотели получить
как результат, какие средства вы использовали (приложения, ссылки на них), что у вас в итоге
получилось (на чем вы остановились), и почему вы не смогли решить задачу (если есть четкое
понимание – почему).
К примеру: «Я решил сделать отправку данных по почте, однако не смог прикрепить несколько
файлов к почтовому письму. В итоге – у меня получилось создать письмо и заполнить заголовки
(код), использовал вот такие программы: … (список программ с ссылками), я уверен, что проблема в
том, что первая программа вообще не поддерживает прикрепление данных, а остальные –
поддерживают максимум 1 файл, таким образом – считаю задачу нерешенной».
Страница 47 из 47