как повысить api приложения
Обновляемся на новую версию API Android по наставлению Google
Скоро выходит Android 12, но в этом августе уже с 11-й версии разработчикам придётся использовать новые стандарты доступа приложений к внешним файлам. Если раньше можно было просто поставить флаг, что ваше приложение не поддерживает нововведения, то скоро они станут обязательными для всех. Главный фокус — повышение безопасности.
Переход на новую версию API — довольно трудоёмкая операция, требующая больших затрат на её поддержку при введении крупных апдейтов. Далее расскажу немного про наш переход и возникшие при этом трудности.
Что происходит
Если вы уже знакомы с теорией, то этот раздел можно пропустить — тут я хочу поверхностно сравнить подходы к предмету в разных версиях операционной системы.
В Android есть внутреннее Internal Storage (IS) и внешнее хранилище External Storage (ES). Исторически это были встроенная память в телефоне и внешняя SD-карта, поэтому ES был больше, но медленнее и дешевле. Отсюда и разделение — настройки и критически важное записывали в IS, а в ES хранили данные и большие файлы, например, медиа. Потом ES тоже стал встраиваться в телефон, но разделение, по крайней мере логическое, осталось.
У приложения всегда есть доступ к IS, и там оно может делать что угодно. Но эта папка только для конкретного приложения и она ограничена в памяти. К ES нужно было получать доступ и, кроме манипуляции со своими данными, можно было получить доступ к данным других приложений и производить с ними любые действия (редактировать, удалять или украсть).
Но после разделения на внутреннее и внешнее хранилища все равно оставались проблемы. Многие приложения могли хранить чувствительную информацию не только в IS, но и в ES — то есть ответственность лежала целиком на разработчиках и на том, кто хочет завладеть файлами.
В Android решили всё это переделать ещё в 10-й версии, а в 11-й это стало обязательным.
Чтобы минимизировать риски для пользователя в Google решили внедрить Scoped Storage (SS) в ES. Возможность проникнуть в папки других приложений убрали, а доступ есть только к своим данным — теперь это сугубо личная папка. А IS с 10-й версии ещё и зашифрована по умолчанию.
В Android 11 Google зафорсировала использование SS — когда таргет-версия SDK повышается до 30-й версии API, то нужно использовать SS, иначе будут ошибки, связанные с доступом к файлам. Фишка Android в том, что можно заявить совместимость с определённой версией ОС. Те, кто не переходили на 11, просто говорили, что пока не совместимы с этой версий, но теперь нужно начать поддерживать нововведения всем. С осени не получится заливать апдейты, если не поддерживаешь Android 11, а с августа нельзя будет заливать новые приложения.
Если SS не поддерживается (для девайсов ниже 10-й версии), то для доступа к данным других приложений требуется получить доступ к чтению и записи в память. Иначе придётся получать доступ к файлам через Media Content, Storage Access Framework или новый, появившийся в 11-м Android, фреймворк Datasets в зависимости от типа данных. Здесь тоже придётся получать разрешение доступа к файлу, но по более интересной схеме. Когда расшариваемый файл создаёшь сам, то доступ к нему не нужен. Но если переустановить приложение — доступ к нему опять потребуется. К каждому файлу система привязывает приложение, поэтому когда запрашиваешь доступ, его может не оказаться. Особо беспокоиться не нужно, это сложно отследить, поэтому лучше просто сразу запрашивать пермишен.
Media Content, SAF и Datasets относятся к Shared Storage (ShS). При удалении приложения расшаренные данные не удаляются. Это полезно, если не хочется потерять нужный контент.
Хотя даже при наличии SS можно дать доступ к своим файлам по определённой технологии — через FileProvider можно указать возможность получения доступа к своим файлам из другого приложения. Это нормально, потому что файлы расшаривает сам разработчик.
Также добавилась фича — если приложение не использовалось несколько месяцев, то снимаются все пермишены и доступы к системным элементам. По best practice разрешение запрашивается по необходимости (то есть непосредственно перед использованием того, на что спрашиваем разрешение), поэтому мы просто перед выполнением какого-либо действия проверяем, есть ли у нас пермишены. Если нет, то запрашиваем.
В то же время перекрыли доступы к приложениям внутри девайса. Если раньше можно было отследить, что установлены определённые приложения и отправлять к ним соответствующие интенты, то сейчас мы должны прямо в манифесте прописать, что работаем именно с этими приложениями, и только после этого получить доступ.
В качестве примера можем взять шаринг — мы шарим множество приложений, и их всех нужно указывать в манифесте, иначе они не обнаружатся. Начнём перебирать пакет установленных приложений — будет информация, что не указанного в манифесте приложения нет и при шаринге всё отвалится.
Перейдём к практике.
Переход на новую версию
Основная функциональность по работе с файлами в приложении iFunny представлена в виде сохранения мемов в память и расшаривания их между приложениями. Это было первое, что требовалось починить.
Для этого выделили в общий интерфейс работу с файлами, реализация которого зависела от версии API.
FilesManipulator представляет собой интерфейс, который знает, как работать с файлами и предоставляет разработчику API для записи информации в файл. Copier — это интерфейс, который разработчик должен реализовать, и в который передаётся поток вывода. Грубо говоря, мы не заботимся о том, как создаются файлы, мы работаем только с потоком вывода. Под капотом до 10-й версии Android в FilesManipulator происходит работа с File API, после 10-й (и включая её) — MediaStore API.
Рассмотрим на примере сохранения картинки.
По сути, вся работа с файлами реализована через эти классы. Шаринг в другие приложения автоматически сохраняют медиа в память устройства и последующая работа с URI уже происходит по новому пути. Но есть такие SDK, которые ещё не успели перестроиться под новые реалии и до сих пор используют File API для проверки медиа. В этом случае используем кеш из External Storage и при необходимости провайдим доступ к файлу через FileProvider API.
Помимо ограничений с памятью в приложениях, таргетированных на 30-ю версию API, появилось ограничение на видимость приложения. Так как iFunny использует шаринг во множество приложений, то данная функциональность была сломана полностью. К счастью, достаточно добавить в манифест query, открывающую область видимости к приложению, и можно будет также полноценно использовать SDK.
Для неявных интентов тоже приходится добавлять код в манифест, чтобы задекларировать то, с чем будет работать приложение. В качестве примера выложу часть кода, добавленного в манифест.
После проверок запуска UI-тестов на девайсах с версиями API 29-30 было выявлено, что они также перестали корректно отрабатываться.
Первоначально в LogCat обнаружил, что приложение не может приконнектиться к процессу Orchestrator и выдает ошибку java.lang.RuntimeException: Cannot connect to androidx.test.orchestrator.OrchestratorService.
Эта проблема из разряда видимости других приложений, поэтому достаточно было добавить строку
Тест удачно запустился, но возникла другая ошибка — Allure не может сохранить отчёт в память устройства, падает с ошибкой.
Очевидно из-за Scoped Storage стало невозможно сохранять файлы в другие папки, поэтому снова почитав документацию по управлению файлами в памяти на девайсе, обнаружил интересный раздел. Там рассказано, как для нужд тестов открыть доступ к папкам девайса, но с существенными ограничениями, которые можно почитать тут.
На Android 11 тесты удачно запустились и стали проходить без ошибок.
Запустил тесты — всё еще не происходит сохранения в память отчёта. Тогда я обнаружил, что в манифесте WRITE_EXTERNAL_STORAGE ограничен верхней планкой до 28 версии API, то есть запрашивая работу памятью мы не предоставили все разрешения. После изменения верхней планки (конечно, для варианта debug) и запроса пермишена на запись тесты удачно запустились и отчёт Allure сохранился в память устройства.
Добавлены следующие определения пермишенов для debug-сборки.
После всех вышеописанных манипуляций с приложением, можно спокойно устанавливать targetSdkVersion 30, загружать в Google Play и не беспокоиться про дедлайн, после которого загружать приложения версией ниже станет невозможно.
Изменение уровня API Android Studio
Я хочу изменить минимальную версию SDK в Android Studio от API 12 до API 14. Я попытался изменить ее в файле манифеста, т. Е.
И восстановление проекта, но я до сих пор получаю Android Studio IDE, вызывая некоторые ошибки. Я полагаю, что мне нужно установить минимальный SDK в «свойствах проекта» или что-то подобное, поэтому среда IDE распознает изменение, но я не могу найти, где это делается в Android Studio.
Когда вы хотите обновить minSdkVersion в существующем проекте …
После обновления minSdkVersion minSdkVersion вам нужно щелкнуть по кнопке, чтобы синхронизировать файл градиента («Sync Project with Gradle files»). Это очистит маркер.
Для пользователей студии Android:
Градул автоматически перестраивает проект.
Поскольку теперь Android Studio стабильна, есть простой способ сделать это.
PS: Хотя на этот вопрос уже был дан ответ, но Android Studio немного изменила его стабильный выпуск. Таким образом, простой прямой способ поможет любому новому поиску ответа приземлиться здесь.
В студии Android вы можете легко нажать:
Вы также можете изменить versionCode вашего приложения.
В build.gradle измените minSdkVersion 13 на minSdkVersion 8 Это все, что вам нужно сделать. Я решил свою проблему, только сделав это.
В соответствии с этим ответом вы просто не включаете minsdkversion в manifest.xml, и система сборки будет использовать значения из файла build.gradle и помещать информацию в окончательный apk.
Поскольку система сборки нуждается в этой информации, это имеет смысл. Вам не нужно указывать эти значения два раза.
Также отметьте там как минимум два файла build.gradle : один мастер и один для приложения / модуля. Тот, который нужно изменить, находится в приложении / модуле, он уже включает свойство minSdkVersion в недавно созданном проекте.
Если у вас возникли проблемы с указанием целевой SDK для API Google вместо базового пакета SDK, просто измените compileSdkVersion 19 на compileSdkVersion «Google Inc.:Google APIs:19»
Для меня работала: (щелкните правой кнопкой мыши) project-> android tools-> clear lint markers. Хотя по какой-то причине Manifest вернулась к старому (нижнему) минимальному уровню API, но после того, как я изменил его на новый (более высокий) уровень API, не было красной ошибки, и теперь проект использует новый минимальный уровень API.
Изменить: Извините, я вижу, что вы использовали Android Studio, а не Eclipse. Но я думаю, что в Studio есть похожие «четкие маркеры», и это может решить проблему.
В студии Android откройте build.gradle и отредактируйте следующий раздел:
Здесь вы можете изменить minSdkVersion с 12 до 14
Изменение minSdkVersion в манифесте не требуется. Если вы измените его в файле сборки градации, как показано ниже, вы выполните то, что вам нужно сделать.
Делаем новую версию API. Быстро и легко
Коммуникация правит миром. Взаимодействие необходимо и между людьми, и между программным обеспечением. Хотите адекватного ответа на ваш запрос к приложению? API вам в помощь! Необходимость в реализации API возникает практически во всех проектах, и со временем мы задумываемся, можно ли улучшить текущий API? Последовательность конкретных шагов и реальные примеры – наш рецепт создания рабочего web-API проекта.
Первый вопрос, который нужно задать: «А точно ли стоит реализовать новую версию API?» Возможно, уже работающая версия отвечает всем необходимым вам критериям. Но если вы уже для себя ответили «да» на поставленный вопрос, то читайте дальше и найдете наш ответ. Если вы ответили «нет», то тоже читайте дальше и применяйте наш опыт проектирования и реализации в следующих ваших проектах.
Итак, какие же задачи могут стать поводом к разработке новой реализации API. В рамках развития программных продуктов, например, в сфере комплексной безопасности, как у нас, периодически появляется необходимость ускорить процесс клиентской и серверной̆ разработки, или снизить временные затраты на поддержку и развитие API, или упростить поддержку обратной совместимости с помощью версионности API, а также добавить автогенерацию документации API. Или все эти задачи одновременно.
Какие шаги можно предпринять для решения этих задач, и как выйти на новый уровень зрелости API можно узнать в этой статье. Реальный алгоритм действий при разработке новой реализации API, описанный здесь, поможет в создании собственного проекта, а возможно станет предметом дискуссии. Комментарии профессионалов приветствуются!
Рассмотрим на примере API для работы с котиками то, как мы совершенствовали один из наших проектов.
Как понять, что стоит реализовать новую версию API
Для того чтобы понять, что API пора спасать, необходимо пройтись по следующим пунктам:
определить уровень зрелости API;
проверить, есть ли у API версионность;
проверить наличие документации API.
Разберем каждый пункт по отдельности, чтобы точно определиться, стоит ли «игра свеч» или «и так сойдет».
Определим уровень зрелости API
Для этого идеально подходит модель Леонарда Ричардсона, в которой он выделяет четыре уровня зрелости API:
Уровень 0: Один URI и один HTTP метод (в основном метод POST);
Уровень 1: Несколько URI и один HTTP метод;
Уровень 2: Несколько URI, каждый из которых поддерживает разные HTTP методы;
Уровень 3: HATEOAS. Ресурсы сами описывают свои возможности и взаимосвязи.
Если API соответствует 0 или 1 уровню зрелости, то определенно есть куда расти, потому что:
Если используется один URI, то не понятно с каким ресурсом работаем;
Не понятно, что делаем с ресурсом, так как используется один HTTP метод;
Использование одного URI создает трудности с документацией̆ API;
Использование одного URI создает трудности с логированием входящих запросов;
Из-за использования одного URI, информация о типе ресурса передается в теле запроса.
Посчитаем, сколько «если» у нас получилось, и определим направление разработки. Это поможет сконцентрироваться на задачах и четко сформулировать дальнейшие шаги.
Проверим, есть ли у API версионность
Затем необходимо проверить версионность. Это позволит реализовывать изменения в текущем API, а при необходимости даст возможность включать расширения в новую версию API. Кроме того, она позволит серверу облегчить обеспечение обратной совместимости.
Благодаря версионности можно также ранжировать документацию по версиям, чтобы разработчики клиента всегда могли определить, насколько у них актуальная документация. Согласитесь, это удобно разработчикам, тестировщикам и сотрудникам технической поддержки.
Рассмотрим 3 основных способа версионирования API и разберем подробнее каждый из них. Современные разработчики выделяют следующие способы:
Использование разных URI (Uniform Resource Identifier);
Использование параметра запроса;
Использование заголовка, Accept Header/Media Type.
Каждый из приведенных способов версионирования имеет свои плюсы и минусы. И для каждого конкретного случая реализации API необходимо оценить и выбрать оптимальный способ или их комбинацию.
Использование разных URI простой в проектировании, реализации и документировании способ версионирования. Однако он имеет целый ряд недостатков:
приводит к загрязнению URI, так как префиксы и суффиксы добавляются к основным строкам URI;
разбивает существующие URI, то есть все клиенты должны обновиться до нового;
приводит к увеличению размер HTTP кэша для хранения нескольких версий;
создает большое количество дубликатов URI, может снизить производительность приложения из-за увеличения количества обращений к кэшу;
является крайне негибким и не позволяет просто изменить ресурс или небольшой их набор.
Пример:
2. Использование параметра запроса позволяет легко документировать версионность и рекомендуется к использованию в случае, если важно HTTP – кэширование. Однако и этот способ приводит к загрязнению пространства URI.
Пример:
3. Использование заголовка и Accept Header/Media Type также легко документировать и, в отличие от предыдущих способов не приводит к загрязнению пространства URI. Но и у этого способа выделяют несколько минусов:
приводит к неправильному использованию заголовков, так как они изначально предусматривались не для версионирования;
требует для управления версиями на основе заголовка и типа медиа использования таких инструментов, как Postman, или создания автоматизированных средств, добавляющих необходимый̆ заголовок в HTTP запрос.
Пример:
Выбор конкретного способа целиком лежит на плечах разработчика, исходя из поставленной задачи и навыков. Каждый вариант вполне рабочий, но имеет свою специфику и особенности реализации.
Проверим наличие документации API
Даже к фену удобно иметь описание, не говоря уже о серьезной проекте разработки ПО. Поэтому наглядное описание API всегда удобно для использования как backend, так и frontend разработчиками. Документация может быть реализована, например, с помощью Swagger (фреймворк для спецификации RESTful API), он дает возможность не только интерактивно просматривать спецификацию, но и отправлять запросы с помощью Swagger UI:
Немного окунувшись в теорию и предварительный анализ, переходим непосредственно к проектированию и реализации API. Наше API отвечал следующим критериям:
соответствует 0 уровню зрелости (Один URI и один HTTP метод);
невозможно достоверно установить, с каким ресурсом API работает и какие функции выполняет;
отсутствуют автоматизированные средства документации API, что приводит к неполной документации API или ее полному отсутствию для некоторых запросов;
появляются сложности с поддержкой обратной совместимости, так как нет версионности API.
Для большего понимания того, что не нравилось, приведем пример того, как выглядел наш API.
Пример:
Цели реализации нового API
Если в предыдущем пункте мы уверенно выявили хотя бы один пункт в существующем API, то самое время переходить к реализации нового. Основными целями, которые преследует разработчики при создании API являются:
Ускорение процесса клиентской и серверной̆ разработки;
Снижение временных затрат на поддержку и развитие API;
Добавление автогенерации документации API;
Поддержка версионности API для упрощения поддержки обратной совместимости с помощью версионности API.
Таким образом, проект получает автономность от его создателя, гибкость в масштабировании и апгрейде и, зачастую, серьезно выигрывает по производительности в целом.
Повышаем уровень зрелости API
Для решения вышеперечисленных проблем и достижения целей было принято решение о переходе на 2 уровень зрелости API. Это позволило понять, с каким ресурсом идет текущая работа и что с ним необходимо сделать, плюс появилась возможность документировать API.
Для того, чтобы повысить API с 0 на 2 уровень зрелости были проанализированы все текущие проблемы и выделены следующие пункты:
1. Разделение текущего API на смысловые части для выделения соответствующего ресурса для каждой части;
2. Использование методов, соответствующих действиям над ресурсами: GET, POST, PUT, DELETE;
3. Обозначение ресурса во множественном числе;
Пример:
4. Указание фильтрации в параметрах.
Пример:
Добавляем версионность
После повышения зрелости API выходим на новый этап и выбираем способ версионирования. Для текущего проекта был выбран способ версионирования с использованием собственного заголовка. Это решение не попадает в пункт “неправильное использование заголовков”, так как будет использоваться собственный заголовок. Для удобства было решено указывать версии вида “2.n”.
Для начала реализуем контроллер:
После этого для реализации версионности, создадим enum:
Если в заголовке было отправлено значение “2.0”, до контроллера оно дойдет уже в виде “v2”. При такой реализации вместо того, чтобы перечислять все доступные версии, можно будет указать в заголовке, что ожидается enum. А контроллер после добавления версионирования будет выглядеть так:
При дальнейшем развитии API и реализации новых версий, список всех существующих версий будет храниться в enum. Когда для конкретной̆ новой̆ версии потребуется уникальная реализация, то в контроллере можно будет указать версию явно.
Указание версии было решено сделать обязательным.
Документируем
И наконец переходим к документированию. Критерии выбора конкретного инструмента были основаны на собственном опыте и дискуссии с коллегами-разработчиками. В ходе обсуждения был выбран популярный и широко используемый инструмент автогенерации API Swagger. Он не является единственным для решения задач документирования, но в нашем случае был признан оптимальным, так как бесплатен, прост для освоения и обладает необходимым набором функций для грамотного документирования API.
Рассмотрим пример реализации документации для созданного выше контроллера. Для этого реализуем интерфейс:
С его помощью можно добавить название и описание API текущего контроллера, описание каждого запроса, плюс есть возможность указать схему тела запроса. Остальную информацию Swagger получает из аннотаций контроллера.
Перейдя в Swagger UI увидим задокументированное API:
Получим более подробную информацию:
Преимущества новой версии API
На примерах выше был продемонстрирован переход с 0 уровня зрелости API на 2 уровень зрелости согласно модели Ричардсона, благодаря этому мы получили:
повышение уровня зрелости API, что дало понимание, с каким ресурсом мы работаем и что с ним делаем;
версионирование, которое позволит вносить изменения в текущий API;
удобное документирование и появление внятной документации, да и документации вообще.
В итоге и на стороне сервера, и на стороне клиента теперь можно увидеть актуальный API с полным описанием методов, моделей, кодов ответов, параметров запроса и версий. Это значительно упростит разработку новых версий в будущим и сэкономит время на разбор чужого кода.
Скорость разработки при переходе на новую версию API значительно возросла, ведь разработчикам стало значительно удобнее и приятнее работать. Наш путь разработки оказался вполне рабочим и его смело можно рекомендовать для применения в реальных проектах. А может в вашем арсенале есть другие варианты? Готовы обсудить!
Уровень API игры на Unity3d для публикации в Google Play (error API level 29)
При публикации приложения в Google Play у вас может появится ошибка связанная с используемым им уровнем API:
«You uploaded a debuggable APK or Android App Bundle. For security reasons you need to disable debugging before it can be published in Google Play. Learn more about debuggable APKs or Android App Bundles. You App currently targets API livel 28 and must target at least API level 29 to ensure it is built on the latest APIs optimized for security and perfomance. Change your app’s target API level to at least 29.»
«Вы загрузили отлаживаемый APK или Android App Bundle. По соображениям безопасности вам необходимо отключить отладку, прежде чем ее можно будет опубликовать в Google Play. Узнайте больше об отлаживаемых APK-файлах или наборах Android-приложений. Ваше приложение в настоящее время нацелено на API livel 28 и должно быть ориентировано как минимум на уровень API 29, чтобы гарантировать, что оно построено на последних API, оптимизированных для обеспечения безопасности и производительности. Измените целевой уровень API вашего приложения как минимум на 29.»
На момент написания этого поста Google Play требует для всех новых игр целевой уровень API равный 29 или выше. Эта настройка находится (в Unity3d) в «File» — «Build Settings» — «Player Settings» — «Player» — «Android» — «Other Settings» — «Target API Level».
Если после смены целевого уровня API приложение успешно собралось, то проблема решена. Google Play примет эту версию. В моём же случае все оказалось немного сложнее. В установленном Unity3D не оказалось требуемой версии Android SDK и его пришлось скачивать отдельно.
Через функцию «Update Android SDK» внутри Unity3d обновление не устанавливалось. Обновить Android SDK мне помог старый-добрый Android Studio. После загрузки и установки Adnroid Studio зайдите в «File» — «Settings» — «Appearance & Behavior» — «System Settings» — «Android SDK».
В этом окне настроек необходимо скачать недостающие версии — это делается путем установки флажка напротив желаемой версии и нажатии кнопки «Apply». Далее откройте в проводнике директорию с расположением всех версий SDK («Android SDK Location») и скопируйте нужную версию в директорию которую использует Unity3d для своей работы. Путь к этой директории находится в редакторе Unity3d — «Edit» — «Preferences» — «External Tools» — «Android SDK Tools».
После копирования требуемой версии Android SDK приложение будет собираться без проблем и Google Play его одобрит.