Commit b9366c71 by Frank Gregor

Merge branch 'develop' of github.com:phranck/flutter-permission-handler into develop

# Conflicts:
#	ios/Classes/PermissionManager.m
parents 4a1d3a48 dc6beac0
...@@ -37,7 +37,7 @@ We really appreciate contributions via GitHub pull requests. To contribute take ...@@ -37,7 +37,7 @@ We really appreciate contributions via GitHub pull requests. To contribute take
* Apply your changes * Apply your changes
* Verify your changes and fix potential warnings/ errors: * Verify your changes and fix potential warnings/ errors:
* Check formatting: `flutter format .` * Check formatting: `flutter format .`
* Run static analyses: `flutter analyzes` * Run static analyses: `flutter analyze`
* Run unit-tests: `flutter test` * Run unit-tests: `flutter test`
* Commit your changes: `git commit -am "<your informative commit message>"` * Commit your changes: `git commit -am "<your informative commit message>"`
* Push changes to your fork: `git push origin <name_of_your_branch>` * Push changes to your fork: `git push origin <name_of_your_branch>`
......
...@@ -169,6 +169,10 @@ enum PermissionGroup { ...@@ -169,6 +169,10 @@ enum PermissionGroup {
/// Android: None /// Android: None
/// iOS: MPMediaLibrary /// iOS: MPMediaLibrary
mediaLibrary mediaLibrary
/// Android: Check notification enable
/// iOS: Check and request notification permission
notification
} }
``` ```
......
...@@ -19,6 +19,7 @@ import android.telephony.TelephonyManager; ...@@ -19,6 +19,7 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.core.app.NotificationManagerCompat;
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener; import io.flutter.plugin.common.PluginRegistry.ActivityResultListener;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
...@@ -60,7 +61,8 @@ public class PermissionHandlerPlugin implements MethodCallHandler { ...@@ -60,7 +61,8 @@ public class PermissionHandlerPlugin implements MethodCallHandler {
private static final int PERMISSION_GROUP_SPEECH = 13; private static final int PERMISSION_GROUP_SPEECH = 13;
private static final int PERMISSION_GROUP_STORAGE = 14; private static final int PERMISSION_GROUP_STORAGE = 14;
private static final int PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS = 15; private static final int PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS = 15;
private static final int PERMISSION_GROUP_UNKNOWN = 16; private static final int PERMISSION_GROUP_NOTIFICATION = 16;
private static final int PERMISSION_GROUP_UNKNOWN = 17;
private PermissionHandlerPlugin(Registrar mRegistrar) { private PermissionHandlerPlugin(Registrar mRegistrar) {
this.mRegistrar = mRegistrar; this.mRegistrar = mRegistrar;
...@@ -84,6 +86,7 @@ public class PermissionHandlerPlugin implements MethodCallHandler { ...@@ -84,6 +86,7 @@ public class PermissionHandlerPlugin implements MethodCallHandler {
PERMISSION_GROUP_SPEECH, PERMISSION_GROUP_SPEECH,
PERMISSION_GROUP_STORAGE, PERMISSION_GROUP_STORAGE,
PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS, PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS,
PERMISSION_GROUP_NOTIFICATION,
PERMISSION_GROUP_UNKNOWN, PERMISSION_GROUP_UNKNOWN,
}) })
private @interface PermissionGroup { private @interface PermissionGroup {
...@@ -250,6 +253,16 @@ public class PermissionHandlerPlugin implements MethodCallHandler { ...@@ -250,6 +253,16 @@ public class PermissionHandlerPlugin implements MethodCallHandler {
@PermissionStatus @PermissionStatus
private int checkPermissionStatus(@PermissionGroup int permission) { private int checkPermissionStatus(@PermissionGroup int permission) {
final Context context = mRegistrar.activity() == null ? mRegistrar.activeContext() : mRegistrar.activity();
if (context == null) {
Log.d(LOG_TAG, "Unable to detect current Activity or App Context.");
return PERMISSION_STATUS_UNKNOWN;
}
if (permission == PERMISSION_GROUP_NOTIFICATION) {
return checkNotificationPermissionStatus(context);
}
final List<String> names = getManifestNames(permission); final List<String> names = getManifestNames(permission);
if (names == null) { if (names == null) {
...@@ -264,12 +277,6 @@ public class PermissionHandlerPlugin implements MethodCallHandler { ...@@ -264,12 +277,6 @@ public class PermissionHandlerPlugin implements MethodCallHandler {
return PERMISSION_STATUS_UNKNOWN; return PERMISSION_STATUS_UNKNOWN;
} }
final Context context = mRegistrar.activity() == null ? mRegistrar.activeContext() : mRegistrar.activity();
if (context == null) {
Log.d(LOG_TAG, "Unable to detect current Activity or App Context.");
return PERMISSION_STATUS_UNKNOWN;
}
final boolean targetsMOrHigher = context.getApplicationInfo().targetSdkVersion >= VERSION_CODES.M; final boolean targetsMOrHigher = context.getApplicationInfo().targetSdkVersion >= VERSION_CODES.M;
for (String name : names) { for (String name : names) {
...@@ -655,6 +662,7 @@ public class PermissionHandlerPlugin implements MethodCallHandler { ...@@ -655,6 +662,7 @@ public class PermissionHandlerPlugin implements MethodCallHandler {
permissionNames.add(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); permissionNames.add(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
break; break;
case PERMISSION_GROUP_NOTIFICATION:
case PERMISSION_GROUP_MEDIA_LIBRARY: case PERMISSION_GROUP_MEDIA_LIBRARY:
case PERMISSION_GROUP_PHOTOS: case PERMISSION_GROUP_PHOTOS:
case PERMISSION_GROUP_REMINDERS: case PERMISSION_GROUP_REMINDERS:
...@@ -726,4 +734,13 @@ public class PermissionHandlerPlugin implements MethodCallHandler { ...@@ -726,4 +734,13 @@ public class PermissionHandlerPlugin implements MethodCallHandler {
return !TextUtils.isEmpty(locationProviders); return !TextUtils.isEmpty(locationProviders);
} }
} }
private int checkNotificationPermissionStatus(Context context) {
NotificationManagerCompat manager = NotificationManagerCompat.from(context);
boolean isGranted = manager.areNotificationsEnabled();
if (isGranted) {
return PERMISSION_STATUS_GRANTED;
}
return PERMISSION_STATUS_DENIED;
}
} }
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array/>
</dict>
</plist>
...@@ -22,6 +22,7 @@ typedef NS_ENUM(int, PermissionGroup) { ...@@ -22,6 +22,7 @@ typedef NS_ENUM(int, PermissionGroup) {
PermissionGroupSpeech, PermissionGroupSpeech,
PermissionGroupStorage, PermissionGroupStorage,
PermissionGroupIgnoreBatteryOptimizations, PermissionGroupIgnoreBatteryOptimizations,
PermissionGroupNotification,
PermissionGroupUnknown, PermissionGroupUnknown,
}; };
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#import "SpeechPermissionStrategy.h" #import "SpeechPermissionStrategy.h"
#import "StoragePermissionStrategy.h" #import "StoragePermissionStrategy.h"
#import "UnknownPermissionStrategy.h" #import "UnknownPermissionStrategy.h"
#import "NotificationPermissionStrategy.h"
#import "PermissionHandlerEnums.h" #import "PermissionHandlerEnums.h"
#import "Codec.h" #import "Codec.h"
......
...@@ -99,6 +99,8 @@ ...@@ -99,6 +99,8 @@
return [SensorPermissionStrategy new]; return [SensorPermissionStrategy new];
case PermissionGroupSpeech: case PermissionGroupSpeech:
return [SpeechPermissionStrategy new]; return [SpeechPermissionStrategy new];
case PermissionGroupNotification:
return [NotificationPermissionStrategy new];
case PermissionGroupStorage: case PermissionGroupStorage:
return [StoragePermissionStrategy new]; return [StoragePermissionStrategy new];
default: default:
......
//
// NotificationPermissionStrategy.h
// permission_handler
//
// Created by Tong on 2019/10/21.
//
#import <Foundation/Foundation.h>
#import <UserNotifications/UserNotifications.h>
#import "PermissionStrategy.h"
@interface NotificationPermissionStrategy : NSObject <PermissionStrategy>
@end
//
// NotificationPermissionStrategy.m
// permission_handler
//
// Created by Tong on 2019/10/21.
//
#import "NotificationPermissionStrategy.h"
@implementation NotificationPermissionStrategy
- (PermissionStatus)checkPermissionStatus:(PermissionGroup)permission {
return [NotificationPermissionStrategy permissionStatus];
}
- (ServiceStatus)checkServiceStatus:(PermissionGroup)permission {
return ServiceStatusNotApplicable;
}
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
PermissionStatus status = [self checkPermissionStatus:permission];
if (status != PermissionStatusUnknown) {
completionHandler(status);
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
if(@available(iOS 10.0, *)) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNAuthorizationOptions authorizationOptions = 0;
authorizationOptions += UNAuthorizationOptionSound;
authorizationOptions += UNAuthorizationOptionAlert;
authorizationOptions += UNAuthorizationOptionBadge;
[center requestAuthorizationWithOptions:(authorizationOptions) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted || error != nil) {
completionHandler(PermissionStatusDenied);
return;
}
}];
} else {
UIUserNotificationType notificationTypes = 0;
notificationTypes |= UIUserNotificationTypeSound;
notificationTypes |= UIUserNotificationTypeAlert;
notificationTypes |= UIUserNotificationTypeBadge;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
[[UIApplication sharedApplication] registerForRemoteNotifications];
completionHandler(PermissionStatusGranted);
});
}
+ (PermissionStatus)permissionStatus {
__block PermissionStatus permissionStatus = PermissionStatusGranted;
if (@available(iOS 10 , *)) {
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
permissionStatus = PermissionStatusDenied;
} else if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
permissionStatus = PermissionStatusUnknown;
}
dispatch_semaphore_signal(sem);
}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
} else if (@available(iOS 8 , *)) {
UIUserNotificationSettings * setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (setting.types == UIUserNotificationTypeNone) permissionStatus = PermissionStatusDenied;
} else {
UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (type == UIUserNotificationTypeNone) permissionStatus = PermissionStatusDenied;
}
return permissionStatus;
}
@end
...@@ -149,8 +149,12 @@ class PermissionGroup { ...@@ -149,8 +149,12 @@ class PermissionGroup {
static const PermissionGroup ignoreBatteryOptimizations = static const PermissionGroup ignoreBatteryOptimizations =
PermissionGroup._(15); PermissionGroup._(15);
/// Android: Notification
/// iOS: Notification
static const PermissionGroup notification = PermissionGroup._(16);
/// The unknown permission only used for return type, never requested /// The unknown permission only used for return type, never requested
static const PermissionGroup unknown = PermissionGroup._(16); static const PermissionGroup unknown = PermissionGroup._(17);
static const List<PermissionGroup> values = <PermissionGroup>[ static const List<PermissionGroup> values = <PermissionGroup>[
calendar, calendar,
...@@ -169,6 +173,7 @@ class PermissionGroup { ...@@ -169,6 +173,7 @@ class PermissionGroup {
speech, speech,
storage, storage,
ignoreBatteryOptimizations, ignoreBatteryOptimizations,
notification,
unknown, unknown,
]; ];
...@@ -189,6 +194,7 @@ class PermissionGroup { ...@@ -189,6 +194,7 @@ class PermissionGroup {
'speech', 'speech',
'storage', 'storage',
'ignoreBatteryOptimizations', 'ignoreBatteryOptimizations',
'notification',
'unknown', 'unknown',
]; ];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment