Natwar Singh
Natwar Singh

Reputation: 2273

How to handle android runtime permission with kivy

I found that kivy is very nice framework to build cross platform application and I am very interested in kivy just to do android application as I think is easy and comfortable in kivy.

After trying few examples, I am interested to know how should handle android run time permission for the kivy app.

Actually I had searched on google, but no single working example out there. Should I go back to android / java or it possible with kivy and some other python libs.

Upvotes: 4

Views: 9120

Answers (3)

RVLTN72
RVLTN72

Reputation: 31

i know this answer is a little late, but to get permissions you have to specify them before the build. E.g buildozer uses a buildozer.spec. In this file you can specify the permissions you need.

Upvotes: 1

S. X. A
S. X. A

Reputation: 21

Hi this question is old but you can use

request_permissions([Permission.WRITE_EXTERNAL_STORAGE])
#For requesting permission you can pass a list with all the permissions you need

check_permission('android.permission.WRITE_EXTERNAL_STORAGE')
#returns True if you have the permission 

you can check: python-for-android example

you can check the code and the list of permission you can use with this method: python-for-android code

Upvotes: 2

Philipp Auersperg
Philipp Auersperg

Reputation: 41

pyjnius is the way to go. You have to port these instructions using pyjnius. This involves the following steps:

  • Unfortunately the api call to ContextCompat.checkSelfPermission is implemented in the android sdk support library which has to be downloaded seperately, so get the .aar with the version best matching your android API level for example here.
  • copy it into your project dir and reference it from your buildozer.spec:

    android.add_aars = support-v4-26.0.0-alpha1.aar  
    
  • make sure jinius is in the requirements in buildozer.spec

  • use the following code snippet

Note: this is a blocking function which waits until the permissions dialog is answered. If the app already has the permission the function returns immediately. So for example if you want to get the permissions for writing to the SD card and for the camera, which are both "dangerous permissions", call:

perms = ["android.permission.READ_EXTERNAL_STORAGE",
         "android.permission.WRITE_EXTERNAL_STORAGE",
         "android.permission.CAMERA"]

haveperms = acquire_permissions(perms)

And here the function for acquiring the permissions:

import time
import functools
import jnius

def acquire_permissions(permissions, timeout=30):
    """
    blocking function for acquiring storage permission

    :param permissions: list of permission strings , e.g. ["android.permission.READ_EXTERNAL_STORAGE",]
    :param timeout: timeout in seconds
    :return: True if all permissions are granted
    """

    PythonActivity = jnius.autoclass('org.kivy.android.PythonActivity')
    Compat = jnius.autoclass('android.support.v4.content.ContextCompat')
    currentActivity = jnius.cast('android.app.Activity', PythonActivity.mActivity)

    checkperm = functools.partial(Compat.checkSelfPermission, currentActivity)

    def allgranted(permissions):
        """
        helper function checks permissions
        :param permissions: list of permission strings
        :return: True if all permissions are granted otherwise False
        """
        return reduce(lambda a, b: a and b,
                    [True if p == 0 else False for p in map(checkperm, permissions)]
                    )

    haveperms = allgranted(permissions)
    if haveperms:
        # we have the permission and are ready
        return True

    # invoke the permissions dialog
    currentActivity.requestPermissions(permissions, 0)

    # now poll for the permission (UGLY but we cant use android Activity's onRequestPermissionsResult)
    t0 = time.time()
    while time.time() - t0 < timeout and not haveperms:
        # in the poll loop we could add a short sleep for performance issues?
        haveperms = allgranted(permissions)

    return haveperms

Probably the cleanest way would be to pimp p4a's PythonActivity.java to do that but this one does it for me for now.

Upvotes: 4

Related Questions