Что значит файл сгенерирован
Создать и скачать файл с помощью Javascript? Если вы думаете об этом, это не так безопасно, как вы думаете, и не должно быть разрешено без взаимодействия с пользователем (однако теперь это разрешено).
Представьте, что вы используете Google Chrome и включили опцию «Автоматически открывать загруженные файлы», и, если вам не повезло, вы входите на вредоносный веб-сайт, и он генерирует загрузку неизвестного файла. Вы знаете, как заканчивается эта история.
Поэтому в последние годы автоматическую загрузку файлов было трудно достичь, но теперь, с появлением HTML5, эту задачу стало легче выполнять.
В этой статье мы покажем вам несколько хитростей для генерации и загрузки непосредственно файла с использованием чистого Javascript.
Самостоятельная функция загрузки
Следующая простая функция позволяет вам сгенерировать загрузку файла прямо в браузере, не связываясь с каким-либо сервером. Он работает во всех браузерах HTML5 Ready, так как использует атрибут загрузки элемент:
Атрибут загрузки указывает, что цель будет загружена, когда пользователь нажимает гиперссылку. Этот атрибут используется только если установлен атрибут href.
Вы можете увидеть этот фрагмент в действии в следующей скрипке:
Использование библиотеки
Создавайте библиотеки, а не войны. FileSaver.js реализует saveAs() Интерфейс FileSaver в браузерах, которые изначально не поддерживают его.
Если вам нужно сохранить действительно большие файлы, размер которых превышает ограничение размера BLOB-объекта или недостаточно оперативной памяти, взгляните на более продвинутый StreamSaver.js это может сохранять данные непосредственно на жесткий диск асинхронно с мощью нового API потоков. Это будет иметь поддержку для прогресса, отмены и знания, когда он закончил писать.
Следующий фрагмент позволяет вам сгенерировать файл (с любым расширением) и загрузить его без контакта с каким-либо сервером:
В следующей таблице показана совместимость FileSaver.js в разных браузерах:
Safari 6.1+
Генерация документа - это операция, позволяющая создать один или несколько файлов в системе ELMA по указанным в настройках операции шаблонам и сохранить их на сервере ELMA. В качестве шаблона может выступать любой файл с расширением TXT, .RTF, HTML, XML, DOC, XLS, DOCX, XLSX или документ из системы ELMA .
Сгенерированные документы сохраняются в контекстные переменные типа " Файл ". В дальнейшем их можно использовать в операциях и сценариях процесса.
Чтобы создать документ с помощью операции Генерация документа, необходимо разместить её в той части графической модели процесса, в которой требуется создать документ. При этом для документа должны быть определены все необходимые контекстные переменные, используемые в шаблоне. Данная операция находится на боковой панели элементов графической модели процесса в блоке " Plug-ins ".
Чтобы открыть окно настроек операции Генерация документа, необходимо дважды кликнуть мышью по ней на графической модели или выбрать пункт Настройки в контекстном меню элемента.
Вкладка "Общие"
Рис. 1. Настройки операции "Генерация документа". Вкладка "Общие"
Название * — название операции, отображаемое на графической модели , в документации по процессу и регламенте процесса , а также в заголовке окна редактирования данной операции. Название операции также отображается на кнопке перехода к этой операции процесса в веб-приложении в случае, если переход не имеет собственного названия.
Описание — описание операции, отображаемое в документации по процессу и регламенте процесса .
Вкладка "Настройки"
На этой вкладке необходимо указать один или несколько шаблонов файлов, по которым будут создаваться файлы в системе ELMA, и переменную, в которую будет сохраняться сгенерированный файл. При достижении экземпляром процесса данной операции, в системе ELMA будет создано столько файлов, сколько шаблонов указано в списке.
Рис. 2. Настройки операции "Генерация документа". Вкладка "Настройки"
Кнопка Добавить позволяет задать новый файл шаблона. В качестве файла шаблона может выступать любой файл с расширением TXT, HTML, XML, DOC, XLS, DOCX, XLSX, документ из системы ELMA или контекстная переменная типа " Файл ".
Кнопка Изменить позволяет открыть файл шаблон документа для редактирования.
Кнопка Открыть позволяет открыть файл шаблона для просмотра.
Кнопка Удалить позволяет удалить файл шаблона из списка.
Кнопка Создать переменную позволяет создать контекстную переменную процесса типа " Файл ". Такая переменная необходима для сохранения сгенерированного документа в системе ELMA.
Кнопка Выше позволяет переместить шаблон в списке выше на одну позицию.
Кнопка Ниже позволяет переместить шаблон в списке ниже на одну позицию.
Добавление файла шаблона
Для добавления файла шаблона необходимо нажать кнопку Добавить на вкладке Настройки окна настройки операции Генерация документа. Файл шаблона может быть добавлен из внешнего источника, из системы ELMA или через контекстную переменную типа "Файл" .
Добавление файла шаблона из внешнего источника
Для добавления файла шаблона из внешнего источника, например, с локального компьютера, необходимо нажать на кнопку Тип шаблона и в открывшемся окне (рис. 5) выбрать пункт Файл.
В поле Файл шаблона с помощью кнопки Открыть укажите файл шаблона.
Значение поля Имя шаблона по умолчанию соответствует названию файла шаблона, выбранного в поле Файл шаблона. Это название может быть изменено. Указанное здесь значение отображается в столбце Название шаблона на вкладке Настройки окна настроек операции Генерация документа ( рис. 2 ), а так же в качестве названия сгенерированного документа в процессе.
Поле Тип файла заполняется автоматически. В данном поле содержится информации о типе выбранного файла шаблона.
В поле Комментарий при необходимости можно добавить комментарий или описание создаваемого шаблона документа.
Для сохранения изменений необходимо нажать на кнопку ОК. Нажатие кнопки Отменить или закрытие окна приведет к возврату к окну настройки операции Генерация документа без сохранения изменений.
Добавление шаблона из документа из системы ELMA
Рис. 6. Добавление шаблона из документа из системы ELMA
Для добавления файла шаблона из документа из системы ELMA необходимо нажать на кнопку Тип шаблона и в открывшемся окне ( рис. 5 ) выбрать пункт Документ.
Значение поля Имя шаблона необходимо заполнить вручную. Указанное здесь значение отображается в столбце Название шаблона на вкладке Настройки окна настроек операции Генерация документа ( рис. 2 ), а так же в качестве названия сгенерированного документа в процессе.
В поле Id документа необходимо указать идентификационный номер документа, который будет являться шаблоном, в системе. В качестве шаблона будет использована версия документа со статусом "Текущая" . Для того, что бы узнать идентификационный номер документа, необходимо открыть его карточку в веб-приложении . Идентификационный номер документа указывается в адресной строке браузера после текста "Document/View/" (рис. 7).
Рис. 7. Идентификационный номер документа в веб-приложении
Добавление шаблона через контекстную переменную типа "Файл"
Рис. 8. Добавление шаблона через контекстную переменную
Для добавления файла шаблона через контекстную переменную типа " Файл " необходимо нажать на кнопку Тип шаблона и в открывшемся окне ( рис. 5 ) выбрать пункт Контекстная переменная.
Поле Имя шаблона аналогично полю Имя шаблона формы добавления шаблона из документа из системы ELMA.
В поле Контекстная переменная необходимо указать контекстную переменную типа "Файл", в которой содержится шаблон документа. Для добавления контекстной переменой необходимо нажать на кнопку Добавить переменную. Следует отметить, что данная переменная должна быть заполнена в процессе до выполнения операции Генерация документа.
Добавление контекстной переменной процесса типа "Файл"
Сгенерированный на основе шаблона и с использование контекстных переменных файл должен быть сохранен в контекстную переменную типа " Файл ". Для сопоставления шаблона с переменной, в которую будет сохранен документ, необходимо в списке шаблонов напротив нужного шаблона в столбце Переменная выбрать из выпадающего списка требуемую переменную ( рис. 2 ). Если такой переменной ещё не существует в контексте процесса, её можно создать, нажав кнопку Создать переменную. При этом появляется незаполненная карточка контекстной переменной , в качестве типа которой по умолчанию указан тип "Файл".
Если переменная добавляется через вкладку Контекст карточки процесса , необходимо выбрать тип "Файл" в группе типов "Системные" (рис. 9).
Рис. 9. Создание контекстной переменной процесса типа "Файл"
Пример использования операции "Генерация документа"
В качестве примера рассмотрим процесс приема техники на ремонт в сервисном центре. Оператор записывает данные клиента, информацию о технике, информацию о неисправности. По окончании процесса приема техники оператор должен выдать клиенту акт приема техники на ремонт, а так же распечатать заявку клиента для службы ремонта.
Для этого примера создадим процесс "Прием оборудования на ремонт" (рис. 10).
Рис. 10. Карта процесса "Прием оборудования на ремонт"
Среди контекстных переменных процесса создадим две переменные "Акт приема на ремонт" и "Заявка на ремонт" типа "Файл". При выполнении операции "Генерация документа" в них будут сохраняться создаваемые документы.
Кроме того, в процессе используем следующие контекстные переменные:
Номер заявки - тип "Целое число", генерируется автоматически в рамках сценария "Сформировать системные данные заявки";
Дата приема заявки - тип "Дата / время", генерируется автоматически в рамках сценария "Сформировать системные данные заявки";
Наименование оборудования, Серийный номер, Неисправность со слов клиента, Внешний вид - тип "Строка", вводится ответственным лицом;
Клиент - тип "Физическое лицо", вводится или выбирается из базы ответственным лицом;
Мастер - тип "Пользователь", выбирается из списка пользователей системы ответственным лицом;
Ориентировочная сумма ремонта - тип "Деньги", вводится ответственным лицом;
Инициатор - тип "Пользователь", заполняется автоматически в динамической зоне ответственности "Инициатор" данными пользователя, запустившего процесс.
Рис. 11. Контекстные переменные процесса "Прием оборудования на ремонт"
В первой задаче инициатор процесса заполняет необходимые данные клиента и принимаемого в ремонт оборудования (рис. 12), во второй с помощью сценария заполняются данные о номере и времени приема заявки. Таким образом, переменные, используемые при генерации документов, определены к моменту их формирования.
Рис. 12. Форма задачи "Заполнить данные для заявки" в веб-приложении
После нажатия на кнопку Сформировать документы, согласно процессу , выполняется сценарий и запускается операция "Генерация документов", которая формирует необходимые документы по шаблонам, указанным в ее настройках (рис. 13). Созданные файлы сохраняются в контекстных переменных "Акт приема на ремонт" и "Заявка на ремонт".
После этого инициатору процесса назначаются последовательно задачи "Передать акт клиенту" (рис. 14) и "Передать заявку мастеру" (рис. 15), в которых он может распечатать документы, сохраненные в контекстные переменные "Акт приема на ремонт" и "Заявка на ремонт" операцией Генерация документа.
Рис. 14. Форма задачи "Передать акт клиенту" в веб-приложении
Рис. 15. Форма задачи "Передать заявку мастеру" в веб-приложении
Ниже приведено содержимое используемых шаблонов, сгенерированных файлов и настройки, выполненные на вкладках Форма (контекст) задач "Заполнить данные для заявки", "Передать акт клиенту" и "Передать заявку мастеру".
В своих предыдущих статьях я пытался показать отдельные фрагменты Генератора документов. Как стало понятно из обсуждений, отдельные его фрагменты существуют в различных реализациях и обсуждать их не интересно. Действительно, зачем обсуждать отдельные строительные кирпичики, когда не видишь здания целиком. Поэтому в этой статье я попытаюсь показать здание целиком, чтобы не обсуждать его отдельные кирпичики. Я попытаюсь описать свое видение реализации генератора документов, опираясь на личный опыт, полученный в одном из крупнейших банков России. Я шел от практики, реализовал генератор в MS Word и Excel, вот что в результате этого процесса нарисовалось.
2. Генератор должен на основе шаблонов автоматически строить UI формы для обеспечения ручного ввода информации, отсутствующей в БД. Таким образом, введя вручную значение такого поля, оно будет подставлено в разные места документа(тов), правильно сопряжено с другими словами, иметь правильный падеж и т.д. Значения, введенные вручную, должны сохраняться в БД и в случае необходимости копироваться в основную БД, обеспечивая принцип одного ввода. Часть полей должна быть просто показана на форме без возможности редактирования, только для визуального контроля.
Разработчики шаблонов с помощью специальной среды разработки устанавливают порядок следования полей, их расположение на закладках UI формы, выбирают форматы ввода\вывода, отмечают поля для заполнения прочерками и т.п. Роль IT в этих процессах может быть только консультационная. Практика показывает, что хорошая документация плюс наличие обучающих примеров, плюс уже обученный сотрудник, плюс дружественная среда разработки позволяют почти полностью освободить IT от подготовки шаблонов, форм ввода информации и вопросников. А это значит, что бизнес сам себя обеспечивает нужными документами, освобождает IT от рутины, устраняет посредников между требованиями и реализацией и работает практически во временном режиме, удобном самому бизнесу. Ну и, конечно, бизнес перестает платить за реализацию генерации документов сторонним разработчикам и некомпетентным исполнителям, которые не находятся в контексте бизнеса конкретной организации и ее практики.
Разработка шаблонов помимо понимания требований к конечному документу, это кропотливый труд, требующий внимания и прилежания. Разметка шаблонов будущего документа, это работа не для молодых, амбициозных, но нетерпеливых IT-шников, здесь нужны женские руки, женское прилежание и склонность лучше мужчин справляться с монотонными операциями подходит как нельзя кстати. Поддержка шаблонов, их модификация — это все же больше женский хлеб, чем мужской.
Я сам как-то попробовал разметить документ для бизнеса, и скажу честно, это не принесло мне радости, хотя дало несколько прекрасных идей для улучшения процессов подготовки шаблонов. С тех пор я сильно зауважал тех женщин, которые, не имея этих замечательных новшеств, терпеливо и без жалоб тянули свою нелегкую женскую долю.
3. Количество шаблонов должно стремиться к минимуму, но в то же самое время сами шаблоны не должны быть огромными. Сколько должно быть шаблонов и каковы их размеры должны решать сами разработчики шаблонов, т.е. бизнес. И точных правил, однозначно определяющих размеры шаблонов, не существует. Но рекомендации могут быть. Одна из них — чем больше по размеру шаблон, тем больше вычислительных ресурсов потребуется Генератору для генерации документов на его основе. Поэтому не стоит в один шаблон упаковывать весь мир.
Практически, размеры шаблонов определяются тем, сколько разнообразных документов можно сгенерировать из одного шаблона и насколько они будут похожи друг на друга, относятся ли к одной теме и т.п. Совершенно не редки шаблоны размером 100 и более страниц.
Когда я увидел впервые такие огромные шаблоны, я, при всем доверии к компетенции бизнеса, засомневался в правильности их выбора. Но чтобы указать бизнесу на его ошибки, нужно разобраться с тем, что неправильно было сделано и предложить лучший вариант, а это требует погружения в практику бизнеса, что, в свою очередь, потребует от IT-шника компетенций, не относящихся к его текущим умениям и навыкам. А посему, со своим уставом не надо ходить в чужой монастырь. Надо доверять людям, 100 страниц, значит 100.
Понятно, что разработчики шаблонов не оперируют понятиями производительности и не считают затрат вычислительных русурсов. Их интересует результат. Тем не менее они заинтересованы в том, чтобы генерация документов осуществлялась максимально быстро.
Поэтому разметка шаблонов должна позволять разработчикам шаблонов управлять скоростью генерации, и разработчики шаблонов, безусловно, такими возможностями пользуются. Идея сокращения размера шаблона заключается в том, что шаблон может быть большим, но состоять из кусочков, котрые подгружаются в память по мере надобности. Т.е. в процессе компиляции шаблона он по указаним в разметке разбивается компилятором на кусочки, которые в момент генерации документа будут подгружены в память в зависимости от того, какой документ из этих кусочков собирается. Т.е. с точки зрения разработчика шаблона, шаблон может быть большим, но с точки зрения Генератора, шаблон — это маленькая базовая часть плюс конкретные кусочки, подставляемые на свое изначальное место в случае надобности. Такой способ работы с шаблонами приводит к сокращению времени генерации и, соответственно, сокращению потребляемых вычислительных ресурсов. Ответственность за скорость генерации лежит при таком подходе на разработчике шаблона (а он работник бизнеса).
4. Генератор должен уметь включать в себя статьи, параграфы, части других документов, отсутствующие изначально в шаблоне. В шаблоне только отмечается место, куда такая информация может быть вставлена. Т.е. генератор должен уметь синтезировать документ из отдельных параграфов и фрагментов других документов. Здесь основная сложность заключается в сопряжении разнородного внешнего текстового материала с основным документом. Например, в библиотеке могут храниться отдельные пункты договора и, в зависимости от условий договора, эти пункты должны вставляться в основной документ. При вставке надо выровнять шрифт и отступы, определить номера пунктов договора, вычислить ссылки на другие пункты как текущего документа, так и на пункты другого документа (например, генерального договора) и т.п.
5. Атрибуты отображения текста в готовом документе должны быть достаточными, чтобы соответствовать потребностям бизнеса. Это толщина, наклон, подчеркивание и вычеркивание текста, его подсвечивание (highlight) определенным набором цветов (каждый цвет подсветки может нести смысловую нагрузку). Очень важна поддержка возможности отображения исправлений, когда в документе можно видеть первоначальный и исправленный вариант текста. Пользователь документа должен иметь возможность переключаться из режима отображения конечного вида документа в режим отображения правок (MS Word). Генератор должен уметь автоматически создавать оглавление документа, а также создавать сноски.
Также у разработчика шаблонов должен быть в ассортименте достаточный набор спецсимволов, которые однозначно интерпретируются пользователем документа, как то: всякого рода галки, квадратики с галками и без, указательный палец и др. Генератор должен уметь вставлять картинки из других документов или из файлов (например, QR-код), создавать ссылки на сайты, уметь впечатывать отдельные символы слова (например, кодовое слово) в ячейки обычно однострочной таблицы. И, конечно, должен быть доступен набор тэгов разметки, позволяющий создавать таблицы любой сложности, с разнообразием заголовков и строк таблицы. В дополнение к таким тэгам придаются тэги разметки, позволяющие удалять (сжимать) пустые строки или столбцы таблицы, если после генерации они не были заполнены данными.
6. Генератор должен уметь возвращать результат в вызывающую программу или сохранять готвый документ в файловую папку. Генератор реализуется в виде нескольких методов WEB-service, одним из которых является генерация документа или пачки документов по шаблону. Вызывать WEB-Service можно из любой программы или СУБД. Если результат сохраняется в файл, то очень важно иметь гибкую, настраиваемую по требованиям бизнеса, подсистему, которая определяет спецификацию самой папки и имя файла документа, которые могут быть интеллектуальными и включать в себя дату, имя клиента и т.п. Обычная практика работы с документами клиента приводит к созданию папки, где лежат все документы, относящиеся к сделке, в том числе не подготовленные генератором, и пользователям удобно использовать файловую «деревянную» структуру для работы с документами.
При генерации пачки документов по одному шаблону, если генерируемые документы кроме значения полей ничем не отличаются, можно значительно скратить время генерации, т.к. все подготовительные операции с шаблоном выполняются вначале только один раз, а затем по этой промежуточной форме шаблона производится генерация пачки документов. Например, набор документов по поручительствам может иметь одни и те же условия соглашения для поручителей, поэтому все документы должны отличаться только данными самих поручителей, их ФИО, адреса, должности и прочее. В этом случае выгодно использовать генерацию пачки документов по одному шаблону, и получить выигрыш во времени генерации за счет того, что генератор использует механизм использования промежуточной формы шаблона. Такая функциональность также должна поддерживаться генератором.
7. Представим себе документ, например, анкету, в котором есть раздел, включающий сведения о родителях. А у клиента нет родителей, и никогда не было. В одном месте анкеты он поставит галку, что родителей у него нет, а в другом месте сведения о родителях останутся незаполненными. После распечатки такой анкеты будет использована лишняя бумага. Действительно, если у клиента родителей нет, то и сведений о родителях в документе быть не должно. И таких моментов, вызывающих когнитивный диссонанс, в документах зачастую пруд пруди. Напрасно тратится энергия и труд, затраченные на производство бумаги, напрасно тратится время жизни человека, который просматривает такую анкету с пустыми полями. Этого быть не должно. Это могло быть раньше, в докомпьютерную эпоху, но сейчас, при наличии генератора документов такое расточительство должно быть прекращено. И все что нужно сделать IT-шникам, это всего-навсего получить заранее ответ на вопрос, есть ли у клиента родители, и в зависимости от ответа, запрашивать данные о них или исключить полностью из документа раздел сведений о них. Т.е. перед собственно заполнением полей документа должен быть пройден вопросник, ответы на вопросы которого являются аргументами как для функции получения списка полей, необходимых для заполнения в документе, так и аргументами функции генерации документа по конкретному шаблону.
8. Не будем лукавить. «Зачем так много слов, так много треска». Работник бэкофиса, если он не слишком ленив, может обеспечить себя шаблонами сам. И зачем ему генератор, когда у него есть его собственные шаблоны на все типовые случаи жизни. Если что-то меняется в жизни, он создаст себе новый шаблон и с помощью команды Replace может быстро сделать нужный документ, например, типовой договор. Но вот ситуация, которая при таком подходе не работает. Т.е. она работает, конечно, но кое-как. Допустим, составлен первичный вариант договора поручительства и передан клиенту, а затем юристам на согласование. В результате правок через некоторое время на основе этого первичного документа появляется новый документ, в котором многие пункты первоначального варианта исправлены, дополнены и все такое. Теперь на основе этого нового варианта поручительства надо составить 10 или больше документов поручительств, где должны быть подставлены ФИО, адреса, должности и прочие реквизиты поручителей, а остальное содержимое документа должно быть таким, как в новом варианте поручительства.
Здесь возникает ситуация, когда у работника бэкофиса шаблона нет, т.к. на все случаи жизни шаблонами не запасешься и все варианты поручительств не переберешь. Вот случай, когда генератор действительно может проявить свое преимущество по сравнению с обычным ручным способом подготовки документов. Для этого генератор должен сгенерировать такой первичный договор поручительства, который после внесения правок клиентом и юристами может сам выступить в роли шаблона. Тогда подготовка 10 или более документов поручительств для разных поручителей займет несколько секунд работы компьютера, не будет содержать ошибок, опечаток и всего того, что может сделать любой человек в любой момент. Т.е. не только экономится время подготовки документов, но повышается их качество, т.к. компьютер не ошибается. Чтобы получить такую функциональность генератор должен в момент генерации первичного документа создавать налету скрытую разметку, которая существует в виде закладок и не видна людям, работающим с текстом документа. Каждая закладка однозначно соотнесена с именем поля, а значит, что в место документа, отмеченное закладкой, можно подставлять любые значения, но только способ подстановки будет отличаться от первичного. К сожалению, если говорить про MS Word, не всегда закладки сохраняются в документе после внесения правок, это зависит от способа, каким вместо одного текста был внесен другой. Чтобы устранить последствия исчезновения закладок, приходится делать дополнительные закладки, по которым можно вычислить место исчезнувших закладок. Такой механизм вполне работоспособен, жаль, что Microsoft ничего не предпринимает для стандартного решения этой проблемы. Ну может быть, когда-нибудь, когда что-то сдуется или изменится климат, данная проблема будет решена.
9. Шаблоны, содержашие в себе скрытую разметку, по сравнению с первоначальными шаблонами, являются ригидными. Но степенью ригидности, к счастью, можно управлять. Из ригидного шаблона можно получить гибридный (вот так рождаются каламбуры), для этого в части ригидного шаблона нужно подставить части из первоначального шаблона. Обычно в документе есть такие места (гипервариабельные), которые позволяют вернуть на место ту разметку, которая была в первоначальном шаблоне до генерации документа. Естественно, такие места надо разметить в шаблоне. В результате, даже после правок клиентом и юристами, шаблон, содержащий только закладки, остается достаточно гибким. К тем частям, которые вернулись из первоначального (или любого другого) шаблона, налету можно получить вопросник, если разметка с ответами на вопросы будет обнаружена в вернувшихся частях шаблона. Гибридный шаблон обеспечивает ту степень гибкости, которая во многих случаях оказывается соответствующей требованиям бизнеса.
Итак, я рассмотрел некоторые отдельные «кирпичики», которые нужно иметь, чтобы построить «здание» под названием «Генератор документов». Я старался акцентировать ваше внимание на том, чтобы шаблоны создавались самим бизнесом и участие IT было минимальным. Надеюсь, разговор о гибридных шаблонах тоже мог быть полезным.
Понятно, что во многих случаях достаточно иметь более простую машинку для подготовки документов. В тех организациях, где нет вопросов про родителей и документы однообразны и статичны, можно использовать рогатку вместо пушки. В тех же организациях, где имеется индивидуальный подход к клиентам и процесс подготовки договоров не автоматизирован
в достаточной степени, данная статья поможет определиться с требованиями к разработчикам того программного продукта, который сегодня по функционалу должен и может соответствовать описанию, данному мной в этой статье.
Ссылка на официальный документ производства продукции:
Предисловие:
В магазине приложений Google Play есть ограничение на загрузку в 100 МБ. Приложения, размер которых превышает этот размер, должны загружать лишнюю часть в виде расширенного файла. Всего может быть загружено 2 расширенных файла. Максимальный размер каждого файла может составлять 2 ГБ, а формат файла obb [расширенный Файл может использовать любой формат файла (ZIP, PDF, MP4 и т. Д.). Вне зависимости от любого формата файла, Android считает, что это файлы obb (непрозрачные двоичные двоичные объекты).
Для каждого приложения каталог может содержать только до 2 расширенных файлов. Одним из них является основной файл расширения, а другим - файл расширения патча, поэтому обычно требуется обрабатывать только основной файл расширения.
1. Правила именования OBB
Имя файла состоит из четырех частей, в том числе:
- main | patch: используется для указания того, является ли это основным расширением или дополнительным расширением.
- расширение-версия: код версии загруженного в данный момент apk.
- имя-пакета: имя пакета apk
- obb: суффикс на самом деле является zip-файлом, Google play автоматически изменит zip-файл на obb-файл.
Например, предположим, что ваша версия APK (versionCode) 25, а имя вашего пакета - com.example.app. Если основной файл расширения загружен, файл переименовывается в:
- При загрузке APK, OBB будет загружен отдельно, вы не можете просто обновить файл OBB
- При загрузке приложения файл OBB загружается в каталог% external storage% / Android / obb / package name
Во-вторых, метод генерации OBB:
1. Google официальный инструмент JobB
Сделано вOBB(Opaque Binary Blob)Инструмент для форматирования файлов, вAndroid SDKв%ANDROID——HOME/tools%вЕсть работа под инструменты / bin。
Примечание. Если вы не настроили среду Android SDK, вам нужно открыть командное окно и перетащить jobb.bat в окно cmd, чтобы выполнить
2. Используйте WinRAR для сжатия (рекомендуется)
tip: Если ваш файл расширения - это какой-то мультимедийный файл, и вы не хотите распаковывать пакет ресурсов, а используйте вызов воспроизведения мультимедиаПоместите файлы, которые необходимо сжать, в ресурсы или используйте winRAR для сжатия в соответствии с каталогом.
Выберите папку ресурсов и щелкните правой кнопкой мыши, добавьте в сжатый файл, откройте следующее окно и назовите его в соответствии с правилами именования.
(например, MediaPlayer.setDataSource () и SoundPool.load ()) непосредственно воспроизводят файлы мультимедиа в пакете ресурсов.
Тогда вы не должны сжимать файл при создании пакета расширения файла, а просто упаковать его. Метод сжатия: хранилище
Процесс сжатия
3. Где сохранить расширенные файлы
Когда Android Market загрузит файл расширения программы, он будет сохранен в общем хранилище системы. Чтобы программа работала нормально, вы не можете удалять, перемещать или переименовывать файл расширения. На некоторых устройствах Market не может автоматически загрузить файл расширения, поэтому вы должны загрузить файл и сохранить его в том же месте при запуске программы.
Местоположение сохранения файла расширения выглядит следующим образом:
Для каждого приложения каталог может содержать только до 2 файлов расширения. Один - это основной файл расширения, а другой - файл расширения патча. При обновлении программы, если есть новые файлы расширений, новые файлы будут перезаписывать старые файлы расширений.
Если вам нужно распаковать файл расширения для использования, будьте осторожны, чтобы не удалить файл .obb, и не разархивируйте файл в этот каталог. Вы должны сохранить разархивированные файлы в каталог, возвращенный getExternalFilesDir (). Если возможно, лучше использовать формат файла, который программа может прочитать непосредственно, без необходимости разархивировать файл снова. Команда разработчиков Android предоставляет проект (APK Expansion Zip Library), который может напрямую читать содержимое ZIP-файла без распаковки файла.
Следует отметить, что файлы, хранящиеся в общей области хранения системы, также могут быть доступны пользователям и другим приложениям.
В-четвертых, использование файлов расширения APK
Для использования файлов расширений в приложении требуются два дополнительных элемента библиотеки Android:
- Google Market Licensing package-
- Google Market APK Expansion Library package-
После загрузки используйте каталог google_market_licensing \ library в файле market_licensing-r02.zip для создания проекта библиотеки;
Затем используйте google_market_apk_expansion \ downloader_library в market_apk_expansion-r01.zip для создания другого библиотечного проекта.
В то же время для упрощения обработки файлов расширений формата ZIP файл market_apk_expansion-r01.zip также содержит проект библиотеки для обработки файлов ZIP: google_market_apk_expansion \ zip_file Если вы используете формат файла расширения ZIP, вы также можете создать этот проект библиотеки.
1. Объявление необходимых разрешений
Примечание. По умолчанию уровень API, необходимый для загрузки проекта библиотеки, равен 4, а для проекта библиотеки ZIP с расширением APK требуется уровень API 5.
После того, как подготовка завершена, давайте посмотрим, как использовать файл расширения.
2. Реализация сервиса загрузчика
Для загрузки файлов в фоновом режиме проект библиотеки загрузки предоставляет реализацию Сервиса с именем DownloaderService. Вы должны наследовать от этого файла, чтобы реализовать свой сервис загрузки. Чтобы упростить разработку сервисов загрузки, DownloaderService также реализует следующие функции:
- Зарегистрируйте BroadcastReceiver для отслеживания изменений в состоянии сетевого подключения устройства. Если сетевое соединение отключено, загрузка приостанавливается, а если сетевое соединение восстанавливается, загрузка продолжается. -
- Запланируйте уведомление RTC_WAKEUP, которое можно использовать для запуска службы загрузки после прекращения службы загрузки.
- Генерация уведомления (Notification) для отображения хода загрузки и статуса ошибки загрузки
- Разрешить вашей программе вручную приостановить и возобновить загрузку
Убедитесь, что общая область хранения смонтирована и доступна.Перед загрузкой файла проверьте, существует ли файл и достаточно ли места для хранения. Уведомить пользователя, если есть проблема.
getSALT (): стратегия разрешений используется для генерации случайного набора байтов для Обфускатора.
getAlarmReceiverClassName (): возвращает имя класса BroadcastReceiver, используемое для перезапуска процесса загрузки в вашей программе. В некоторых случаях, когда служба загрузки неожиданно прерывается, загрузите ее снова через класс BroadcastReceiver. Например, программа управления процессами прекратила загрузку.
- Ниже приведен код реализации класса DownloaderService:
Затем объявите службу в файле манифеста. Это очень просто!
- Реализация AlarmReceiver
Чтобы обнаружить процесс загрузки и перезапустить службу загрузки, DownloaderService организует сигнал тревоги RTC_WAKEUP для отправки намерения в BroadcastReceiver программы. Вы должны определить этот BroadcastReceiver для вызова функции, предоставляемой библиотекой загрузчика, и использовать эту функцию, чтобы проверить состояние загрузки и перезапустить службу загрузки, если это необходимо.
Реализовать этот класс также очень просто. Вообще говоря, просто переписать функцию onReceive () и вызвать функцию DownloaderClientMarshaller.startDownloadServiceIfRequired ()
Определите, что AlarmReceiver наследуется от BroadcastReceiver следующим образом:
Затем объявите получателя в файле манифеста. Это очень просто!
3. Начните загрузку файла расширения
Основная активность программы (активность, запускаемая с помощью значка Launcher) должна отвечать за проверку наличия файла расширения и запуск службы загрузки, если он не существует.
Чтобы использовать библиотеку Downloader для загрузки, выполните следующие действия:
1) Проверьте, был ли файл загружен
Класс Helper в библиотеке Downloader содержит несколько функций, упрощающих этот шаг:
getExtendedAPKFileName(Context, c, boolean mainFile, int versionCode)
doesFileExist(Context c, String fileName, long fileSize)
Например, в примере проекта проверьте наличие файла с помощью следующей функции в функции onCreate () Activity:
Здесь объект XAPKFile хранит номер версии и размер известного файла расширения и является ли он основным файлом расширения. Если функция возвращает false, запустите службу загрузки.
2) Запустите загрузку с помощью функции DownloaderClientMarshaller.startDownloadServiceIfRequired (Context c, PendingIntenttificationClient, ClassserviceClass).
Параметры этой функции следующие:
- context: Your application’s Context.
- messagesClient: PendingIntent, используемый для запуска основной операции. Используется в уведомлениях, созданных DownloaderService для отображения прогресса загрузки. Когда пользователь выбирает уведомление, система вызывает PendingIntent, чтобы открыть действие, которое отображает ход загрузки (вообще говоря, действие, которое начинает загрузку).
- serviceClass: класс, унаследованный от DownloaderService в программе. При необходимости служба будет запущена для начала загрузки.
Эта функция возвращает целое число, чтобы указать, нужно ли загружать файл. Существуют следующие значения:
- NO_DOWNLOAD_REQUIRED: указывает, что файл уже существует или загружается в данный момент.
- LVL_CHECK_REQUIRED: указывает, что для авторизации требуется получить URL-адрес для загрузки файла расширения.
- DOWNLOAD_REQUIRED: указывает, что URL-адрес файла расширения был получен, но загрузка еще не началась.
- LVL_CHECK_REQUIRED и DOWNLOAD_REQUIRED по сути одинаковы, в общем случае вам не нужно обращать внимание на это состояние. Вызовите startDownloadServiceIfRequired () в вашей основной деятельности, вам нужно только увидеть, является ли возвращаемое значение NO_DOWNLOAD_REQUIRED. Если возвращаемое значение не равно NO_DOWNLOAD_REQUIRED, библиотека загрузчика начинает загрузку. Вам следует обновить интерфейс программы, чтобы отобразить ход загрузки, если возвращаемое значение равно NO_DOWNLOAD_REQUIRED, это означает, что файл был загружен и ваша программа может нормально запускаться.
3) Когда возвращаемое значение функции startDownloadServiceIfRequired () не равно NO_DOWNLOAD_REQUIRED,
Вызовите функцию DownloaderClientMarshaller.CreateStub (клиент IDownloaderClient, ClassdownloaderService) для создания экземпляра IStub. Этот экземпляр IStub обеспечивает функцию привязки между Activity и службой загрузки, так что ваша Activity может получить событие загрузки.
Для функции CreateStub () требуется класс, который реализует интерфейс IDownloaderClient и класс реализации DownloaderService в качестве параметров. Вообще говоря, пока Activity реализует интерфейс IDownloaderClient.
Команда разработчиков Android рекомендует создавать объекты IStub в функции onCreate () в Activity (созданной после функции startDownloadServiceIfRequired ()).
Когда функция onCreate () возвращается, Activity выполнит функцию onResume () и вызовет функцию connect () IStub в этой функции. Также вызовите функцию отсоединения IStub в функции onStop ().
Вызовите connect (), чтобы связать Activity и DownloaderService.
4. Обработка прогресса загрузки
Чтобы получать информацию о ходе загрузки, вам необходимо реализовать интерфейс IDownloaderClient. Интерфейс имеет следующие функции:
onServiceConnected(Messenger m)
После инициализации IStub эта функция будет вызываться обратно. Параметры этой функции используются для доступа к вашему DownloaderService. Вы можете использовать функцию DownloaderServiceMarshaller.CreateProxy () для создания этого объекта IDownloaderService. Затем вы можете использовать этот объект для управления службой загрузки, такой как приостановка и возобновление загрузки.
onDownloadStateChanged(int newState)
Эта функция вызывается при изменении состояния загрузки, например, при запуске загрузки или завершении загрузки.
Значением параметра newState является одна из констант, определенных в интерфейсе IDownloaderClient (начиная с STATE_);
Текстовое описание состояния можно получить с помощью функции Helpers.getDownloaderStringResourceIDFromState (), чтобы пользователи могли легче его понять. Например, соответствующее текстовое описание STATE_PAUSED_ROAMING: «Загрузка приостановлена, потому что вы находитесь в роуминге / в настоящее время в роуминге, загрузка остановлена»
onDownloadProgress(DownloadProgressInfo progress)
Параметр DownloadProgressInfo этой функции содержит различную информацию о ходе загрузки, такую как предполагаемое время завершения, текущая скорость загрузки, процент выполнения и т. д. Интерфейс загрузки может быть обновлен на основе этой информации.
Есть также несколько полезных функций:
- requestPauseDownload()
Приостановить загрузку - requestContinueDownload()
возобновить загрузку - setDownloadFlags(int flags)
Установите логотип загрузки. В настоящее время поддерживается только один флаг: FLAGS_DOWNLOAD_OVER_CELLULAR. Загрузите файлы расширения через мобильную сеть. По умолчанию этот флаг не включен, поэтому по умолчанию загрузка только через WIFI.
5. Читайте расширенные файлы
После загрузки файла расширения APK мы рассмотрим, как его использовать. Однако для некоторых реализаций Android 6.0 (уровень API 23) и более поздних версий все еще требуются разрешения, поэтому необходимо объявить разрешения хранения в манифесте приложения и запросить разрешения внешнего хранилища во время выполнения, как показано ниже:
Перед использованием файла расширения obb необходимо переместить библиотеку Zip Library в свой собственный проект для зависимости. Используя эту библиотеку, вы можете легко прочитать ресурсы в файле расширения ZIP как виртуальную файловую систему.
Совет: (Zip-библиотека находится в / extras / google / google_market_apk_expansion / zip_file /)
Используйте класс APKExpansionSupport для получения ресурсов в obb
Предоставьте несколько способов доступа к расширенному имени файла и ZIP-файлу:
-
getAPKExpansionFiles()
-
ZipResourceFile
- getInputStream(String assetPath)
Предоставьте InputStream для чтения файлов в ZIP-файле. Требуемый путь assetPath должен быть относительно корня содержимого файла ZIP. - getAssetFileDescriptor(String assetPath)
Предоставьте AssetFileDescriptor для файлов в файле ZIP. Требуемый путь к assetPath должен быть указан относительно корня содержимого файла ZIP. Это полезно для определенных API-интерфейсов Android, для которых требуется AssetFileDescriptor
Прежде всего, чтобы получить путь к файлу расширения, вы можете выполнить операцию с помощью следующего кода:
Читайте также: