DEV Community

Cover image for How to convert kivy/kivymd app to apk in Windows?
Mehmet
Mehmet

Posted on • Updated on

How to convert kivy/kivymd app to apk in Windows?

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
Enter fullscreen mode Exit fullscreen mode
!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
Enter fullscreen mode Exit fullscreen mode
!pip3 install --upgrade Cython==0.29.19 virtualenv
Enter fullscreen mode Exit fullscreen mode
!export PATH=$PATH:~/.local/bin/
Enter fullscreen mode Exit fullscreen mode
!pip install buildozer
Enter fullscreen mode Exit fullscreen mode
!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
Enter fullscreen mode Exit fullscreen mode
!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
Enter fullscreen mode Exit fullscreen mode
!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
Enter fullscreen mode Exit fullscreen mode
!sudo apt-get install libffi-dev
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Resources

Buildozer Installation
Spec file
Running
p4a
in addition

Top comments (5)

Collapse
 
kringeometr profile image
Kringeometr

[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

Collapse
 
aatmaj profile image
Aatmaj

Thanks for the post.

Collapse
 
kattaramana profile image
kattaRamana

If Pandas is needed , how to go about?

Collapse
 
eklavya profile image
Eklavya

You actually can't!!
I have an app made in kivy with pandas, but it compiled with error :(

Collapse
 
kushp15 profile image
kushp15

I am using pyodbc, kivy, kivymd, how to do?