Skip to content

Commit bc608d6

Browse files
committed
feat: Allows registering the onRequestPermissionsResult callback.
Adds an interface in PythonActivity and a method to register a Python function which will be called when the onRequestPermissionsResult callback is received. In android/permissions.py, a new function 'register_permissions_callback' is added to register a Python function (that takes three arguments) which will receive the three arguments of onRequestPermissionsResult.
1 parent e4cecb1 commit bc608d6

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonActivity.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,34 @@ public void onWindowFocusChanged(boolean hasFocus) {
581581
// call native function (since it's not yet loaded)
582582
}
583583
considerLoadingScreenRemoval();
584-
}
584+
}
585+
586+
/**
587+
* Used by android.permissions p4a module to register a call back after
588+
* requesting runtime permissions
589+
**/
590+
public interface PermissionsCallback {
591+
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
592+
}
593+
594+
private PermissionsCallback permissionCallback;
595+
private boolean havePermissionsCallback = false;
596+
597+
public void addPermissionsCallback(PermissionsCallback callback) {
598+
permissionCallback = callback;
599+
havePermissionsCallback = true;
600+
Log.v(TAG, "addPermissionsCallback(): Added callback for onRequestPermissionsResult");
601+
}
602+
603+
@Override
604+
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
605+
Log.v(TAG, "onRequestPermissionsResult()");
606+
if (havePermissionsCallback) {
607+
Log.v(TAG, "onRequestPermissionsResult passed to callback");
608+
permissionCallback.onRequestPermissionsResult(requestCode, permissions, grantResults);
609+
}
610+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
611+
}
585612

586613
/**
587614
* Used by android.permissions p4a module to check a permission
@@ -592,9 +619,9 @@ public boolean checkCurrentPermission(String permission) {
592619

593620
try {
594621
java.lang.reflect.Method methodCheckPermission =
595-
Activity.class.getMethod("checkSelfPermission", java.lang.String.class);
622+
Activity.class.getMethod("checkSelfPermission", java.lang.String.class);
596623
Object resultObj = methodCheckPermission.invoke(this, permission);
597-
int result = Integer.parseInt(resultObj.toString());
624+
int result = Integer.parseInt(resultObj.toString());
598625
if (result == PackageManager.PERMISSION_GRANTED)
599626
return true;
600627
} catch (IllegalAccessException | NoSuchMethodException |
@@ -612,7 +639,7 @@ public void requestPermissions(String[] permissions) {
612639
try {
613640
java.lang.reflect.Method methodRequestPermission =
614641
Activity.class.getMethod("requestPermissions",
615-
java.lang.String[].class, int.class);
642+
java.lang.String[].class, int.class);
616643
methodRequestPermission.invoke(this, permissions, 1);
617644
} catch (IllegalAccessException | NoSuchMethodException |
618645
InvocationTargetException e) {

pythonforandroid/recipes/android/src/android/permissions.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
try:
3-
from jnius import autoclass
3+
from jnius import autoclass, PythonJavaClass, java_method
44
except ImportError:
55
# To allow importing by build/manifest-creating code without
66
# pyjnius being present:
@@ -421,6 +421,41 @@ class Permission:
421421
)
422422

423423

424+
class onRequestPermissionsCallback(PythonJavaClass):
425+
"""Callback class for registering a Python callback from
426+
onRequestPermissionsResult in PythonActivity.
427+
"""
428+
__javainterfaces__ = ['org.kivy.android.PythonActivity$PermissionsCallback']
429+
__javacontext__ = 'app'
430+
_callback = None # To avoid garbage collection
431+
432+
def __init__(self, func):
433+
self.func = func
434+
onRequestPermissionsCallback._callback = self
435+
super().__init__()
436+
437+
@java_method('(I[Ljava/lang/String;[I)V')
438+
def onRequestPermissionsResult(self, requestCode, permissions, grantResults):
439+
self.func(requestCode, permissions, grantResults)
440+
441+
442+
def register_permissions_callback(callback):
443+
"""Register a callback. This will asynchronously receive arguments from
444+
onRequestPermissionsResult on PythonActivity after request_permission(s)
445+
is called.
446+
447+
The callback must accept three arguments: requestCode, permissions and
448+
grantResults.
449+
450+
Note that calling request_permission on SDK_INT < 23 will return
451+
immediately (as run-time permissions are not required), and so this
452+
callback will never happen.
453+
"""
454+
java_callback = onRequestPermissionsCallback(callback)
455+
python_activity = autoclass('org.kivy.android.PythonActivity')
456+
python_activity.addPermissionsCallback(java_callback)
457+
458+
424459
def request_permissions(permissions):
425460
python_activity = autoclass('org.kivy.android.PythonActivity')
426461
python_activity.requestPermissions(permissions)

0 commit comments

Comments
 (0)