Kivy. Сборка пакетов под Android и никакой магии

Во вчерашней статье Python в Mobile development, в которой речь шла о библиотеке KivyMD (коллекции виджетов в стиле Material Design для использования их в кроссплатформенном фреймворке Kivy), в комментариях меня попросили рассказать о процессе сборки пакета для платформы Android. Для многих этот процесс, к сожалению, был и остается чем-то из ряда магического шаманства и не подъёмным для новичков делом. Что ж, давайте разбираться, так ли на самом деле все сложно и действительно ли я маг и волшебник.

Конечно, мог бы! Итак, вы написали свой код на Python и Kivy. Что нужно для того, чтобы это можно было запустить на Android устройствах? Перейдите в репозиторий KivyMD и вы увидите, что в этой инструкции уже давно прописаны шаги, которые позволят вам собрать APK пакет:
- Загрузите XUbuntu 18.04
wget https://github.com/HeaTTheatR/KivyMD-data/raw/master/install-kivy-buildozer-dependencies.sh
chmod +x install-kivy-buildozer-dependencies.sh
./install-kivy-buildozer-dependencies.sh
Все! Теперь у вас есть виртуальная машина для сборки APK пакетов для приложений Kivy! Что дальше? Давайте, собственно, займемся сборкой тестового приложения. Создайте в домашнем каталоге вашей виртуальной машины директорию TestKivyMD с пустым файлом main.py:

Далее откройте файл main.py и напишите код нашего тестового приложения, которое будет использовать библиотеку KivyMD:
from kivy.lang import Builder from kivymd.app import MDApp KV = """ Screen: MDToolbar: title: "My firt app" elevation: 10 md_bg_color: app.theme_cls.primary_color left_action_items: [["menu", lambda x: x]] pos_hint: MDRaisedButton: text: "Hello World" pos_hint: """ class HelloWorld(MDApp): def build(self): return Builder.load_string(KV) HelloWorld().run()
Сохраните, откройте терминал в директории с файлом main.py и установите библиотеку KivyMD:
sudo pip3 install kivymd
После установки можно протестировать наш код:
python3 main.py
Результатом работы скрипта будет экран с Toolbar и одной кнопкой «Hello World»:

Дальше нам нужно создать файл спецификации buildozer.spec, который должен располагаться в той же директории, что и файл main.py:

Если вы не закрывали терминал (если терминал был закрыт, откройте его в директории TestKivyMD), введите команду:
buildozer init
Эта команда создаст дефолтный файл спецификации. Откройте его и отредактируйте:
[app] # (str) Title of your application title = KivyMDTest # (str) Package name package.name = kivymd_test # (str) Package domain (needed for android/ios packaging) package.domain = com.heattheatr # (str) Source code where the main.py live source.dir = . # (list) Source files to include (let empty to include all the files) source.include_exts = py,png,jpg,jpeg,ttf # (list) Application version version = 0.0.1 # (list) Application requirements # comma separated e.g. requirements = sqlite3,kivy requirements = python3,kivy==1.11.1,kivymd # (str) Supported orientation (one of landscape, sensorLandscape, portrait or all) orientation = portrait # (bool) Indicate if the application should be fullscreen or not fullscreen = 1 # (list) Permissions android.permissions = INTERNET,WRITE_EXTERNAL_STORAGE # (int) Target Android API, should be as high as possible. android.api = 28 # (int) Minimum API your APK will support. android.minapi = 21 # (str) Android NDK version to use android.ndk = 17c # (bool) If True, then skip trying to update the Android sdk # This can be useful to avoid excess Internet downloads or save time # when an update is due and you just want to test/build your package android.skip_update = False # (bool) If True, then automatically accept SDK license # agreements. This is intended for automation only. If set to False, # the default, you will be shown the license when first running # buildozer. android.accept_sdk_license = True # (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64 android.arch = armeabi-v7a [buildozer] # (int) Log level (0 = error only, 1 = info, 2 = debug (with command output)) log_level = 2 # (int) Display warning if buildozer is run as root (0 = False, 1 = True) warn_on_root = 0 # (str) Path to build artifact storage, absolute or relative to spec file build_dir = ./.buildozer # (str) Path to build output (i.e. .apk, .ipa) storage bin_dir = ./bin
Здесь все понятно поэтому дополнительные комментарии излишни. Почитайте внимательно дефолтную спецификацию, в ней можно указать путь к иконке, пресплеш при загрузке приложения и многое другое. Я оставил лишь то, что нам сейчас нужно для сборки нашего тестового пакета. И, собственно, запускаем процесс сборки командой в терминале:
buildozer android debug
Можете смело идти на кухню и заваривать кофе, потому что в первый раз процесс загрузки и компиляции библиотек займет очень много времени. Все последующие сборки проходят за 10-20 секунд.
Кофе выпит и самое время заглянуть в терминал:

