diff --git a/android/build.gradle b/android/build.gradle index a81f712..569625a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -51,4 +51,5 @@ dependencies { androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" implementation 'androidx.core:core:1.2.0' implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'com.android.support:appcompat-v7:28.0.0' } diff --git a/android/src/main/java/com/capacitor/permissions/AppPermissionsPlugin.java b/android/src/main/java/com/capacitor/permissions/AppPermissionsPlugin.java index 7296ca8..a4ea5f2 100644 --- a/android/src/main/java/com/capacitor/permissions/AppPermissionsPlugin.java +++ b/android/src/main/java/com/capacitor/permissions/AppPermissionsPlugin.java @@ -6,34 +6,86 @@ import com.getcapacitor.PluginCall; import com.getcapacitor.PluginMethod; + import android.Manifest; import android.content.pm.PackageManager; +import android.os.Build; -import androidx.core.app.ActivityCompat; +import androidx.annotation.RequiresApi; import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; -@NativePlugin() +@NativePlugin(requestCodes = {AppPermissionsPlugin.REQUEST_CAMERA, AppPermissionsPlugin.REQUEST_COARSE_LOCATION, + AppPermissionsPlugin.REQUEST_READ_EXTERNAL_STORAGE, AppPermissionsPlugin.REQUEST_WRITE_EXTERNAL_STORAGE, + AppPermissionsPlugin.REQUEST_NOTIFICATION_POLICY}) public class AppPermissionsPlugin extends Plugin { + static final int REQUEST_CAMERA = 20120; + static final int REQUEST_READ_EXTERNAL_STORAGE = 20130; + static final int REQUEST_WRITE_EXTERNAL_STORAGE = 20140; + static final int REQUEST_COARSE_LOCATION = 20150; + static final int REQUEST_NOTIFICATION_POLICY = 20160; + + + @RequiresApi(api = Build.VERSION_CODES.M) @PluginMethod - public void request(PluginCall call){ - JSObject ret = new JSObject(); + public void request(PluginCall call) { + String name = call.getString("permission"); + saveCall(call); + switch (name) { + case "camera": + requestPermissions(Manifest.permission.CAMERA, REQUEST_CAMERA); + break; + case "photos": + requestPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, REQUEST_READ_EXTERNAL_STORAGE); + break; + case "geolocation": + requestPermissions(Manifest.permission.ACCESS_COARSE_LOCATION, REQUEST_COARSE_LOCATION); + break; + case "notifications": + requestPermissions(Manifest.permission.ACCESS_NOTIFICATION_POLICY, REQUEST_NOTIFICATION_POLICY); + break; + case "file-write": + requestPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_WRITE_EXTERNAL_STORAGE); + break; + default: + call.reject("Unknown permission type"); + } + + } - if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + private void requestPermissions(String permission, int permissionConstant) { + pluginRequestPermission(permission, permissionConstant); + } + + @Override + protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + super.handleRequestPermissionsResult(requestCode, permissions, grantResults); + JSObject ret = new JSObject(); + PluginCall savedCall = getSavedCall(); - ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); - ret.put("state", "GRANTED"); + if (savedCall == null) { + return; } - else - { - ret.put("state", "ALREADY GRANTED"); + + for (int result : grantResults) { + if (result == PackageManager.PERMISSION_DENIED) { + ret.put("state", "denied"); + savedCall.resolve(ret); + return; + } } - call.resolve(ret); + if (requestCode == REQUEST_CAMERA || requestCode == REQUEST_COARSE_LOCATION || requestCode == REQUEST_READ_EXTERNAL_STORAGE || + requestCode == REQUEST_NOTIFICATION_POLICY || requestCode == REQUEST_WRITE_EXTERNAL_STORAGE) { + // We got the permission + ret.put("state", "granted"); + savedCall.resolve(ret); + } } + @PluginMethod public void query(PluginCall call) { String name = call.getString("name"); @@ -51,10 +103,6 @@ public void query(PluginCall call) { case "notifications": checkNotifications(call); break; - case "clipboard-read": - case "clipboard-write": - checkClipboard(call); - break; case "file-write": checkFileWrite(call); break; @@ -75,7 +123,7 @@ private void checkPerm(String perm, PluginCall call) { call.resolve(ret); } - private void checkFileWrite(PluginCall call){ + private void checkFileWrite(PluginCall call) { checkPerm(Manifest.permission.WRITE_EXTERNAL_STORAGE, call); } @@ -98,9 +146,4 @@ private void checkNotifications(PluginCall call) { call.resolve(ret); } - private void checkClipboard(PluginCall call) { - JSObject ret = new JSObject(); - ret.put("state", "granted"); - call.resolve(ret); - } } diff --git a/ios/Plugin/Plugin.swift b/ios/Plugin/Plugin.swift index c78575e..2d309ea 100644 --- a/ios/Plugin/Plugin.swift +++ b/ios/Plugin/Plugin.swift @@ -21,17 +21,17 @@ public class AppPermissionsPlugin: CAPPlugin { case "LOCATION_ALWAYS": locationManager.requestAlwaysAuthorization(); break; - case "PHOTO_LIBRARY": + case "photos": PHPhotoLibrary.requestAuthorization { (PHAuthorizationStatus) in switch (PHAuthorizationStatus) { case .authorized: - status = "PHOTO_LIBRARY/AUTHORIZED"; + status = "granted"; break; case.denied, .restricted: - status = "PHOTO_LIBRARY/DENIED"; + status = "denied"; break; case.notDetermined: - status = "PHOTO_LIBRARY/NOT_DETERMINED"; + status = "not_determined"; break; } call.resolve([ @@ -39,26 +39,26 @@ public class AppPermissionsPlugin: CAPPlugin { ]) } break; - case "CAMERA": + case "camera": AVCaptureDevice.requestAccess(for: .video) { (granted) in if granted { - status = "CAMERA/AUTHORIZED"; + status = "granted"; } else { - status = "CAMERA/DENIED"; + status = "denied"; } call.success([ "status": status ]) } break; - case "NOTIFICATION": + case "notifications": UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in if granted { - status = "NOTIFICATION/AUTHORIZED"; + status = "granted"; } else { - status = "NOTIFICATION/DENIED"; + status = "denied"; } call.success([ "status": status @@ -70,80 +70,24 @@ public class AppPermissionsPlugin: CAPPlugin { } } - + @objc func query(_ call: CAPPluginCall) { - let permission = call.getString("name") ?? "" - var status = ""; - switch (permission) { - case "LOCATION_WHEN_IN_USE", "LOCATION_ALWAYS": - switch (CLLocationManager.authorizationStatus()) { - case.authorizedAlways: - status = "LOCATION/AUTHORIZED_ALWAYS"; - break; - case.authorizedWhenInUse: - status = "LOCATION/AUTHORIZED_WHEN_IN_USE"; - break; - case.denied, .restricted: - status = "LOCATION/DENIED"; - break; - case .notDetermined: - status = "LOCATION/NOT_DETERMINED"; - break; - } - call.resolve([ - "status": status - ]) - break; - case "PHOTO_LIBRARY": - switch (PHPhotoLibrary.authorizationStatus()) { - case .authorized: - status = "PHOTO_LIBRARY/AUTHORIZED"; - break; - case.denied, .restricted: - status = "PHOTO_LIBRARY/DENIED"; - break; - case.notDetermined: - status = "PHOTO_LIBRARY/NOT_DETERMINED"; - break; - } - call.resolve([ - "status": status - ]) - break; - case "CAMERA": - switch (AVCaptureDevice.authorizationStatus(for: .video)) { - case .authorized: - status = "CAMERA/AUTHORIZED"; - break; - case.denied, .restricted: - status = "CAMERA/DENIED"; - break; - case.notDetermined: - status = "CAMERA/NOT_DETERMINED"; - break; - } - call.resolve([ - "status": status - ]) - break; - case "NOTIFICATION": - UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { settings in - switch settings.authorizationStatus { - case .authorized, .provisional: - status = "NOTIFICATION/AUTHORIZED"; - case .denied: - status = "NOTIFICATION/DENIED"; - case .notDetermined: - status = "NOTIFICATION/NOT_DETERMINED"; - } - call.resolve([ - "status": status - ]) - } - ) - break; + guard let name = call.getString("name") else { + call.reject("Must provide a permission to check") + return + } + + switch (name) { + case "camera": + return checkCamera(call) + case "geolocation": + return checkGeolocation(call) + case "notifications": + return checkNotifications(call) + case "photos": + return checkPhotos(call) default: - status = "ERROR"; + return call.reject("Unknown permission type") } } } diff --git a/package.json b/package.json index 14d8f3e..16ca982 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "capacitor-permissions", - "version": "0.0.21", + "version": "0.0.22", "description": "A Capacitor plugin for accessing and requesting app permissions", "main": "dist/esm/index.js", "types": "dist/esm/index.d.ts", diff --git a/src/definitions.ts b/src/definitions.ts index 3fa8932..e2d65f2 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -12,15 +12,6 @@ export interface PluginListenerHandle { remove: () => void; } -export declare enum PermissionType { - Camera = "camera", - Photos = "photos", - FileWrite = "file-write", - Geolocation = "geolocation", - Notifications = "notifications", - ClipboardRead = "clipboard-read", - ClipboardWrite = "clipboard-write" -} export interface PermissionsRequestResult { results: any[]; @@ -32,7 +23,7 @@ export interface PermissionsPlugin extends Plugin { } export interface PermissionsOptions { - name: PermissionType; + name: string; } export interface PermissionResult { state: 'granted' | 'denied' | 'prompt'; diff --git a/src/web.ts b/src/web.ts index 95c6749..a0a98f6 100644 --- a/src/web.ts +++ b/src/web.ts @@ -1,5 +1,5 @@ import { WebPlugin } from '@capacitor/core'; -import { PermissionsPlugin, PermissionsOptions, PermissionResult, PermissionType } from './definitions'; +import { PermissionsPlugin, PermissionsOptions, PermissionResult } from './definitions'; export class AppPermissionsPluginWeb extends WebPlugin implements PermissionsPlugin { @@ -22,7 +22,7 @@ export class AppPermissionsPluginWeb extends WebPlugin implements PermissionsPlu return Promise.reject('This browser does not support the Permissions API'); } - const name = options.name === PermissionType.Photos ? 'camera' : options.name; + const name = options.name; const ret = await navigator.permissions.query({ name }); return {