In this article, I will explain how we can convert a cross-platform application made using kivy/kivymd in python on Windows to an APK file without the need for a Linux machine. For this, I will use the online platform called Google Colab.
After logging into google colab, let's prepare the environment for the conversion process. Do not forget to upload the project you are working on. Follow these commands step by step:
!sudo apt update
!sudo apt install -y git zip unzip openjdk-8-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev
!pip3 install --upgrade Cython==0.29.19 virtualenv
!export PATH=$PATH:~/.local/bin/
!pip install buildozer
!sudo apt-get install -y \
python3-pip \
build-essential \
git \
python3 \
python3-dev \
ffmpeg \
libsdl2-dev \
libsdl2-image-dev \
libsdl2-mixer-dev \
libsdl2-ttf-dev \
libportmidi-dev \
libswscale-dev \
libavformat-dev \
libavcodec-dev \
zlib1g-dev
!sudo apt-get install -y \
python3-pip \
build-essential \
git \
python3 \
python3-dev \
ffmpeg \
libsdl2-dev \
libsdl2-image-dev \
libsdl2-mixer-dev \
libsdl2-ttf-dev \
libportmidi-dev \
libswscale-dev \
libavformat-dev \
libavcodec-dev \
zlib1g-dev
!sudo apt-get install build-essential libsqlite3-dev sqlite3 bzip2 libbz2-dev zlib1g-dev libssl-dev openssl libgdbm-dev libgdbm-compat-dev liblzma-dev libreadline-dev libncursesw5-dev libffi-dev uuid-dev libffi6
!sudo apt-get install libffi-dev
Now our environment is ready. We can start the conversion process. We will use buildozer for this. Run this command to start Buildozer:
!buildozer init
This command will create a configuration file named buildozer.spec for us. Now it's time to edit this file. At least you should change the;
title
, package.name
, package.domain
.
After changing these, my suggestion is to make some more changes to avoid some problems. Let's look at source.dir
first, if your main.py
file is in the same directory, there is no need to change it, but if not, you should write the path
here.
Afterwards, if you have used separate files such as png, txt, csv in the program, you should add the extension to source.include_exts
.
Now let's change the most important, requirements
. If you only used kivy, python3,kivy==2.0.0rc4
will be enough to do it this way.If you also used kivymd then you should add this https://github.com/kivymd/KivyMD/archive/master.zip
. If you have used other libraries, run the pip install <library-name>
command, and it will show the downloaded packages. You can add them without specifying the version.
If you want to use icon you can uncomment icon.filename
and you can edit the path.
If you want your app to be fullscreen, you can make fullscreen
1.
We will need to clone python-for-android to avoid problems such as not showing some symbols.
!git clone <git-link-of-forked-repo>
Then we need to edit it in spec file.p4a.source_dir = /path/to/your/python-for-android
and p4a.branch = develop
.
Finally, if you need permissions on android you have to write them.We are done with spec file for now.
Now we can start the conversion process by this command:
!buildozer -v android debug
When you first run this process, it may take up to 15-20 minutes depending on your internet speed. When the process is finished, your bin/*.apk file is ready and you can download it to the phone.
If the application does not work, you can create a log file from the phone. For this, try to run the application after clicking on the settings / developer option / bug report. After waiting for a while, it will also show the process in the notification bar. You can now see the errors by sharing it to your computer.
You can also check out my project that I made using kivymd.
Mehmet Karagoz.
Top comments (5)
[WARNING]: ERROR: /content/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/other_builds/hostpython3/desktop/hostpython3/native-build/python3 failed!
Command failed: ['/usr/bin/python3', '-m', 'pythonforandroid.toolchain', 'create', '--dist_name=KringCalc', '--bootstrap=sdl2', '--requirements=python3,kivy==master,kivymd,android.permissions', '--arch=arm64-v8a', '--arch=armeabi-v7a', '--copy-libs', '--color=always', '--storage-dir=/content/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a', '--ndk-api=21', '--ignore-setup-py', '--debug']
ENVIRONMENT:
SHELL = '/bin/bash'
NV_LIBCUBLAS_VERSION = '12.2.5.6-1'
NVIDIA_VISIBLE_DEVICES = 'all'
COLAB_JUPYTER_TRANSPORT = 'ipc'
NV_NVML_DEV_VERSION = '12.2.140-1'
NV_CUDNN_PACKAGE_NAME = 'libcudnn8'
CGROUP_MEMORY_EVENTS = '/sys/fs/cgroup/memory.events /var/colab/cgroup/jupyter-children/memory.events'
NV_LIBNCCL_DEV_PACKAGE = 'libnccl-dev=2.19.3-1+cuda12.2'
NV_LIBNCCL_DEV_PACKAGE_VERSION = '2.19.3-1'
VM_GCE_METADATA_HOST = '169.254.169.253'
HOSTNAME = '21d8c3bdb0d3'
LANGUAGE = 'en_US'
TBE_RUNTIME_ADDR = '172.28.0.1:8011'
GCE_METADATA_TIMEOUT = '3'
NVIDIA_REQUIRE_CUDA = ('cuda>=12.2 brand=tesla,driver>=470,driver<471 '
'brand=unknown,driver>=470,driver<471 brand=nvidia,driver>=470,driver<471 '
'brand=nvidiartx,driver>=470,driver<471 brand=geforce,driver>=470,driver<471 '
'brand=geforcertx,driver>=470,driver<471 brand=quadro,driver>=470,driver<471 '
'brand=quadrortx,driver>=470,driver<471 brand=titan,driver>=470,driver<471 '
'brand=titanrtx,driver>=470,driver<471 brand=tesla,driver>=525,driver<526 '
'brand=unknown,driver>=525,driver<526 brand=nvidia,driver>=525,driver<526 '
'brand=nvidiartx,driver>=525,driver<526 brand=geforce,driver>=525,driver<526 '
'brand=geforcertx,driver>=525,driver<526 brand=quadro,driver>=525,driver<526 '
'brand=quadrortx,driver>=525,driver<526 brand=titan,driver>=525,driver<526 '
'brand=titanrtx,driver>=525,driver<526')
NV_LIBCUBLAS_DEV_PACKAGE = 'libcublas-dev-12-2=12.2.5.6-1'
NV_NVTX_VERSION = '12.2.140-1'
COLAB_JUPYTER_IP = '172.28.0.12'
NV_CUDA_CUDART_DEV_VERSION = '12.2.140-1'
NV_LIBCUSPARSE_VERSION = '12.1.2.141-1'
COLAB_LANGUAGE_SERVER_PROXY_ROOT_URL = '172.28.0.1:8013/'
NV_LIBNPP_VERSION = '12.2.1.4-1'
NCCL_VERSION = '2.19.3-1'
KMP_LISTEN_PORT = '6000'
TF_FORCE_GPU_ALLOW_GROWTH = 'true'
ENV = '/root/.bashrc'
PWD = '/content'
TBE_EPHEM_CREDS_ADDR = '172.28.0.1:8009'
COLAB_LANGUAGE_SERVER_PROXY_REQUEST_TIMEOUT = '30s'
TBE_CREDS_ADDR = '172.28.0.1:8008'
NV_CUDNN_PACKAGE = 'libcudnn8=8.9.6.50-1+cuda12.2'
NVIDIA_DRIVER_CAPABILITIES = 'compute,utility'
COLAB_JUPYTER_TOKEN = ''
LAST_FORCED_REBUILD = '20240122'
NV_NVPROF_DEV_PACKAGE = 'cuda-nvprof-12-2=12.2.142-1'
NV_LIBNPP_PACKAGE = 'libnpp-12-2=12.2.1.4-1'
NV_LIBNCCL_DEV_PACKAGE_NAME = 'libnccl-dev'
TCLLIBPATH = '/usr/share/tcltk/tcllib1.20'
NV_LIBCUBLAS_DEV_VERSION = '12.2.5.6-1'
COLAB_KERNEL_MANAGER_PROXY_HOST = '172.28.0.12'
NVIDIA_PRODUCT_NAME = 'CUDA'
NV_LIBCUBLAS_DEV_PACKAGE_NAME = 'libcublas-dev-12-2'
USE_AUTH_EPHEM = '1'
NV_CUDA_CUDART_VERSION = '12.2.140-1'
COLAB_WARMUP_DEFAULTS = '1'
HOME = '/root'
LANG = 'en_US.UTF-8'
COLUMNS = '100'
CUDA_VERSION = '12.2.2'
CLOUDSDK_CONFIG = '/content/.config'
NV_LIBCUBLAS_PACKAGE = 'libcublas-12-2=12.2.5.6-1'
NV_CUDA_NSIGHT_COMPUTE_DEV_PACKAGE = 'cuda-nsight-compute-12-2=12.2.2-1'
COLAB_RELEASE_TAG = 'release-colab_20240125-060137_RC00'
PYDEVD_USE_FRAME_EVAL = 'NO'
KMP_TARGET_PORT = '9000'
CLICOLOR = '1'
KMP_EXTRA_ARGS = ('--logtostderr --listen_host=172.28.0.12 --target_host=172.28.0.12 '
'--tunnel_background_save_url=colab.research.google.com/tun/m/cc... '
'--tunnel_background_save_delay=10s '
'--tunnel_periodic_background_save_frequency=30m0s '
'--enable_output_coalescing=true --output_coalescing_required=true')
NV_LIBNPP_DEV_PACKAGE = 'libnpp-dev-12-2=12.2.1.4-1'
COLAB_LANGUAGE_SERVER_PROXY_LSP_DIRS = '/datalab/web/pyright/typeshed-fallback/stdlib,/usr/local/lib/python3.10/dist-packages'
NV_LIBCUBLAS_PACKAGE_NAME = 'libcublas-12-2'
COLAB_KERNEL_MANAGER_PROXY_PORT = '6000'
CLOUDSDK_PYTHON = 'python3'
NV_LIBNPP_DEV_VERSION = '12.2.1.4-1'
ENABLE_DIRECTORYPREFETCHER = '1'
NO_GCE_CHECK = 'False'
JPY_PARENT_PID = '85'
PYTHONPATH = '/env/python'
TERM = 'xterm-color'
NV_LIBCUSPARSE_DEV_VERSION = '12.1.2.141-1'
GIT_PAGER = 'cat'
LIBRARY_PATH = '/usr/local/cuda/lib64/stubs'
NV_CUDNN_VERSION = '8.9.6.50'
SHLVL = '0'
PAGER = 'cat'
COLAB_LANGUAGE_SERVER_PROXY = '/usr/colab/bin/language_service'
NV_CUDA_LIB_VERSION = '12.2.2-1'
NVARCH = 'x86_64'
NV_CUDNN_PACKAGE_DEV = 'libcudnn8-dev=8.9.6.50-1+cuda12.2'
NV_CUDA_COMPAT_PACKAGE = 'cuda-compat-12-2'
MPLBACKEND = 'module://ipykernel.pylab.backend_inline'
NV_LIBNCCL_PACKAGE = 'libnccl2=2.19.3-1+cuda12.2'
LD_LIBRARY_PATH = '/usr/local/nvidia/lib:/usr/local/nvidia/lib64'
COLAB_GPU = ''
GCS_READ_CACHE_BLOCK_SIZE_MB = '16'
NV_CUDA_NSIGHT_COMPUTE_VERSION = '12.2.2-1'
NV_NVPROF_VERSION = '12.2.142-1'
LC_ALL = 'en_US.UTF-8'
COLAB_FILE_HANDLER_ADDR = 'localhost:3453'
PATH = '/root/.buildozer/android/platform/apache-ant-1.9.4/bin:/opt/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin'
NV_LIBNCCL_PACKAGE_NAME = 'libnccl2'
COLAB_DEBUG_ADAPTER_MUX_PATH = '/usr/local/bin/dap_multiplexer'
NV_LIBNCCL_PACKAGE_VERSION = '2.19.3-1'
PYTHONWARNINGS = 'ignore:::pip._internal.cli.base_command'
DEBIAN_FRONTEND = 'noninteractive'
COLAB_BACKEND_VERSION = 'next'
OLDPWD = '/'
_ = '/usr/local/bin/buildozer'
PACKAGES_PATH = '/root/.buildozer/android/packages'
ANDROIDSDK = '/root/.buildozer/android/platform/android-sdk'
ANDROIDNDK = '/root/.buildozer/android/platform/android-ndk-r25b'
ANDROIDAPI = '31'
ANDROIDMINAPI = '21'
Buildozer failed to execute the last command
The error might be hidden in the log above this error
Please read the full log, and search for it before
raising an issue with buildozer itself.
In case of a bug report, please add a full log with log_level = 2
Thanks for the post.
If Pandas is needed , how to go about?
You actually can't!!
I have an app made in kivy with pandas, but it compiled with error :(
I am using pyodbc, kivy, kivymd, how to do?