Вуаля! Наше приложение построено! Самое время закинуть его на смартфон и запустить:
Все работает! И оказывается не все так сложно, как казалось.
Также меня спрашивали:

Ни у Flutter ни у React Native нет преимуществ перед языком разметки Kivy Language, которая позволяет создавать и позиционировать лайоуты и виджеты. Как по мне, то, как строится UI во Flutter — это самое настоящее извращение. Придумать это мог только больной на голову человек. Чтобы не быть голословным, давайте посмотрим на код Flutter и код Kivy одного и того же простейшего приложения… Выглядеть оно будет следующим образом:
import 'package:flutter/widgets.dart'; main() => runApp( Directionality( textDirection: TextDirection.ltr, child: Container( color: Color(0xFFFFFFFF), child: App(), ), ), ); class App extends StatelessWidget < @override Widget build(BuildContext context) < return Center( child: GestureDetector( // используется как обычный виджет onTap: () < // одно из свойств GestureDetector // Этот метод будет вызван, когда дочерний элемент будет нажат print('You pressed me'); >, child: Container( // нашей кнопкой будет контейнер decoration: BoxDecoration( // стилизуем контейнер shape: BoxShape.circle, // зададим ему круглую форму color: Color(0xFF17A2B8), // и покрасим его в синий ), width: 80.0, height: 80.0, ), ), ); > > class Counter extends StatefulWidget < // Изменяемое состояние хранится не в виджете, а внутри объекта особого класса, // создаваемого методом createState() @override StatecreateState() => _CounterState(); // Результатом функции является не просто объект класса State, // а обязательно State > class _CounterState extends State < // Внутри него мы наконец-то можем объявить динамические переменные, // в которых мы будем хранить состояние. // В данном случае, это счетчик количества нажатий int counter = 0; // А дальше все очень просто, мы имплементируем точно такой же метод // для отрисовки виджетов, который мы использовали в классе Stateless виджета. @override Widget build(BuildContext context) < // И тут практически ничего не изменилось с нашего последнего примера, // а то что изменилось — я прокомментировал: return Center( child: GestureDetector( onTap: () < // В момент, когда кнопка нажата, мы увеличиваем значение // перменной counter. setState(() < // setState() необходим для того, чтобы вызвать методы // жизненного цикла виджета и сказать ему, что пора обновится ++counter; >); >, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, color: Color(0xFF17A2B8), ), width: 80.0, child: Center( child: Text( // выводим значение свойства counter '$counter', // чтобы следить за его изменением style: TextStyle(fontSize: 30.0), ), ), ), ), ); > >
А вот абсолютно тоже самое, но с использованием Kivy и KivyMD:
from kivy.lang import Builder from kivymd.app import MDApp KV = """ #:import get_color_from_hex kivy.utils.get_color_from_hex Screen: MDCard: MDLabel: value: 0 text: str(self.value) halign: "center" on_touch_down: self.value += 1 canvas.before: Color: rgba: get_color_from_hex("#4eaabe") Ellipse: pos: self.center[0] - dp(25), self.center[1] - dp(25) size: dp(50), dp(50) """ class HelloWorld(MDApp): def build(self): return Builder.load_string(KV) HelloWorld().run()
По-моему, вывод очевиден и не нуждается в моем комментировании…
Надеюсь, был вам полезен. Оставляю опрос на тему «Удалось ли вам построить приложение для Андроид».
Как создать .apk файл с помощью buildozer в Windows?
При попытке создания файла .apk через buildozer столкнулся с проблемой, что если это делать в Windows, то не создается target android, это видно если прописать в терминале buildozer help . Если создать виртуальную машину с Ubuntu, то там этой проблемы нет, но пока не хотелось бы переходить на неё, рано ещё. Вероятно проблема из-за того, что надо установить модуль python-for-android, но он не доступен для Windows, если я правильно понял. Это моя первая попытка использования buildozer, ubuntu и виртуальных машин, так что уже мозг кипит, возможно не понимаю какой-то нюанс. Кто-нибудь знает как добавить отдельно target для android? Или установить модуль python-for-android, если дело в нём? Или может подскажете гайд, где пошагово показана работа buildozer именно для Windows? Не нашел такого гайда, а по официальной документации почему-то не выходит добиться результата. В крайнем случае — подскажите пожалуйста как еще можно создать .apk файл из python именно в Windows? Игра на pygame, если это важно. Первый скрин — терминал PyCharm в Windows, второй — в Ubuntu

Отслеживать
задан 24 фев в 16:57
335 1 1 серебряный знак 12 12 бронзовых знаков
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Отвечу сам. Заодно памятка будет на будущее.
- Вместо виртуальных машин устанавливаем Windows Subsystem for Linux (WSL) — правой кнопкой на меню пуск, WindowsPowerShell (администратор), wsl —install , перезагрузка. Подробная инструкция тут.
- Переходим в папку с проектом через консоль WSL. Или открываем путь к ней в проводнике и на папке, в которой находит основной файл программы (или внутри этой папки на пустом месте), и нажимаем сочетание Shift+ПКМ. В контекстном меню добавится новый пункт «Откройте здесь оболочку Linux«, нажимаем туда.
ВАЖНО. В названии папки с main.py не должно быть пробелов. А основной файл должен называться именно main.py (можно будет изменить это требование на 5 шаге)
- Вводим команду (чтобы вставить в консоль скопированный текст нажмите в ней правую кнопку мыши):
sudo apt update
Если в конце её работы видим ошибки вроде:
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy/InRelease Temporary failure resolving 'archive.ubuntu.com' W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy-updates/InRelease Temporary failure resolving 'archive.ubuntu.com' W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy-backports/InRelease Temporary failure resolving 'archive.ubuntu.com' W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease Temporary failure resolving 'security.ubuntu.com' W: Some index files failed to download. They have been ignored, or old ones used instead.
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf > /dev/null sudo apt update
Eесли ошибок нет, но в последней строке написано что-то вроде
4 packages can be upgraded. Run 'apt list --upgradable' to see them.
sudo apt upgrade sudo apt update
Вроде как это необязательно, но на мой взгляд лучше обновить.
- Продолжаем поочередно вводить команды отсюда:
sudo apt install -y git zip unzip openjdk-17-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev pip3 install --user --upgrade Cython==0.29.33 virtualenv export PATH=$PATH:~/.local/bin/ pip3 install --user --upgrade buildozer buildozer init
- В папке появится файл настроек, который можно редактировать хоть блокнотом, хоть IDLE. В строке с зависимостями добавьте импортируемые модули. В моем случае вместо kivy нужны pygame , pygame-menu и typing-extensions . Там же можно поменять название, автора, ориентацию и т.д. В официальной документации buildozer и python-for-android достаточно подробно описано.
# (list) Application requirements # comma separated e.g. requirements = sqlite3,kivy requirements = python3,pygame,pygame-menu,typing-extensions
На мой взгляд этот пункт самый важный, так как у меня приложение вылетало пока я не добавил последний модуль typing-extensions . Он нужен из-за модуля pygame-menu , но на ПК и без него работает, а его добавление для андроида нигде не документируется. Чтобы это понять мне пришлось узнать что такое Android Studio, logcat, виртуальное устройство, расшифровка логов и т.д. Остальные пункты удобнее настраивать когда приложение уже запускается и можно смотреть разницу при их изменении в разных сборках. Но если накосячить тут, то запустить не получится.
Закрываем файл, сохранив изменения.
- Вводим команду для начала создания .apk файла:
buildozer android debug
В примерах регулярно советуют добавлять deploy run , но если вы не подключали заранее устройство, то не нужно этого делать. Без этих команд скомпилируется .apk файл, который уже сами скинете куда надо. В первый раз в процессе создания файла надо будет 2 раза ввести y , чтобы согласиться с условиями лицензии. Файл .apk будет в папке bin , дальше его можно скидывать на телефон или виртуальное устройство.
Лично я в buildoser.spec прописал bin_dir = /mnt/h/ЯДиск где ЯДиск- папка, автоматически синхронизирующая все содержимое с облаком. Сразу же после создания файла он оказывается в этой папке (или перезаписывает предыдущую версию) и отправляется в облако. Остается открыть облако на телефоне и запустить синхронизированный .apk для установки. Самый удобный метод без использования кабелей, что я смог придумать. Можно еще вроде Android Studio соединить с телефоном по Wi-Fi и тогда уже разворачивать приложение автоматически после сборки, но не каждый телефон поддерживает такую синхронизацию
VS Web School

В предыдущем посте мы рассматривали как Как установить Kivy и Buildozer на Ubuntu 14.04 (Часть 1) , в этой статье мы сделаем компиляцию нашего кода в .apk файл с помощью Buildozer. Если вы читали предыдущую статью то, вы уже установили Buildozer в ваше виртуальное окружение. Однако, мы еще не готовы к созданию .apk файла.
Продолжим. Создадим папку myapp и файл main.py
(pyvenv)vlad@vs:/media/vlad/android/pyvenv$ mkdir myapp
(pyvenv)vlad@vs:/media/vlad/android/pyvenv$ cd myapp
(pyvenv)vlad@vs:/media/vlad/android/pyvenv/myapp$ nano main.py
Добавьте этот код:
Это очень простое приложение которое содержит кнопку и текст на ней «Hello World». Кнопка ничего не делает, когда вы нажимаете на нее, она только изменяет цвета фона, по умолчанию она является частью интерфейса в Kivy.
Теперь нам нужно проверить код, прежде чем мы будем его компилировать. Случайная ошибка в коде может повлиять на компиляцию файла .apk или же на работу в самом телефоне.
Запустим наше приложение
(pyvenv)vlad@vs:/media/vlad/android/pyvenv/myapp$ python main.py
Должна появиться вот такая кнопка
После этого шага, нужно инициализировать Buildozer в этой папке:
$ buildozer init
В текущей папке появиться файл с именем buildozer.spec . В нем находится много опций, которые мы можем изменить. Это настройки нашего приложения и процесса компиляции.
Настоятельно рекомендуется изменить LOG_LEVEL на ( debug ) в buildozer.spec для того, чтобы увидеть ошибки компиляции. Со временем, вы можете столкнуться с различными ошибками и режим отладки, будет очень полезным для их решения.
В файле buildozer.spec, нужно установить LOG_LEVEL со значением = 2 :
Выбираем Application Versioning с методом 2, она нужна Buildozer для компиляции приложения.
Для того, чтобы собрать .apk и проверить код на ошибки используйте эту команду:
(pyvenv)vlad@vs:/media/vlad/android/pyvenv/myapp$ buildozer android debug
В некоторых случаях .apk почему-то не хочет компилироваться если виртуальное окружение находится не в домашней директории, а на другом диске, тогда создайте ваше виртуальное окружение в папке /home это должно помочь. И повторите все шаги, которые были описаны выше.
Как сделать apk файл kivy
Поиск по сайту. Поиск
Корзина пуста.
Открыть меню

Playlist: Как сделать apk файл для Android из kivy приложения на Python
Если вам понравились материалы сайта, вы можете поддержать проект финансово, переведя некоторую сумму с банковской карты, счёта мобильного телефона или из кошелька ЮMoney.
Похожие записи


28.04.2023 28.04.2023 Рубрики


15.01.2022 17.01.2022 Рубрики


Подписаться
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Новые статьи
- Как обойти запрет на обход блокировок в России на сайтах с WordPress
- HTTP/3 и WordPress: понимание и использование HTTP/3
- Подборка полезных сервисов с искусственным интеллектом
- Подборка сервисов на основе нейросетей
- Подборка онлайн-сервисов для создания видео
Почему меня рекомендуют?
Я работаею всегда честно! К примеру, если услуга стоит 5000 рублей, то и беру за неё 5000, а не 9000 или 15000. Клиенты чувствуют, что здесь обмана нет. Честность — это мой принцип: я никогда не путаюсь в ценах, так как они не меняются от проекта к проекту.
— Честная ценовая политика;
— Качество разработки;
— Дружественное общение;
— Всегда на связи!;
Что вы получите?
— квалифицированную консультацию, понятную для вас;
— качественное исполнение задачи;
— экономию средств и времени на изготовление и продвижение сайта;
— комфортное развитие сайта (я рассказываю, что и как происходит с вашим проектом);
— красивый и удобный дизайн;
— качественную, безопасную CMS;
— оформление и наполнение сайта;
— понятную и быструю панель управления сайтом;
— мобильную версию;
— быструю загрузку сайта;
— помощь при выборе и регистрации домена и хостинга;
— подготовку проекта к SEO оптимизации.
Почему разные цены?
Сайт — это целый организм и на его стоимость влияют десятки разных факторов. Некоторых людей при заказе сайта интересует только цена. Но вы же, к примеру, понимаете, почему один автомобиль стоит дешевле другого, так же и с сайтами.
Если вебмастер говорит доступным для вас языком, значит можно продолжать сотрудничество. Задавайте вопросы, чтобы избежать мошенников.
Удачных Вам разработок!