Your free e-book!

See when it is not worth using Scrum.
"Why Scrum Doesn't Work" Download

When alone Kivy is not enough

Everybody likes games, and almost everybody likes Python Development 🙂 One interesting tool to join these two things together is Kivy.

Few words about Kivy – Python framework

 It’s a cross-platform Python library that can be very useful in the rapid development of applications (not only games) that make use of innovative user interfaces, such as e.g. multi-touch apps.
Kivy’s execution speed is comparable to the native mobile alternative, Java for Android or Objective C for iOS. Moreover, Kivy has the huge advantage of being able to run on multiple platforms, just as HTML5 does; in which case, Kivy performs better because it doesn’t rely on a heavy browser, and many of its components are implemented in C using the Cython library in such a way that most of the graphics processing runs directly in the GPU [2].

A typical application written in Kivy consists of two files: one in Python (*.py, application logic) and the second in Kivy language (*.kv, design language specifically geared towards easy and scalable GUI design). Below example is a ‘Hello World’ in Kivy. First file:

# File name:
from import App  
from kivy.uix.button import Label

class HelloApp(App):  
    def build(self):
        return Label()

if __name__=="__main__":  

and the second:

 # File name: hello.kv
#:kivy 1.9.0

Awesome Pong Game tutorial learns basics of Kivy in an attractive way.

Portability in Kivy

Kivy applications are generally portable across all supported platforms – Mac, Windows, Linux, iOS, Android, and Raspberry Pi with no significant problems. Kivy strives to be as cross-platform as possible and delivers a similar user experience on every system it supports. This is a huge feature by itself; as a plus, one has the ability to write code once and run everywhere with little (or not at all) tweaks [1][2].
The downside of being cross-platform, however, is that one can only rely on the core functionalities supported by every system. This feature set includes i.a. rendering graphics on the screen, reproducing a sound if there is a sound card, accepting user input, and not too much else.
Each Kivy app, by the virtue of being written in Python, also has access to the vast Python standard library. It facilitates networking, supports a number of application protocols, and provides many general-purpose algorithms and utility functions.
Still, the input-output (I/O) capabilities of a “pure Kivy” programs are limited to those that are present on most platforms. This amounts to a tiny fraction of what a common computer system, such as a smartphone or a tablet PC, can actually do [1][2].
Features that are directly available in Python or Kivy:
• Hardware-accelerated graphics,
• Touch screen input with optional multi-touch,
• Sound playback,
• Networking [2].

Features that aren’t supported or require an external library:
• Modem, support for voice calls, and SMS,
• Use of built-in cameras (videos and taking pictures),
• Use of a built-in microphone to record sound,
• Cloud storage for application data, associated with a user account,
• Bluetooth,
• Location services and GPS,
• Fingerprinting and other biometric security,
• Motion sensors (accelerometer and gyroscope),
• Screen brightness control,
• Vibration and other forms of feedback,
• Battery charge level [2][3].

For many entries from the above list different Python libraries exist and they can handle many platform specific tasks, for example Pyjnius (accessing Java classes from Python), Audiostream (provides an easy-to-use API for streaming bytes to the speaker), Plyer (accessing features of your hardware) and others.
For example, using Plyer one can get information about battery (status and percentage of charging) and display it in a clear way:

from import App  
from kivy.uix.boxlayout import BoxLayout  
from kivy.uix.button import Button  
from kivy.lang import Builder  
from import StringProperty, ObjectProperty  
from plyer import battery

    lbl1: lbl1
    lbl2: lbl2
            size_hint_y: None
            pos_hint: {'y': .5}
            text: "Battery Status"
            on_press: root.get_status()
            size_hint_y: None
            pos_hint: {'y': .1}
                text: "Is Charging?"
                id: lbl1
                text: "Percentage"
                id: lbl2

class BatteryInterface(BoxLayout):  
    lbl1 = ObjectProperty()
    lbl2 = ObjectProperty()

    def get_status(self, *args):
        self.lbl1.text = str(battery.status['isCharging'])
        self.lbl2.text = str(battery.status['percentage']) + "%"

class BatteryApp(App):

    def build(self):
        return BatteryInterface()

if __name__ == "__main__":  
    app = BatteryApp()

It’s not like these aforementioned features are completely unavailable to application. The challenge is that these parts of functionality are fragmented across different platforms (or even consecutive versions of the same platform, for example, Android); thus, one ends up writing platform-specific, not portable code anyway [2].

Kivy + Android

A lot of functionalities are available on Android and it is only partially covered by an existing Python or Kivy API. It creates possibility to use platform-specific features in one’s application. Unlike pure Kivy, the underlying Android API certainly provides us with ways of recording sound programmatically [1][2].
And here comes the Pyjnius with help. This library allows for using Java classes directly from Python. It means that one can have full access to the native Android API and the official Android documentation, which is obviously more suited for Java development, not Python. Pyjnius allows also for using the official Python interpreter (CPython), together with a multitude of libraries such as NumPy, which facilitates very fast computations [2].

