diff --git a/android/modules/android/src/java/ti/modules/titanium/android/AndroidModule.java b/android/modules/android/src/java/ti/modules/titanium/android/AndroidModule.java index 646dcdb69fd..77513809bc5 100644 --- a/android/modules/android/src/java/ti/modules/titanium/android/AndroidModule.java +++ b/android/modules/android/src/java/ti/modules/titanium/android/AndroidModule.java @@ -17,6 +17,8 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollFunction; import org.appcelerator.kroll.KrollModule; +import org.appcelerator.kroll.KrollObject; +import org.appcelerator.kroll.KrollPromise; import org.appcelerator.kroll.KrollRuntime; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.Log; @@ -684,40 +686,48 @@ public boolean hasPermission(Object permissionObject) } @Kroll.method - public void requestPermissions(Object permissionObject, - @Kroll.argument(optional = true) KrollFunction permissionCallback) + public KrollPromise requestPermissions(final Object permissionObject, + @Kroll.argument(optional = true) final KrollFunction permissionCallback) { - if (Build.VERSION.SDK_INT >= 23) { - ArrayList permissions = new ArrayList(); - if (permissionObject instanceof String) { - permissions.add((String) permissionObject); - } else if (permissionObject instanceof Object[]) { - for (Object permission : (Object[]) permissionObject) { - if (permission instanceof String) { - permissions.add((String) permission); + // TODO: Create a subclass of Promise that takes in KrollFunction callback and "this" KrollObject + // to fire the callback when we resolve/reject? + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + if (Build.VERSION.SDK_INT >= 23) { + List permissions = new ArrayList(); + if (permissionObject instanceof String) { + permissions.add((String) permissionObject); + } else if (permissionObject instanceof Object[]) { + for (Object permission : (Object[]) permissionObject) { + if (permission instanceof String) { + permissions.add((String) permission); + } } } - } - Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); - ArrayList filteredPermissions = new ArrayList(); - for (String permission : permissions) { - if (currentActivity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { - continue; + Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); + List filteredPermissions = new ArrayList(); + for (String permission : permissions) { + if (currentActivity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { + continue; + } + filteredPermissions.add(permission); + } + if (filteredPermissions.size() > 0) { + TiBaseActivity.registerPermissionRequestCallback(REQUEST_CODE, permissionCallback, + callbackThisObject, promise); + currentActivity.requestPermissions(filteredPermissions.toArray( + new String[filteredPermissions.size()]), REQUEST_CODE); + return; } - filteredPermissions.add(permission); } - if (filteredPermissions.size() > 0) { - TiBaseActivity.registerPermissionRequestCallback(REQUEST_CODE, permissionCallback, getKrollObject()); - currentActivity.requestPermissions(filteredPermissions.toArray(new String[filteredPermissions.size()]), - REQUEST_CODE); - return; + // FIXME: If we're not on API level 23+, shouldn't we reject/error? + KrollDict response = new KrollDict(); + response.putCodeAndMessage(0, null); + if (permissionCallback != null) { + permissionCallback.callAsync(callbackThisObject, response); } - } - KrollDict response = new KrollDict(); - response.putCodeAndMessage(0, null); - if (permissionCallback != null) { - permissionCallback.callAsync(getKrollObject(), response); - } + promise.resolve(response); + }); } @Kroll.method diff --git a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarModule.java b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarModule.java index 8582fac3523..22800f6e14c 100644 --- a/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarModule.java +++ b/android/modules/calendar/src/java/ti/modules/titanium/calendar/CalendarModule.java @@ -14,6 +14,8 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollFunction; import org.appcelerator.kroll.KrollModule; +import org.appcelerator.kroll.KrollObject; +import org.appcelerator.kroll.KrollPromise; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.titanium.TiApplication; import org.appcelerator.titanium.TiBaseActivity; @@ -126,21 +128,26 @@ public boolean hasCalendarPermissions() } @Kroll.method - public void requestCalendarPermissions(@Kroll.argument(optional = true) KrollFunction permissionCallback) + public KrollPromise requestCalendarPermissions( + @Kroll.argument(optional = true) final KrollFunction permissionCallback) { - if (hasCalendarPermissions()) { - KrollDict response = new KrollDict(); - response.putCodeAndMessage(0, null); - permissionCallback.callAsync(getKrollObject(), response); - return; - } - - TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_CALENDAR, permissionCallback, - getKrollObject()); - Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); - currentActivity.requestPermissions( - new String[] { Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR }, - TiC.PERMISSION_CODE_CALENDAR); + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + if (hasCalendarPermissions()) { + KrollDict response = new KrollDict(); + response.putCodeAndMessage(0, null); + permissionCallback.callAsync(callbackThisObject, response); + promise.resolve(response); + return; + } + + TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_CALENDAR, permissionCallback, + callbackThisObject, promise); + Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); + currentActivity.requestPermissions( + new String[] { Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR }, + TiC.PERMISSION_CODE_CALENDAR); + }); } @Kroll.method diff --git a/android/modules/contacts/src/java/ti/modules/titanium/contacts/ContactsModule.java b/android/modules/contacts/src/java/ti/modules/titanium/contacts/ContactsModule.java index c31226daad8..49fd7be3cbd 100644 --- a/android/modules/contacts/src/java/ti/modules/titanium/contacts/ContactsModule.java +++ b/android/modules/contacts/src/java/ti/modules/titanium/contacts/ContactsModule.java @@ -14,6 +14,8 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollFunction; import org.appcelerator.kroll.KrollModule; +import org.appcelerator.kroll.KrollObject; +import org.appcelerator.kroll.KrollPromise; import org.appcelerator.kroll.KrollProxy; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.Log; @@ -76,21 +78,26 @@ public boolean hasContactsPermissions() } @Kroll.method - public void requestContactsPermissions(@Kroll.argument(optional = true) KrollFunction permissionCallback) + public KrollPromise requestContactsPermissions( + @Kroll.argument(optional = true) final KrollFunction permissionCallback) { - if (hasContactsPermissions()) { - KrollDict response = new KrollDict(); - response.putCodeAndMessage(0, null); - permissionCallback.callAsync(getKrollObject(), response); - return; - } + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + if (hasContactsPermissions()) { + KrollDict response = new KrollDict(); + response.putCodeAndMessage(0, null); + permissionCallback.callAsync(callbackThisObject, response); + promise.resolve(response); + return; + } - TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_CONTACTS, permissionCallback, - getKrollObject()); - Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); - currentActivity.requestPermissions( - new String[] { Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS }, - TiC.PERMISSION_CODE_CONTACTS); + TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_CONTACTS, permissionCallback, + callbackThisObject, promise); + Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); + currentActivity.requestPermissions( + new String[] { Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS }, + TiC.PERMISSION_CODE_CONTACTS); + }); } @Kroll.method diff --git a/android/modules/filesystem/src/java/ti/modules/titanium/filesystem/FilesystemModule.java b/android/modules/filesystem/src/java/ti/modules/titanium/filesystem/FilesystemModule.java index 2c9e87a123a..83526d6b258 100644 --- a/android/modules/filesystem/src/java/ti/modules/titanium/filesystem/FilesystemModule.java +++ b/android/modules/filesystem/src/java/ti/modules/titanium/filesystem/FilesystemModule.java @@ -18,6 +18,8 @@ import org.appcelerator.kroll.KrollFunction; import org.appcelerator.kroll.KrollInvocation; import org.appcelerator.kroll.KrollModule; +import org.appcelerator.kroll.KrollObject; +import org.appcelerator.kroll.KrollPromise; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.Log; import org.appcelerator.titanium.io.TiFileFactory; @@ -113,23 +115,28 @@ private boolean hasStoragePermissions() } @Kroll.method - public void requestStoragePermissions(@Kroll.argument(optional = true) KrollFunction permissionCallback) + public KrollPromise requestStoragePermissions( + @Kroll.argument(optional = true) final KrollFunction permissionCallback) { - if (hasStoragePermissions()) { - KrollDict response = new KrollDict(); - response.putCodeAndMessage(0, null); - permissionCallback.callAsync(getKrollObject(), response); - return; - } + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + if (hasStoragePermissions()) { + KrollDict response = new KrollDict(); + response.putCodeAndMessage(0, null); + permissionCallback.callAsync(callbackThisObject, response); + promise.resolve(response); + return; + } - String[] permissions = new String[] { - android.Manifest.permission.READ_EXTERNAL_STORAGE, - android.Manifest.permission.WRITE_EXTERNAL_STORAGE - }; - Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); - TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_EXTERNAL_STORAGE, permissionCallback, - getKrollObject()); - currentActivity.requestPermissions(permissions, TiC.PERMISSION_CODE_EXTERNAL_STORAGE); + String[] permissions = new String[] { + android.Manifest.permission.READ_EXTERNAL_STORAGE, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); + TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_EXTERNAL_STORAGE, + permissionCallback, callbackThisObject, promise); + currentActivity.requestPermissions(permissions, TiC.PERMISSION_CODE_EXTERNAL_STORAGE); + }); } @Kroll.method diff --git a/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java b/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java index b3c888fc2a3..2d02e349e95 100644 --- a/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java +++ b/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java @@ -13,6 +13,8 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollFunction; import org.appcelerator.kroll.KrollModule; +import org.appcelerator.kroll.KrollObject; +import org.appcelerator.kroll.KrollPromise; import org.appcelerator.kroll.KrollProxy; import org.appcelerator.kroll.KrollRuntime; import org.appcelerator.kroll.annotations.Kroll; @@ -508,28 +510,35 @@ public boolean hasLocationPermissions() @SuppressLint("NewApi") @Kroll.method - public void requestLocationPermissions(@Kroll.argument(optional = true) Object type, - @Kroll.argument(optional = true) KrollFunction permissionCallback) - { - KrollFunction permissionCB; - if (type instanceof KrollFunction && permissionCallback == null) { - permissionCB = (KrollFunction) type; - } else { - permissionCB = permissionCallback; - } + public KrollPromise requestLocationPermissions(@Kroll.argument(optional = true) final Object type, + @Kroll.argument(optional = true) final KrollFunction permissionCallback) + { + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + KrollFunction permissionCB; + if (type instanceof KrollFunction && permissionCallback == null) { + permissionCB = (KrollFunction) type; + } else { + permissionCB = permissionCallback; + } - // already have permissions, fall through - if (hasLocationPermissions()) { - KrollDict response = new KrollDict(); - response.putCodeAndMessage(0, null); - permissionCB.callAsync(getKrollObject(), response); - return; - } + // already have permissions, fall through + if (hasLocationPermissions()) { + KrollDict response = new KrollDict(); + response.putCodeAndMessage(0, null); + if (permissionCB != null) { + permissionCB.callAsync(callbackThisObject, response); + } + promise.resolve(response); + return; + } - TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_LOCATION, permissionCB, getKrollObject()); - Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); - currentActivity.requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, - TiC.PERMISSION_CODE_LOCATION); + TiBaseActivity.registerPermissionRequestCallback(TiC.PERMISSION_CODE_LOCATION, permissionCB, + callbackThisObject, promise); + Activity currentActivity = TiApplication.getInstance().getCurrentActivity(); + currentActivity.requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, + TiC.PERMISSION_CODE_LOCATION); + }); } /** @@ -710,9 +719,12 @@ public void getCurrentPosition(KrollFunction callback) * for the specified address if available */ @Kroll.method - public void forwardGeocoder(String address, KrollFunction callback) + public KrollPromise forwardGeocoder(final String address, + @Kroll.argument(optional = true) final KrollFunction callback) { - tiLocation.forwardGeocode(address, createGeocodeResponseHandler(callback)); + return KrollPromise.create((promise) -> { + tiLocation.forwardGeocode(address, createGeocodeResponseHandler(callback, promise)); + }); } /** @@ -725,9 +737,12 @@ public void forwardGeocoder(String address, KrollFunction callback) * for the specified latitude and longitude if available */ @Kroll.method - public void reverseGeocoder(double latitude, double longitude, KrollFunction callback) + public KrollPromise reverseGeocoder(double latitude, double longitude, + @Kroll.argument(optional = true) final KrollFunction callback) { - tiLocation.reverseGeocode(latitude, longitude, createGeocodeResponseHandler(callback)); + return KrollPromise.create((promise) -> { + tiLocation.reverseGeocode(latitude, longitude, createGeocodeResponseHandler(callback, promise)); + }); } /** @@ -738,7 +753,8 @@ public void reverseGeocoder(double latitude, double longitude, KrollFunction cal * once the geocode response is ready * @return the geocode response handler */ - private GeocodeResponseHandler createGeocodeResponseHandler(final KrollFunction callback) + private GeocodeResponseHandler createGeocodeResponseHandler(final KrollFunction callback, + final KrollPromise promise) { final GeolocationModule geolocationModule = this; @@ -747,6 +763,10 @@ private GeocodeResponseHandler createGeocodeResponseHandler(final KrollFunction public void handleGeocodeResponse(KrollDict geocodeResponse) { geocodeResponse.put(TiC.EVENT_PROPERTY_SOURCE, geolocationModule); + promise.resolve(geocodeResponse); + if (callback == null) { + return; + } callback.call(getKrollObject(), new Object[] { geocodeResponse }); } }; diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index 7ab67061c67..76f54803606 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -19,6 +19,8 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollFunction; import org.appcelerator.kroll.KrollModule; +import org.appcelerator.kroll.KrollObject; +import org.appcelerator.kroll.KrollPromise; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.Log; import org.appcelerator.titanium.ContextSpecific; @@ -532,103 +534,121 @@ public void showCamera(@SuppressWarnings("rawtypes") HashMap options) } @Kroll.method - public void requestCameraPermissions(@Kroll.argument(optional = true) KrollFunction permissionCallback) + public KrollPromise requestCameraPermissions( + @Kroll.argument(optional = true) KrollFunction permissionCallback) { - // Do not continue if we already have permission. - if (hasCameraPermissions()) { - if (permissionCallback != null) { + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + // Do not continue if we already have permission. + if (hasCameraPermissions()) { KrollDict response = new KrollDict(); response.putCodeAndMessage(0, null); - permissionCallback.callAsync(getKrollObject(), response); + if (permissionCallback != null) { + permissionCallback.callAsync(callbackThisObject, response); + } + promise.resolve(response); + return; } - return; - } - // Do not continue if there is no activity to host the request dialog. - Activity activity = TiApplication.getInstance().getCurrentActivity(); - if (activity == null) { - if (permissionCallback != null) { + // Do not continue if there is no activity to host the request dialog. + Activity activity = TiApplication.getInstance().getCurrentActivity(); + if (activity == null) { KrollDict response = new KrollDict(); response.putCodeAndMessage(-1, "There are no activities to host the camera request dialog."); - permissionCallback.callAsync(getKrollObject(), response); + if (permissionCallback != null) { + permissionCallback.callAsync(callbackThisObject, response); + } + promise.reject(response); + return; } - return; - } - // Create the permission list. On Android 10+, we don't need external storage permission anymore. - ArrayList permissionList = new ArrayList<>(); - permissionList.add(Manifest.permission.CAMERA); - if (Build.VERSION.SDK_INT < 29) { - permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } + // Create the permission list. On Android 10+, we don't need external storage permission anymore. + ArrayList permissionList = new ArrayList<>(); + permissionList.add(Manifest.permission.CAMERA); + if (Build.VERSION.SDK_INT < 29) { + permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); + } - // Show dialog requesting permission. - TiBaseActivity.registerPermissionRequestCallback( - TiC.PERMISSION_CODE_CAMERA, permissionCallback, getKrollObject()); - activity.requestPermissions(permissionList.toArray(new String[0]), TiC.PERMISSION_CODE_CAMERA); + // Show dialog requesting permission. + TiBaseActivity.registerPermissionRequestCallback( + TiC.PERMISSION_CODE_CAMERA, permissionCallback, callbackThisObject, promise); + activity.requestPermissions(permissionList.toArray(new String[0]), TiC.PERMISSION_CODE_CAMERA); + }); } @Kroll.method - public void requestAudioRecorderPermissions(@Kroll.argument(optional = true) KrollFunction permissionCallback) + public KrollPromise requestAudioRecorderPermissions( + @Kroll.argument(optional = true) final KrollFunction permissionCallback) { - // Do not continue if we already have permission. - if (hasAudioRecorderPermissions()) { - if (permissionCallback != null) { + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + // Do not continue if we already have permission. + if (hasAudioRecorderPermissions()) { KrollDict response = new KrollDict(); response.putCodeAndMessage(0, null); - permissionCallback.callAsync(getKrollObject(), response); + if (permissionCallback != null) { + permissionCallback.callAsync(callbackThisObject, response); + } + promise.resolve(response); + return; } - return; - } - // Do not continue if there is no activity to host the request dialog. - Activity activity = TiApplication.getInstance().getCurrentActivity(); - if (activity == null) { - if (permissionCallback != null) { + // Do not continue if there is no activity to host the request dialog. + Activity activity = TiApplication.getInstance().getCurrentActivity(); + if (activity == null) { KrollDict response = new KrollDict(); response.putCodeAndMessage(-1, "There are no activities to host the camera request dialog."); - permissionCallback.callAsync(getKrollObject(), response); + if (permissionCallback != null) { + permissionCallback.callAsync(callbackThisObject, response); + } + promise.reject(response); + return; } - return; - } - // Show dialog requesting permission. - TiBaseActivity.registerPermissionRequestCallback( - TiC.PERMISSION_CODE_MICROPHONE, permissionCallback, getKrollObject()); - activity.requestPermissions( - new String[] { Manifest.permission.RECORD_AUDIO }, TiC.PERMISSION_CODE_MICROPHONE); + // Show dialog requesting permission. + TiBaseActivity.registerPermissionRequestCallback( + TiC.PERMISSION_CODE_MICROPHONE, permissionCallback, callbackThisObject, promise); + activity.requestPermissions( + new String[] { Manifest.permission.RECORD_AUDIO }, TiC.PERMISSION_CODE_MICROPHONE); + }); } @Kroll.method - public void requestPhotoGalleryPermissions(@Kroll.argument(optional = true) KrollFunction permissionCallback) + public KrollPromise requestPhotoGalleryPermissions( + @Kroll.argument(optional = true) KrollFunction permissionCallback) { - // Do not continue if we already have permission. - if (hasPhotoGalleryPermissions()) { - if (permissionCallback != null) { + final KrollObject callbackThisObject = getKrollObject(); + return KrollPromise.create((promise) -> { + // Do not continue if we already have permission. + if (hasPhotoGalleryPermissions()) { KrollDict response = new KrollDict(); response.putCodeAndMessage(0, null); - permissionCallback.callAsync(getKrollObject(), response); + if (permissionCallback != null) { + permissionCallback.callAsync(callbackThisObject, response); + } + promise.resolve(response); + return; } - return; - } - // Do not continue if there is no activity to host the request dialog. - Activity activity = TiApplication.getInstance().getCurrentActivity(); - if (activity == null) { - if (permissionCallback != null) { + // Do not continue if there is no activity to host the request dialog. + Activity activity = TiApplication.getInstance().getCurrentActivity(); + if (activity == null) { KrollDict response = new KrollDict(); response.putCodeAndMessage( -1, "There are no activities to host the external storage permission request dialog."); - permissionCallback.callAsync(getKrollObject(), response); + if (permissionCallback != null) { + permissionCallback.callAsync(callbackThisObject, response); + } + promise.reject(response); + return; } - return; - } - // Show dialog requesting permission. - TiBaseActivity.registerPermissionRequestCallback( - TiC.PERMISSION_CODE_EXTERNAL_STORAGE, permissionCallback, getKrollObject()); - activity.requestPermissions( - new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, TiC.PERMISSION_CODE_EXTERNAL_STORAGE); + // Show dialog requesting permission. + TiBaseActivity.registerPermissionRequestCallback( + TiC.PERMISSION_CODE_EXTERNAL_STORAGE, permissionCallback, callbackThisObject, promise); + activity.requestPermissions( + new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, TiC.PERMISSION_CODE_EXTERNAL_STORAGE); + }); } @SuppressWarnings({ "unchecked", "rawtypes" }) diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java index 7acac9f2dca..3d6d62279e0 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java +++ b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java @@ -14,6 +14,7 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollFunction; import org.appcelerator.kroll.KrollObject; +import org.appcelerator.kroll.KrollPromise; import org.appcelerator.kroll.KrollProxy; import org.appcelerator.kroll.KrollRuntime; import org.appcelerator.kroll.common.Log; @@ -430,6 +431,24 @@ public static void registerPermissionRequestCallback( */ public static void registerPermissionRequestCallback( Integer requestCode, final KrollFunction callback, final KrollObject context) + { + TiBaseActivity.registerPermissionRequestCallback(requestCode, callback, context, null); + } + + /** + * Registers a global KrollCallback to be invoked when onRequestPermissionsResult() is called for the given + * request code. Indicates if permissions were granted from a requestPermissions() method call. + *

+ * The registered callback can be removed via the TiBaseActivity.unregisterPermissionRequestCallback() method. + * @param requestCode Unique 8-bit integer ID to be used by the requestPermissions() method. + * @param callback + * Callback to be invoked with KrollDict properties "success", "code", and an optional "message". Can be null. + * @param context KrollObject providing the JavaScript context needed to invoke a JS callback. + * @param promise Promise to be invoked. Can be null. + */ + public static void registerPermissionRequestCallback( + Integer requestCode, final KrollFunction callback, final KrollObject context, + final KrollPromise promise) { if (requestCode == null) { return; @@ -441,7 +460,7 @@ public void onRequestPermissionsResult( @NonNull TiBaseActivity activity, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (callback == null) { + if (callback == null && promise == null) { return; } @@ -465,7 +484,16 @@ public void onRequestPermissionsResult( if (context == null) { Log.w(TAG, "Permission callback context object is null"); } - callback.callAsync(context, response); + if (callback != null) { + callback.callAsync(context, response); + } + if (promise != null) { + if (deniedPermissions.isEmpty()) { + promise.resolve(response); + } else { + promise.reject(response); + } + } } }); }