Skip to content

Commit f145532

Browse files
authored
Merge pull request #9 from BaseflowIT/feature/example_app
Implemented example app
2 parents 7bde400 + c95a87f commit f145532

11 files changed

+157
-59
lines changed

android/src/main/kotlin/com/baseflow/permissionhandler/PermissionHandlerPlugin.kt

+8-4
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,14 @@ class PermissionHandlerPlugin(private val registrar: Registrar, private var requ
220220
}
221221
}
222222

223-
ActivityCompat.requestPermissions(
224-
registrar.activity(),
225-
permissionsToRequest.toTypedArray(),
226-
permissionCode)
223+
if (permissionsToRequest.count() > 0) {
224+
ActivityCompat.requestPermissions(
225+
registrar.activity(),
226+
permissionsToRequest.toTypedArray(),
227+
permissionCode)
228+
} else if (mRequestResults.count() > 0) {
229+
processResult()
230+
}
227231
}
228232

229233
private fun handlePermissionsRequest(permissions: Array<String>, grantResults: IntArray) {
Binary file not shown.

example/android/.idea/misc.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/android/app/src/main/AndroidManifest.xml

+22-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,28 @@
66
to allow setting breakpoints, to provide hot reload, etc.
77
-->
88
<uses-permission android:name="android.permission.INTERNET"/>
9-
<uses-permission android:name="android.permission.READ_CALENDAR"/>
10-
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
9+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
10+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
11+
<uses-permission android:name="android.permission.RECEIVE_MMS" />
12+
<uses-permission android:name="android.permission.RECEIVE_SMS" />
13+
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
14+
<uses-permission android:name="android.permission.RECORD_AUDIO" />
15+
<uses-permission android:name="android.permission.CALL_PHONE" />
16+
<uses-permission android:name="android.permission.CAMERA" />
17+
<uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
18+
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
19+
<uses-permission android:name="android.permission.READ_CALL_LOG" />
20+
<uses-permission android:name="android.permission.READ_CALENDAR" />
21+
<uses-permission android:name="android.permission.READ_CONTACTS" />
22+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
23+
<uses-permission android:name="android.permission.READ_SMS" />
24+
<uses-permission android:name="android.permission.SEND_SMS" />
25+
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
26+
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
27+
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
28+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
29+
<uses-permission android:name="android.permission.SENSORS" />
30+
<uses-permission android:name="android.permission.BODY_SENSORS" />
1131

1232
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
1333
calls FlutterMain.startInitialization(this); in its onCreate method.

example/lib/main.dart

+69-16
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,46 @@
1+
import 'dart:io';
2+
13
import 'package:flutter/material.dart';
24
import 'package:permission_handler/permission_enums.dart';
35
import 'package:permission_handler/permission_handler.dart';
46

57
void main() => runApp(new MyApp());
68

79
class MyApp extends StatelessWidget {
8-
910
@override
1011
Widget build(BuildContext context) {
1112
return new MaterialApp(
12-
home: new Scaffold(
13-
appBar: new AppBar(
14-
title: const Text('Plugin example app'),
15-
),
16-
body: new Center(
17-
child: new ListView(
13+
home: new Scaffold(
14+
appBar: new AppBar(
15+
title: const Text('Plugin example app'),
16+
actions: <Widget>[
17+
IconButton(
18+
icon: const Icon(Icons.settings),
19+
onPressed: () {
20+
PermissionHandler.openAppSettings();
21+
},
22+
)
23+
],
24+
),
25+
body: new Center(
26+
child: new ListView(
1827
children: PermissionGroup.values
19-
.where((PermissionGroup permission) => permission != PermissionGroup.unknown)
20-
.map((PermissionGroup permission) => new PermissionWidget(permission)).toList()
21-
),
28+
.where((PermissionGroup permission) {
29+
if (Platform.isIOS) {
30+
return permission != PermissionGroup.unknown &&
31+
permission != PermissionGroup.phone &&
32+
permission != PermissionGroup.sms &&
33+
permission != PermissionGroup.storage;
34+
} else {
35+
return permission != PermissionGroup.unknown &&
36+
permission != PermissionGroup.mediaLibrary &&
37+
permission != PermissionGroup.photos &&
38+
permission != PermissionGroup.reminders;
39+
}
40+
})
41+
.map((PermissionGroup permission) =>
42+
new PermissionWidget(permission))
43+
.toList()),
2244
),
2345
));
2446
}
@@ -38,7 +60,7 @@ class _PermissionState extends State<PermissionWidget> {
3860
PermissionStatus _permissionStatus = PermissionStatus.unknown;
3961

4062
_PermissionState(this._permissionGroup);
41-
63+
4264
@override
4365
void initState() {
4466
super.initState();
@@ -47,15 +69,46 @@ class _PermissionState extends State<PermissionWidget> {
4769
}
4870

4971
void _listenForPermissionStatus() async {
50-
print(_permissionGroup.toString());
51-
_permissionStatus = await PermissionHandler.checkPermissionStatus(_permissionGroup);
72+
final PermissionStatus status =
73+
await PermissionHandler.checkPermissionStatus(_permissionGroup);
74+
75+
setState(() {
76+
_permissionStatus = status;
77+
});
78+
}
79+
80+
Color getPermissionColor() {
81+
switch (_permissionStatus) {
82+
case PermissionStatus.denied:
83+
return Colors.red;
84+
case PermissionStatus.granted:
85+
return Colors.green;
86+
default:
87+
return Colors.grey;
88+
}
5289
}
5390

54-
@override
91+
@override
5592
Widget build(BuildContext context) {
5693
return new ListTile(
5794
title: new Text(_permissionGroup.toString()),
58-
subtitle: new Text(_permissionStatus.toString()),
95+
subtitle: new Text(
96+
_permissionStatus.toString(),
97+
style: new TextStyle(color: getPermissionColor()),
98+
),
99+
onTap: () async {
100+
requestPermission(_permissionGroup);
101+
},
59102
);
60103
}
61-
}
104+
105+
void requestPermission(PermissionGroup permission) async {
106+
final List<PermissionGroup> permissions = <PermissionGroup>[permission];
107+
final Map<PermissionGroup, PermissionStatus> permissionRequestResult =
108+
await PermissionHandler.requestPermissions(permissions);
109+
110+
setState(() {
111+
_permissionStatus = permissionRequestResult[permission];
112+
});
113+
}
114+
}

ios/Classes/PermissionManager.swift

+12-17
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,36 @@
88
import Flutter
99
import Foundation
1010
import UIKit
11+
import Swift
1112

1213
class PermissionManager: NSObject {
14+
private var _strategyInstances: [ObjectIdentifier: PermissionStrategy] = [:]
1315

1416
static func checkPermissionStatus(permission: PermissionGroup, result: @escaping FlutterResult) {
1517
let permissionStrategy = PermissionManager.createPermissionStrategy(permission: permission)
16-
let permissionStatus = permissionStrategy?.checkPermissionStatus(permission: permission) ?? PermissionStatus.unknown
18+
let permissionStatus = permissionStrategy.checkPermissionStatus(permission: permission)
1719

1820
result(Codec.encodePermissionStatus(permissionStatus: permissionStatus))
1921
}
2022

21-
static func requestPermission(permissions: [PermissionGroup], result: @escaping FlutterResult) {
23+
func requestPermission(permissions: [PermissionGroup], result: @escaping FlutterResult) {
2224
var requestQueue = Set(permissions.map { $0 })
2325
var permissionStatusResult: [PermissionGroup: PermissionStatus] = [:]
2426

2527
for permission in permissions {
2628
let permissionStrategy = PermissionManager.createPermissionStrategy(permission: permission)
27-
28-
if permissionStrategy == nil {
29-
permissionStatusResult[permission] = PermissionStatus.unknown
29+
let identifier = ObjectIdentifier(permissionStrategy as AnyObject)
30+
_strategyInstances[identifier] = permissionStrategy
31+
32+
permissionStrategy.requestPermission(permission: permission) { (permissionStatus: PermissionStatus) in
33+
permissionStatusResult[permission] = permissionStatus
3034
requestQueue.remove(permission)
35+
self._strategyInstances.removeValue(forKey: ObjectIdentifier(permissionStrategy as AnyObject))
3136

3237
if requestQueue.count == 0 {
3338
result(Codec.encodePermissionRequestResult(permissionStatusResult: permissionStatusResult))
3439
return
3540
}
36-
} else {
37-
permissionStrategy!.requestPermission(permission: permission) { (permissionStatus: PermissionStatus) in
38-
permissionStatusResult[permission] = permissionStatus
39-
requestQueue.remove(permission)
40-
41-
if requestQueue.count == 0 {
42-
result(Codec.encodePermissionRequestResult(permissionStatusResult: permissionStatusResult))
43-
return
44-
}
45-
}
4641
}
4742
}
4843
}
@@ -63,7 +58,7 @@ class PermissionManager: NSObject {
6358
result(false)
6459
}
6560

66-
private static func createPermissionStrategy(permission: PermissionGroup) -> PermissionStrategy? {
61+
private static func createPermissionStrategy(permission: PermissionGroup) -> PermissionStrategy {
6762
switch permission {
6863
case PermissionGroup.calendar:
6964
return EventPermissionStrategy()
@@ -88,7 +83,7 @@ class PermissionManager: NSObject {
8883
case PermissionGroup.speech:
8984
return SpeechPermissionStrategy()
9085
default:
91-
return nil
86+
return UnknownPermissionStrategy()
9287
}
9388
}
9489
}

ios/Classes/SwiftPermissionHandlerPlugin.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import UIKit
99

1010
public class SwiftPermissionHandlerPlugin: NSObject, FlutterPlugin {
1111
private static let METHOD_CHANNEL_NAME = "flutter.baseflow.com/permissions/methods";
12+
private let _permissionManager: PermissionManager = PermissionManager()
1213

1314
public static func register(with registrar: FlutterPluginRegistrar) {
1415
let channel = FlutterMethodChannel(name: METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())
@@ -23,7 +24,7 @@ public class SwiftPermissionHandlerPlugin: NSObject, FlutterPlugin {
2324
from: call.arguments),
2425
result: result)
2526
} else if call.method == "requestPermissions" {
26-
PermissionManager.requestPermission(
27+
_permissionManager.requestPermission(
2728
permissions: Codec.decodePermissionGroups(
2829
from: call.arguments),
2930
result: result)

ios/Classes/strategies/LocationPermissionStrategy.swift

+17-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import CoreLocation
99
import Foundation
1010

1111
class LocationPermissionStrategy : NSObject, PermissionStrategy, CLLocationManagerDelegate {
12+
private var _locationManager: CLLocationManager? = nil
1213
private var _permissionStatusHandler: PermissionStatusHandler? = nil
1314
private var _requestedPermission: PermissionGroup? = nil
1415

@@ -40,33 +41,40 @@ class LocationPermissionStrategy : NSObject, PermissionStrategy, CLLocationManag
4041

4142
_permissionStatusHandler = completionHandler
4243
_requestedPermission = permission
43-
let locationManager = CLLocationManager.init()
44-
locationManager.delegate = self
4544

46-
if(permission != PermissionGroup.location) {
47-
if (Bundle.main.object(forInfoDictionaryKey: "NSLocationWhenInUseUsageDescription") != nil) {
48-
locationManager.requestWhenInUseAuthorization()
49-
} else if (Bundle.main.object(forInfoDictionaryKey: "NSLocationAlwaysUsageDescription") != nil) {
50-
locationManager.requestAlwaysAuthorization();
45+
if(_locationManager == nil) {
46+
_locationManager = CLLocationManager()
47+
_locationManager!.delegate = self
48+
}
49+
50+
if(permission == PermissionGroup.location) {
51+
if (Bundle.main.object(forInfoDictionaryKey: "NSLocationAlwaysUsageDescription") != nil) {
52+
_locationManager!.requestAlwaysAuthorization()
53+
} else if (Bundle.main.object(forInfoDictionaryKey: "NSLocationWhenInUseUsageDescription") != nil) {
54+
_locationManager!.requestWhenInUseAuthorization();
5155
} else {
5256
NSException(name: NSExceptionName.internalInconsistencyException, reason:"To use location in iOS8 you need to define either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in the app bundle's Info.plist file", userInfo: nil).raise()
5357
}
5458
} else if permission == PermissionGroup.locationAlways {
5559
if (Bundle.main.object(forInfoDictionaryKey: "NSLocationAlwaysUsageDescription") != nil) {
56-
locationManager.requestAlwaysAuthorization();
60+
_locationManager!.requestAlwaysAuthorization();
5761
} else {
5862
NSException(name: NSExceptionName.internalInconsistencyException, reason:"To use location in iOS8 you need to define NSLocationAlwaysUsageDescription in the app bundle's Info.plist file", userInfo: nil).raise()
5963
}
6064
} else if permission == PermissionGroup.locationWhenInUse {
6165
if (Bundle.main.object(forInfoDictionaryKey: "NSLocationWhenInUseUsageDescription") != nil) {
62-
locationManager.requestWhenInUseAuthorization();
66+
_locationManager!.requestWhenInUseAuthorization();
6367
} else {
6468
NSException(name: NSExceptionName.internalInconsistencyException, reason:"To use location in iOS8 you need to define NSLocationWhenInUseUsageDescription in the app bundle's Info.plist file", userInfo: nil).raise()
6569
}
6670
}
6771
}
6872

6973
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
74+
if status == CLAuthorizationStatus.notDetermined {
75+
return
76+
}
77+
7078
guard let completionHandler = _permissionStatusHandler else { return }
7179

7280
completionHandler(

ios/Classes/strategies/SensorPermissionStrategy.swift

+6-7
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,13 @@ class SensorPermissionStrategy : NSObject, PermissionStrategy {
4848
if #available(iOS 11.0, *) {
4949
let motionManager = CMMotionActivityManager.init()
5050

51-
motionManager.queryActivityStarting(from: NSDate.distantPast, to: NSDate.distantFuture, to: OperationQueue.main) {
52-
(results: [CMMotionActivity]?, error: Error?) in
53-
if results != nil {
54-
completionHandler(PermissionStatus.granted)
55-
} else {
56-
completionHandler(PermissionStatus.denied)
57-
}
51+
motionManager.startActivityUpdates(to: OperationQueue.main) { (_) in
52+
motionManager.stopActivityUpdates()
53+
54+
completionHandler(.granted)
5855
}
56+
} else {
57+
completionHandler(.unknown)
5958
}
6059
}
6160
}

ios/Classes/strategies/SpeechPermissionStrategy.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ class SpeechPermissionStrategy : NSObject, PermissionStrategy {
3838
SpeechPermissionStrategy.determinePermissionStatus(authorizationStatus: authorizationStatus))
3939
return
4040
}
41+
} else {
42+
completionHandler(PermissionStatus.unknown)
4143
}
42-
43-
completionHandler(PermissionStatus.unknown)
4444
}
4545

4646
@available(iOS 10.0, *)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// UnknownPermissionStrategy.swift
3+
// permission_handler
4+
//
5+
// Created by Maurits van Beusekom on 07/08/2018.
6+
//
7+
8+
import Foundation
9+
10+
class UnknownPermissionStrategy : NSObject, PermissionStrategy {
11+
func checkPermissionStatus(permission: PermissionGroup) -> PermissionStatus {
12+
return PermissionStatus.unknown
13+
}
14+
15+
func requestPermission(permission: PermissionGroup, completionHandler: @escaping PermissionStatusHandler) {
16+
completionHandler(PermissionStatus.unknown)
17+
}
18+
}

0 commit comments

Comments
 (0)