Using Java’s native API

Let’s assume that our task is to create an application that allows recording a sound. The most suitable Java classes for purposes of sound recording are MediaRecorder and MediaPlayer. Also adding Environment class would be convenient, cause it provides access to many useful environmental variables.
To load the aforementioned classes into Python application one can use code as follows:

from jnius import autoclass

Environment = autoclass('android.os.Environment')  
MediaRecorder = autoclass('')  
AudioSource = autoclass('$AudioSource')  
OutputFormat = autoclass('$OutputFormat')  
AudioEncoder = autoclass('$AudioEncoder')

Looks quite nice. The simple practical example below shows how to do one thing (figure out where SD card is mounted) in two ways:

//code in Java
import android.os.Environment;  
String path = Environment.getExternalStorageDirectory().getAbsolutePath();


# code in Python
Environment = autoclass('android.os.Environment')  
path = Environment.getExternalStorageDirectory().getAbsolutePath()

Original Java code aimed at recording sound with Android can be found here. To initialize MediaRecorder object one can use the code below:

storage_path = (Environment.getExternalStorageDirectory()  
               .getAbsolutePath() + '/kivy_recording.3gp')
recorder = MediaRecorder()

def init_recorder():  
    # set the audio source for microphone
    # 3GPP media file as a output format
    # Adaptive Multi-Rate with Narrow Band codec

And then our recorder object and init_recorder function could be used in application class, for example in this way [2]:

class RecorderApp(App):  
    is_recording = False
    def begin_end_recording(self):
        if (self.is_recording):

One of few available full examples of code (in Kivy) of the recording app could be found here.

Deploying to Android

Kivy has a custom-built deployment tool called Buildozer. Buildozer is a tool that aims to package mobiles application easily. It automates the entire build process, downloads the prerequisites like python-for-android, Android SDK, NDK, etc. Buildozer manage a file named buildozer.spec in your application directory, describing your application requirements and settings such as title, icon, included modules etc. It will use the specification file to create a package for Android, iOS, and more [1]. Buildozer provides the logcat command, which calls adb logcat under the hood (adb stands for Android Debug Bridge). One can run it with buildozer android logcat. This command provides all sorts of diagnostic information in the terminal. Most importantly, you can see any Python or Java tracebacks related to your program. One can also use python-for-android directly, which is described here [1][2].

The ability to immediately launch and test an application without compiling is an incredibly important aspect of Kivy development. The Kivy Launcher app, which one may find very useful to test his own programs, is available in the form of an .apk file from the official Kivy’s website this will be useful for emulated Android devices that don’t have access to Google Play.

The only prerequisite for testing operation is an Android device, physical or virtualized, with the Kivy Launcher application installed and working [2].

Software Engineers - development team


When one writes non-portable code it has strengths and weaknesses. This particular choice is difficult, because the switch to native API at the beginning of the project may be completely impractical to undo at a later stage.
With platform-specific code, one can do virtually anything that the platform is capable of. There are no artificial limits; our Python code has unrestricted access to the same underlying API as the native code. On the downside, depending on a single platform is risky because porting the program to a new system becomes harder with every platform-specific feature one can use.


  1. Philips D., “Creating Apps inn Kivy”, O’Reilly, 2014.
  2. Vasilkov M., “Kivy Blueprints”, Packt Publishing, 2015.
  3. Ulloa R., “Kivy – Interactive Applications and Games in Python, Second Edition”, Packt Publishing, 2015.

cto - Chris Gibas

Free 30-minute consultation with our CTO

Chris Gibas - our CTO will be happy to discuss your project! Let's talk!

More blog posts
What is app modernization, and when should you consider it?


What is app modernization, and when should you consider it?

Do you feel like your business applications are no longer enough for your organization? It may be the right time for you to consider app modernization. You can improve your business solutions performance and leverage the most popular technical innovations. From this article, you will learn what it means to modernize applications and when you should do it.   Some companies […]

Digital transformation in business – why do you need this for your company?

How can you make your company more efficient, reduce costs and improve the quality of your customer service? Have you ever heard about digital transformation in business? Move from paper documentation to digital systems, adopt new technologies and optimize your business processes to modernize your organization. You can increase profits and make everyday work easier. Read, to learn more.  How […]

Digital transformation in business – why do you need this for your company?


UX design for web applications: TOP 5 best practices


UX design for web applications: TOP 5 best practices

Which elements of UX design in the web application would you define as most important? What is the difference between a functional and a successful web app? These are only some of the questions that you should ask yourself before you start the development of your application. CEach web application has some goal (or goals) — selling products, entertaining or […]

Benefits of Artificial Intelligence in banking

The vital role of Artificial Intelligence in banking solutions development is undeniable. Why are ML and AI so important in this industry? Learn more about the current state of AI in banking and the benefits of using AI in banking software development. Check it out, if you are considering the application of AI in your business. Adopting AI-based solutions enables […]

Benefits of Artificial Intelligence in banking


Get a free estimation

Need a successful project?