Posts tagged development
Technology at mSale - Tips & Tricks part 2 - Kivy Runtime Permissions on Android

Target reader: Intermediate Kivy and Python users

After hanging out in the Kivy discord server for a while (I recommend everyone interested in Kivy join up here!) I noticed there was a distinct problem showing up multiple times, that did not have a clear cut solution for people that were experienced with the framework - but not necessarily with the inner workings of the Android operating system.
In older API versions, you simply had to request whatever permissions you needed up front in the manifest (or buildozer.spec in our case) - and that would be good enough. Nowadays, however - we are required to request them during runtime - and the user can actively select at their own leasure if they approve of them or not. It is also bad form to have our app crash or close if the permission is not granted, so as developers we should handle this in a better way.

The required tools for this can be achieved through the use of Pyjnius - a kivy tool to interface through the JNI - granting us access to everything we would normally have access through natively. Pyjnius is incredibly powerful, and I will come back to it in a later post detailing how to use it with third party libraries - but for now, we will only focus on mostly accessing already existing android api’s.

The completed example app can be found here

First off, we need to declare the permissions we want to use in buildozer.spec as normal - for our example we will be using ACCESS_FINE_LOCATION. The reason for this being that android classifies certain permissions as Dangerous Permissions - and only those are the ones that need to be granted at runtime by the user. Other permissions, such as VIBRATE, are granted upon install as many old timers are used to.

Second, we need to grab a certain external support library - granting us access to ContextCompat - which we will use to check the status of permissions. Here, it is important to grab a package that corresponds to your targeted API - the default currently being 27. You can grab the .aar file from Maven, a sort of repository for artifacts in the Java world (consider it a sort of pypi).
We then declare the file in our buildozer.spec, under the android.add_aars property.

Finally - we need the code to tie this all together. Ultimately this is a pretty simple snippet - but there is a lot going on here that one might not normally get exposed through while only doing Kivy apps. Normally, one would not dive too deep into the various native API’s and such - and only the basic non-dangerous permissions are used.

The completed snippet is as follows:

from jnius import autoclass
from kivy.logger import Logger

PythonActivity = autoclass("").mActivity
Context = autoclass('android.content.Context')
ContextCompat = autoclass('')

def check_permission(permission, activity=PythonActivity):
    permission_status = ContextCompat.checkSelfPermission(activity,
    permission_granted = 0 == permission_status"Permission Status: {}".format(permission_granted))
    return permission_granted

def ask_permission(permission, activity=PythonActivity):

Simply put - this grants us two methods we can use throughout our Kivy apps to confirm the existence of permissions - and also grant them.

The simple order here would be to check if we have the permission, in this case “android.permission.ACCESS_FINE_LOCATION”, confirm wether or not we have it, if the check returns False - we request it, and recheck aftewards if the user granted us the permission we needed. Repeat as needed throughout your app until you get what you require.

I hope this simple blog post will help some people out there in the Kivy world with something that might be a small headache for people getting into mobile development - and an inspiration to continue testing out various other native API’s in collaboration with Kivy.

I have been Kjetil A. Liknes
Thank you for reading.