Commit bc3e34a5 by Maurits van Beusekom

Version 3.1.0

parents 9acc3714 6a19290a
## 3.1.0
* Support service status inquiry for phone permission on iOS & Android.
## 3.0.2
* Fixed bug when rapidly requesting permissions (#23);
......
......@@ -22,7 +22,7 @@ To use this plugin, add `permission_handler` as a [dependency in your pubspec.ya
```yaml
dependencies:
permission_handler: '^3.0.0'
permission_handler: '^3.1.0'
```
> **NOTE:** There's a known issue with integrating plugins that use Swift into a Flutter project created with the Objective-C template. See issue [Flutter#16049](https://github.com/flutter/flutter/issues/16049) for help on integration.
......
......@@ -9,7 +9,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.android.tools.build:gradle:3.4.1'
}
}
......@@ -35,8 +35,8 @@ android {
}
dependencies {
implementation 'androidx.annotation:annotation:1.0.1'
implementation 'androidx.core:core:1.0.1'
implementation 'androidx.annotation:annotation:1.0.2'
implementation 'androidx.core:core:1.0.2'
}
repositories {
......
......@@ -7,9 +7,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
......@@ -281,6 +284,34 @@ public class PermissionHandlerPlugin implements MethodCallHandler {
return isLocationServiceEnabled(context) ? SERVICE_STATUS_ENABLED : SERVICE_STATUS_DISABLED;
}
if (permission == PERMISSION_GROUP_PHONE) {
PackageManager pm = context.getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
return SERVICE_STATUS_NOT_APPLICABLE;
}
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
return SERVICE_STATUS_NOT_APPLICABLE;
}
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:123123"));
List<ResolveInfo> callAppsList = pm.queryIntentActivities(callIntent, 0);
if (callAppsList.isEmpty()) {
return SERVICE_STATUS_NOT_APPLICABLE;
}
if (telephonyManager.getSimState() != TelephonyManager.SIM_STATE_READY) {
return SERVICE_STATUS_DISABLED;
}
return SERVICE_STATUS_ENABLED;
}
return SERVICE_STATUS_NOT_APPLICABLE;
}
......
......@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.android.tools.build:gradle:3.4.1'
}
}
......
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
platform :ios, '8.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
......
......@@ -13,7 +13,6 @@
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
......@@ -179,7 +178,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0910;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
......@@ -213,7 +212,6 @@
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
......@@ -242,7 +240,7 @@
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
......@@ -251,7 +249,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
......@@ -330,6 +328,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
......@@ -339,12 +338,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
......@@ -402,6 +403,7 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
......@@ -411,12 +413,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
......@@ -456,6 +460,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
......@@ -465,12 +470,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
......
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
......@@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
......@@ -46,7 +45,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
......
......@@ -28,7 +28,6 @@ class MyApp extends StatelessWidget {
.where((PermissionGroup permission) {
if (Platform.isIOS) {
return permission != PermissionGroup.unknown &&
permission != PermissionGroup.phone &&
permission != PermissionGroup.sms &&
permission != PermissionGroup.storage;
} else {
......
......@@ -15,6 +15,7 @@
#import "LocationPermissionStrategy.h"
#import "MediaLibraryPermissionStrategy.h"
#import "PermissionStrategy.h"
#import "PhonePermissionStrategy.h"
#import "PhotoPermissionStrategy.h"
#import "SensorPermissionStrategy.h"
#import "SpeechPermissionStrategy.h"
......
......@@ -89,6 +89,8 @@
return [MediaLibraryPermissionStrategy new];
case PermissionGroupMicrophone:
return [AudioVideoPermissionStrategy new];
case PermissionGroupPhone:
return [PhonePermissionStrategy new];
case PermissionGroupPhotos:
return [PhotoPermissionStrategy new];
case PermissionGroupReminders:
......
......@@ -133,6 +133,9 @@
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
switch (authorizationStatus) {
case kCLAuthorizationStatusNotDetermined:
return PermissionStatusUnknown;
......@@ -145,6 +148,9 @@
default:
return PermissionStatusUnknown;
}
#pragma clang diagnostic pop
}
@end
......@@ -43,7 +43,7 @@
return PermissionStatusUnknown;
}
+ (PermissionStatus)determinePermissionStatus:(MPMediaLibraryAuthorizationStatus)authorizationStatus {
+ (PermissionStatus)determinePermissionStatus:(MPMediaLibraryAuthorizationStatus)authorizationStatus API_AVAILABLE(ios(9.3)){
switch (authorizationStatus) {
case MPMediaLibraryAuthorizationStatusNotDetermined:
return PermissionStatusUnknown;
......@@ -58,4 +58,4 @@
return PermissionStatusUnknown;
}
@end
\ No newline at end of file
@end
//
// PhonePermissionStrategy.h
// permission_handler
//
// Created by Sebastian Roth on 5/20/19.
//
#import <Foundation/Foundation.h>
#import "PermissionStrategy.h"
NS_ASSUME_NONNULL_BEGIN
@interface PhonePermissionStrategy : NSObject<PermissionStrategy>
@end
NS_ASSUME_NONNULL_END
//
// PhonePermissionStrategy.m
// permission_handler
//
// Created by Sebastian Roth on 5/20/19.
//
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#import "PhonePermissionStrategy.h"
@implementation PhonePermissionStrategy
- (PermissionStatus)checkPermissionStatus:(PermissionGroup)permission {
return PermissionStatusUnknown;
}
- (ServiceStatus)checkServiceStatus:(PermissionGroup)permission {
// https://stackoverflow.com/a/5095058
if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]]) {
return ServiceStatusNotApplicable;
}
return [self canDevicePlaceAPhoneCall] ? ServiceStatusEnabled : ServiceStatusDisabled;
}
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
completionHandler(PermissionStatusUnknown);
}
// https://stackoverflow.com/a/11595365
-(bool) canDevicePlaceAPhoneCall {
/*
* Returns YES if the device can place a phone call
*/
// Device supports phone calls, lets confirm it can place one right now
CTTelephonyNetworkInfo *netInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [netInfo subscriberCellularProvider];
NSString *mnc = [carrier mobileNetworkCode];
if (([mnc length] == 0) || ([mnc isEqualToString:@"65535"])) {
// Device cannot place a call at this time. SIM might be removed.
return NO;
} else {
// Device can place a phone call
return YES;
}
}
@end
......@@ -42,7 +42,7 @@
return PermissionStatusUnknown;
}
+ (PermissionStatus)determinePermissionStatus:(SFSpeechRecognizerAuthorizationStatus)authorizationStatus {
+ (PermissionStatus)determinePermissionStatus:(SFSpeechRecognizerAuthorizationStatus)authorizationStatus API_AVAILABLE(ios(10.0)){
switch (authorizationStatus) {
case SFSpeechRecognizerAuthorizationStatusNotDetermined:
return PermissionStatusUnknown;
......
......@@ -3,7 +3,7 @@
#
Pod::Spec.new do |s|
s.name = 'permission_handler'
s.version = '3.0.2'
s.version = '3.1.0'
s.summary = 'Permission plugin for Flutter.'
s.description = <<-DESC
A new Flutter project.
......
......@@ -40,6 +40,25 @@ class PermissionHandler {
/// Check current service status.
///
/// Returns a [Future] containing the current service status for the supplied [PermissionGroup].
///
/// Notes about specific PermissionGroups:
/// - **PermissionGroup.phone**
/// - Android:
/// - The method will return [ServiceStatus.notApplicable] when:
/// 1. the device lacks the TELEPHONY feature
/// 1. TelephonyManager.getPhoneType() returns PHONE_TYPE_NONE
/// 1. when no Intents can be resolved to handle the `tel:` scheme
/// - The method will return [ServiceStatus.disabled] when:
/// 1. the SIM card is missing
/// - iOS:
/// - The method will return [ServiceStatus.notApplicable] when:
/// 1. the native code can not find a handler for the `tel:` scheme
/// - The method will return [ServiceStatus.disabled] when:
/// 1. the mobile network code (MNC) is either 0 or 65535. See
/// https://stackoverflow.com/a/11595365 for details
/// - **PLEASE NOTE that this is still not a perfect indication** of the
/// devices' capability to place & connect phone calls
/// as it also depends on the network condition.
Future<ServiceStatus> checkServiceStatus(PermissionGroup permission) async {
final int status = await _methodChannel.invokeMethod(
'checkServiceStatus', permission.value);
......
name: permission_handler
description: Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
version: 3.0.2
version: 3.1.0
authors:
- Baseflow <hello@baseflow.com>
- long1eu <home@long1.eu>
- Sebastian Roth <sebastian.roth@gmail.com>
homepage: https://github.com/baseflowit/flutter-permission-handler
environment:
......
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