pyjnius 是正确的选择。你必须移植这些说明使用 pyjnius。这涉及以下步骤:
- 不幸的是,对 ContextCompat.checkSelfPermission 的 api 调用是在 android sdk 支持库中实现的,必须单独下载,
因此,获取与您的 Android API 级别最匹配的版本的 .aar例如这里.
-
将其复制到您的项目目录中并从 buildozer.spec 中引用它:
android.add_aars = support-v4-26.0.0-alpha1.aar
确保 jinius 符合 buildozer.spec 中的要求
使用以下代码片段
注意:这是一个阻塞函数,它会等待权限对话框得到答复。如果应用程序已经拥有权限,该函数会立即返回。例如,如果您想获得写入 SD 卡和相机的权限,这两者都是“危险权限”,请调用:
perms = ["android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.CAMERA"]
haveperms = acquire_permissions(perms)
这里是获取权限的函数:
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
也许最干净的方法是通过 p4a 的 PythonActivity.java 来做到这一点,但现在这个方法已经为我做到了。