If you are a Windows/Mac developer using Kivy to build an Android app you will have to use Linux or a Linux VM to build a distribution. I was able to build a test app with a Lubuntu VM, however, I was not able to properly debug my first app because I could not get the VM to interact with a USB device. Once I set up an Linux installation I was able to debug and build my app.
Creating a Linux Virtual Machine
Download and install VirtualBox. If you have never used Linux before I recommend a Ubuntu-type. I created an Lubuntu 64-bit VM. There is a known screen resolution issue with Lubuntu. During installation several screens will have the confirm buttons off-screen. Hit enter to proceed through those prompts.
I needed 12GB of space to build test app, not including the space the OS used, so don’t be stingy with the HD allocation. If you underestimate and need to allocate additional space, try this method.
One issue of note: as a Windows 8.1 user I found myself unable to build 64-bit VMs. There are two likely solutions for an Intel processor. Either Hyper-V needs to be disabled (Programs and Features) or VT-x needs to be enabled. You can find VT-x under UEFI firmware or BIOS. Mine was under BIOS, under an option called Intel Virtualization Tech.
Sharing Files with a Virtual Machine
If you developed your app in Windows you’ll need to share those files with the VM. In VirtualBox you’ll be using Guest Additions. The .iso may have been included with your VB download or you may be prompted to download when you change the needed settings.
There are several methods. I used this one.
On the host computer, enter the following on the command line in the VirtualMachine directory, modifying the shared folder path as needed:
VBoxManage sharedfolder add "YourVM" --name "/home/user/SharedFolderName" --hostpath "C:\SharedFolderName"
In the VirtualMachine Application Window toolbar, click Devices > Insert Guest Additions CD Images…
On the guest computer, enter the following on the command line:
mkdir /home/user/SharedFolderName sudo mount -t vboxsf "SharedFolderName" /home/user/SharedFolderName
One issue of note: Some programs cannot modify files in a shared folder. My office filled with hideous cackling when I discovered gedit, the text editor packed with Debian, could not modify files in the shared folder. I had no such issues with Ubuntu/Lubuntu which is one reason I recommended it.
Creating Distributions with Buildozer
The documentation recommends using Buildozer, which is designed to simplify the distribution process. I was able to build a test app using this method. You will need to make sure you have a number of programs and modules installed to use Buildozer. If you’re using a Ubuntu variant you will already have Python 2.7 on your VM.
sudo apt-get update sudo apt-get install python-pip python-dev build-essential sudo pip install --upgrade pip sudo pip install --upgrade virtualenv sudo apt-get install zlib1g-dev sudo apt-get install git sudo apt-get install cython sudo apt-get install default-jdk sudo apt-get install default-jre sudo apt-get install ccache
You will also need 32-bit libraries. If you debug without them, Buildozer will refer you to the documentation, which lists the cmd for Ubuntu.
sudo apt-get install libncurses5:i386 sudo apt-get install libstdc++6:i386 sudo apt-get install libgtk2.0-0:i386 sudo apt-get install libpangox-1.0-0:i386 sudo apt-get install libpangoxft-1.0-0:i386 sudo apt-get install libidn11:i386 sudo apt-get install zlib1g:i386
I was also asked to install several additional Python modules:
sudo pip install colorama sudo pip install appdirs sudo pip install sh sudo pip install six sudo pip install jinja2
Install and upgrade Buildozer, then initialize it in your app’s directory.
sudo pip install buildozer sudo pip install --upgrade buildozer buildozer init
Buildozer will generate a .spec file that needs to be updated with your app information. Go ahead and set the log_level to 2.
One issue of note: To avoid a bug, consider setting requirements = kivy,python2 to avoid a pythonhost context attribute error if using android_new. If using android, use python.
Once you’ve done so, run debug and buildozer will prompt you to install any missing libraries. Buildozer will install Apache ANT, the Android SDK, and the Android NDK for you. This will take a few minutes.
buildozer new_android debug
If all is well, you can deploy and run your app like so:
buildozer android debug deploy run
At some point, Buildozer may throw an error and ask you to raise the log_level in your .spec to 2. Consider:
buildozer android clean
For some problems you will need to debug, which involves attaching your Android device to USB and accessing it through the VM.
The Android SDK has the build-in debugging tool ADB logcat, which lives under platform-tools if it has been installed, and there is also a version included with buildozer.
On your Android device you will need to enable USB Debugging, which may require a special handshake unique to your device (I’m actually not joking, they hide it from the n00bz) so you’ll need to search for how to find it.
You’ll also need to download and install the VirtualBox extension pack.
I ran into several issues attempting to enable USB for Lubuntu. One, I did not have a vboxusers group. Two, when I finally did get everything set up Lubuntu knew the device was there but would not list it as a connected device. USB does appear to be somewhat finicky in VirtualBox.
Once your device is available, you can run things like. I was able to build my working distribution with the latter.
buildozer android logcat buildozer android debug deploy run
The Kivy VM
The documentation also recommends using the Kivy VM, which is a pre-built image provided by the Kivy team. Kivy VM appears to be out of date. Buildozer generated a distribution error that I could not resolve by updating. When I researched the issue I was referred back to manually installing Python-for-Android.
Installing and Using Python-for-Android
I recommend that you attempt to use Buildozer before attempting to use p4a directly. I found manually installing Android SDK/NDK to be time-consuming and confusing. I have not yet built a test app with this method, but I will document how I got to the point where I could attempt a distribution.
sudo apt-get update sudo apt-get install python-pip sudo apt-get install git sudo apt install cython pip install python-for-android pip install virtualenv sudo apt-get install ccache sudo apt-get install zlib1g-dev sudo apt-get install libncurses5:i386 libstdc++6:i386 sudo apt-get install autoconf sudo apt-get install automake sudo apt-get install build-essential libtool sudo dpkg --add-architecture i386 sudo apt-get install default-jre sudo apt-get install default-jdk
For the Android SDK and NDK, I used this guide, paraphrased below. Download and extract the Android SDK command line tools (not the Studio IDE). I unzipped the SDK in my Downloads directory. Go to the tools subdirectory in the terminal.
cd /home/user/Downloads/android-sdk-linux/tools ./android sdk
Click “Install # Packages.” You will also need to install the API for your target machine if you’re not using the latest version (in my case, this was 25). I found that the NDK, which we’ll discuss in a minute, only went to 24, so I had to install 24 of the SDK as well. See What is the API level? for an explanation and the Developer Dashboard for information on which devices use which APIs. You may encounter installation issues. Try deleting the folder and extracting it again. Don’t forget to empty your trash.
Download and extract the Android NDK. You will need to make sure you have the correct target API under /platforms. (As stated above, I found NDK didn’t have API 25.)
Packaging the Distribution
Now you should be able to run p4a. p4a generates good error messages, so hopefully if you’re missing something you’ll be able to figure out what you need to add. The command I worked with was:
p4a apk --private $HOME/KivySharedFolder/Kivy --package=org.example.letscount --name "Let's Count" --version 0.1 --bootstrap=sdl2 --requirements=python2,kivy --arch=armeabi-v7a
I was told by p4a that I needed to use the command –arch=armeabi-v7a, YMMV.