flet-permission-handler 0.1.0.dev1__py3-none-any.whl → 0.2.0.dev34__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flet-permission-handler might be problematic. Click here for more details.

@@ -1,5 +1,2 @@
1
- from flet_permission_handler.permission_handler import (
2
- PermissionHandler,
3
- PermissionStatus,
4
- PermissionType,
5
- )
1
+ from .permission_handler import PermissionHandler
2
+ from .types import Permission, PermissionStatus
@@ -1,143 +1,89 @@
1
- from enum import Enum
2
- from typing import Any, Optional
1
+ from typing import Optional
3
2
 
4
- from flet.core.control import Control
5
- from flet.core.ref import Ref
3
+ import flet as ft
6
4
 
5
+ from .types import Permission, PermissionStatus
7
6
 
8
- class PermissionStatus(Enum):
9
- GRANTED = "granted"
10
- DENIED = "denied"
11
- PERMANENTLY_DENIED = "permanentlyDenied"
12
- LIMITED = "limited"
13
- PROVISIONAL = "provisional"
14
- RESTRICTED = "restricted"
7
+ __all__ = ["PermissionHandler"]
15
8
 
16
9
 
17
- class PermissionType(Enum):
18
- ACCESS_MEDIA_LOCATION = "accessMediaLocation"
19
- ACCESS_NOTIFICATION_POLICY = "accessNotificationPolicy"
20
- ACTIVITY_RECOGNITION = "activityRecognition"
21
- APP_TRACKING_TRANSPARENCY = "appTrackingTransparency"
22
- ASSISTANT = "assistant"
23
- AUDIO = "audio"
24
- BACKGROUND_REFRESH = "backgroundRefresh"
25
- BLUETOOTH = "bluetooth"
26
- BLUETOOTH_ADVERTISE = "bluetoothAdvertise"
27
- BLUETOOTH_CONNECT = "bluetoothConnect"
28
- BLUETOOTH_SCAN = "bluetoothScan"
29
- CALENDAR_FULL_ACCESS = "calendarFullAccess"
30
- CALENDAR_WRITE_ONLY = "calendarWriteOnly"
31
- CAMERA = "camera"
32
- CONTACTS = "contacts"
33
- CRITICAL_ALERTS = "criticalAlerts"
34
- IGNORE_BATTERY_OPTIMIZATIONS = "ignoreBatteryOptimizations"
35
- LOCATION = "location"
36
- LOCATION_ALWAYS = "locationAlways"
37
- LOCATION_WHEN_IN_USE = "locationWhenInUse"
38
- MANAGE_EXTERNAL_STORAGE = "manageExternalStorage"
39
- MEDIA_LIBRARY = "mediaLibrary"
40
- MICROPHONE = "microphone"
41
- NEARBY_WIFI_DEVICES = "nearbyWifiDevices"
42
- NOTIFICATION = "notification"
43
- PHONE = "phone"
44
- PHOTOS = "photos"
45
- PHOTOS_ADD_ONLY = "photosAddOnly"
46
- REMINDERS = "reminders"
47
- REQUEST_INSTALL_PACKAGES = "requestInstallPackages"
48
- SCHEDULE_EXACT_ALARM = "scheduleExactAlarm"
49
- SENSORS = "sensors"
50
- SENSORS_ALWAYS = "sensorsAlways"
51
- SMS = "sms"
52
- SPEECH = "speech"
53
- STORAGE = "storage"
54
- SYSTEM_ALERT_WINDOW = "systemAlertWindow"
55
- UNKNOWN = "unknown"
56
- VIDEOS = "videos"
57
-
58
-
59
- class PermissionHandler(Control):
10
+ @ft.control("PermissionHandler")
11
+ class PermissionHandler(ft.Service):
60
12
  """
61
- A control that allows you check and request permission from your device.
62
- This control is non-visual and should be added to `page.overlay` list.
13
+ Manages permissions for the application.
63
14
 
64
- -----
15
+ This control is non-visual and should be added to `Page.services` list.
65
16
 
66
- Online docs: https://flet.dev/docs/controls/permissionhandler
17
+ Note:
18
+ Currently only supported on Android, iOS, Windows, and Web platforms.
19
+ Raises:
20
+ FletUnsupportedPlatformException: If the platform is not supported.
67
21
  """
68
22
 
69
- def __init__(
70
- self,
71
- # Control
72
- #
73
- ref: Optional[Ref] = None,
74
- data: Any = None,
75
- ):
76
- Control.__init__(
77
- self,
78
- ref=ref,
79
- data=data,
80
- )
81
-
82
- def _get_control_name(self):
83
- return "permission_handler"
84
-
85
- def check_permission(
86
- self, of: PermissionType, wait_timeout: Optional[float] = 25
87
- ) -> Optional[PermissionStatus]:
88
- out = self.invoke_method(
89
- "check_permission",
90
- {"of": of.value if isinstance(of, PermissionType) else of},
91
- wait_for_result=True,
92
- wait_timeout=wait_timeout,
93
- )
94
- return PermissionStatus(out) if out is not None else None
95
-
96
- async def check_permission_async(
97
- self, of: PermissionType, wait_timeout: Optional[float] = 25
23
+ def before_update(self):
24
+ super().before_update()
25
+
26
+ # validate platform
27
+ if not (
28
+ self.page.web
29
+ or self.page.platform
30
+ in [
31
+ ft.PagePlatform.ANDROID,
32
+ ft.PagePlatform.IOS,
33
+ ft.PagePlatform.WINDOWS,
34
+ ]
35
+ ):
36
+ raise ft.FletUnsupportedPlatformException(
37
+ "PermissionHandler is currently only supported on Android, iOS, Windows, and Web platforms."
38
+ )
39
+
40
+ async def get_status_async(
41
+ self, permission: Permission, timeout: int = 10
98
42
  ) -> Optional[PermissionStatus]:
99
- out = await self.invoke_method_async(
100
- "check_permission",
101
- {"of": of.value if isinstance(of, PermissionType) else of},
102
- wait_for_result=True,
103
- wait_timeout=wait_timeout,
43
+ """
44
+ Gets the current status of the given `permission`.
45
+
46
+ Args:
47
+ permission: The `Permission` to check the status for.
48
+ timeout: The maximum amount of time (in seconds) to wait for a response.
49
+ Returns:
50
+ A `PermissionStatus` if the status is known, otherwise `None`.
51
+ Raises:
52
+ TimeoutError: If the request times out.
53
+ """
54
+ status = await self._invoke_method_async(
55
+ "get_status", {"permission": permission}, timeout=timeout
104
56
  )
105
- return PermissionStatus(out) if out is not None else None
57
+ return PermissionStatus(status) if status is not None else None
106
58
 
107
- def request_permission(
108
- self, of: PermissionType, wait_timeout: Optional[float] = 25
59
+ async def request_async(
60
+ self, permission: Permission, timeout: int = 60
109
61
  ) -> Optional[PermissionStatus]:
110
- out = self.invoke_method(
111
- "request_permission",
112
- {"of": of.value if isinstance(of, PermissionType) else of},
113
- wait_for_result=True,
114
- wait_timeout=wait_timeout,
115
- )
116
- return PermissionStatus(out) if out is not None else None
117
-
118
- async def request_permission_async(
119
- self, of: PermissionType, wait_timeout: Optional[float] = 25
120
- ) -> Optional[PermissionStatus]:
121
- out = await self.invoke_method_async(
122
- "request_permission",
123
- {"of": of.value if isinstance(of, PermissionType) else of},
124
- wait_for_result=True,
125
- wait_timeout=wait_timeout,
126
- )
127
- return PermissionStatus(out) if out is not None else None
128
-
129
- def open_app_settings(self, wait_timeout: Optional[float] = 10) -> bool:
130
- opened = self.invoke_method(
131
- "open_app_settings",
132
- wait_for_result=True,
133
- wait_timeout=wait_timeout,
134
- )
135
- return opened == "true"
136
-
137
- async def open_app_settings_async(self, wait_timeout: Optional[float] = 10) -> bool:
138
- opened = await self.invoke_method_async(
139
- "open_app_settings",
140
- wait_for_result=True,
141
- wait_timeout=wait_timeout,
62
+ """
63
+ Request the user for access to the `permission` if access hasn't already been granted access before.
64
+
65
+ Args:
66
+ permission: The `Permission` to request.
67
+ timeout: The maximum amount of time (in seconds) to wait for a response.
68
+ Returns:
69
+ The new `PermissionStatus` after the request, or `None` if the request was not successful.
70
+ Raises:
71
+ TimeoutError: If the request times out.
72
+ """
73
+ r = await self._invoke_method_async(
74
+ "request", {"permission": permission}, timeout=timeout
142
75
  )
143
- return opened == "true"
76
+ return PermissionStatus(r) if r is not None else None
77
+
78
+ async def open_app_settings_async(self, timeout: int = 10) -> bool:
79
+ """
80
+ Opens the app settings page.
81
+
82
+ Args:
83
+ timeout: The maximum amount of time (in seconds) to wait for a response.
84
+ Returns:
85
+ `True` if the app settings page could be opened, otherwise `False`.
86
+ Raises:
87
+ TimeoutError: If the request times out.
88
+ """
89
+ return await self._invoke_method_async("open_app_settings", timeout=timeout)
@@ -0,0 +1,411 @@
1
+ from enum import Enum
2
+
3
+ __all__ = [
4
+ "PermissionStatus",
5
+ "Permission",
6
+ ]
7
+
8
+
9
+ class PermissionStatus(Enum):
10
+ """Defines the state of a [`Permission`][(p).]."""
11
+
12
+ GRANTED = "granted"
13
+ """
14
+ The user granted access to the requested feature.
15
+ """
16
+
17
+ DENIED = "denied"
18
+ """
19
+ The user denied access to the requested feature, permission needs to be asked first.
20
+ """
21
+
22
+ PERMANENTLY_DENIED = "permanentlyDenied"
23
+ """
24
+ Permission to the requested feature is permanently denied,
25
+ the permission dialog will not be shown when requesting this permission.
26
+ The user may still change the permission status in the settings.
27
+
28
+ Note:
29
+ - On Android:
30
+ - Android 11+ (API 30+): whether the user denied the permission for a second time.
31
+
32
+ - Below Android 11 (API 30): whether the user denied access
33
+ to the requested feature and selected to never again show a request.
34
+ - On iOS: If the user has denied access to the requested feature.
35
+ """
36
+
37
+ LIMITED = "limited"
38
+ """
39
+ The user has authorized this application for limited access. So far this is only relevant for the Photo Library picker.
40
+
41
+ Note:
42
+ Only supported on iOS (iOS14+) and Android (Android 14+).
43
+ """
44
+
45
+ PROVISIONAL = "provisional"
46
+ """
47
+ The application is provisionally authorized to post non-interruptive user notifications.
48
+
49
+ Note:
50
+ Only supported on iOS (iOS 12+).
51
+ """
52
+
53
+ RESTRICTED = "restricted"
54
+ """
55
+ The OS denied access to the requested feature. The user cannot change this app's status, possibly due to active restrictions such as parental controls being in place.
56
+
57
+ Note:
58
+ Only supported on iOS.
59
+ """
60
+
61
+
62
+ # todo: show how pyproject config for each could look like for each permission (what exactly is needed in manifest, plist, etc.)
63
+
64
+
65
+ class Permission(Enum):
66
+ """Defines the permissions which can be checked and requested."""
67
+
68
+ ACCESS_MEDIA_LOCATION = "accessMediaLocation"
69
+ """
70
+ Permission for accessing the device's media library.
71
+
72
+ Allows an application to access any geographic locations persisted in the
73
+ user's shared collection.
74
+
75
+ Note:
76
+ Only supported on Android 10+ (API 29+) only.
77
+ """
78
+
79
+ ACCESS_NOTIFICATION_POLICY = "accessNotificationPolicy"
80
+ """
81
+ Permission for accessing the device's notification policy.
82
+
83
+ Allows the user to access the notification policy of the phone.
84
+ Example: Allows app to turn on and off do-not-disturb.
85
+
86
+ Note:
87
+ Only supported on Android Marshmallow+ (API 23+) only.
88
+ """
89
+
90
+ ACTIVITY_RECOGNITION = "activityRecognition"
91
+ """
92
+ Permission for accessing the activity recognition.
93
+
94
+ Note:
95
+ Only supported on Android 10+ (API 29+) only.
96
+ """
97
+
98
+ APP_TRACKING_TRANSPARENCY = "appTrackingTransparency"
99
+ """
100
+ Permission for accessing the device's tracking state.
101
+ Allows user to accept that your app collects data about end users and
102
+ shares it with other companies for purposes of tracking across apps and
103
+ websites.
104
+
105
+ Note:
106
+ Only supported on iOS only.
107
+ """
108
+
109
+ ASSISTANT = "assistant"
110
+ """
111
+ Info:
112
+ - Android: Nothing
113
+ - iOS: SiriKit
114
+ """
115
+
116
+ AUDIO = "audio"
117
+ """
118
+ Permission for accessing the device's audio files from external storage.
119
+
120
+ Note:
121
+ Only supported on Android 13+ (API 33+) only.
122
+ """
123
+
124
+ BACKGROUND_REFRESH = "backgroundRefresh"
125
+ """
126
+ Permission for reading the current background refresh status.
127
+
128
+ Note:
129
+ Only supported on iOS only.
130
+ """
131
+
132
+ BLUETOOTH = "bluetooth"
133
+ """
134
+ Permission for accessing the device's bluetooth adapter state.
135
+
136
+ Depending on the platform and version, the requirements are slightly different:
137
+
138
+ Info:
139
+ - Android: always allowed.
140
+ - iOS:
141
+ - 13 and above: The authorization state of Core Bluetooth manager.
142
+ - below 13: always allowed.
143
+ """
144
+
145
+ BLUETOOTH_ADVERTISE = "bluetoothAdvertise"
146
+ """
147
+ Permission for advertising Bluetooth devices
148
+ Allows the user to make this device discoverable to other Bluetooth devices.
149
+
150
+ Note:
151
+ Only supported on Android 12+ (API 31+) only.
152
+ """
153
+
154
+ BLUETOOTH_CONNECT = "bluetoothConnect"
155
+ """
156
+ Permission for connecting to Bluetooth devices.
157
+ Allows the user to connect with already paired Bluetooth devices.
158
+
159
+ Note:
160
+ Only supported on Android 12+ (API 31+) only.
161
+ """
162
+
163
+ BLUETOOTH_SCAN = "bluetoothScan"
164
+ """
165
+ Permission for scanning for Bluetooth devices.
166
+
167
+ Note:
168
+ Only supported on Android 12+ (API 31+) only.
169
+ """
170
+
171
+ CALENDAR_FULL_ACCESS = "calendarFullAccess"
172
+ """
173
+ Permission for reading from and writing to the device's calendar.
174
+ """
175
+
176
+ CALENDAR_WRITE_ONLY = "calendarWriteOnly"
177
+ """
178
+ Permission for writing to the device's calendar.
179
+
180
+ On iOS 16 and lower, this permission is identical to `Permission.CALENDAR_FULL_ACCESS`.
181
+ """
182
+
183
+ CAMERA = "camera"
184
+ """
185
+ Permission for accessing the device's camera.
186
+
187
+ Info:
188
+ - Android: Camera
189
+ - iOS: Photos (Camera Roll and Camera)
190
+ """
191
+
192
+ CONTACTS = "contacts"
193
+ """
194
+ Permission for accessing the device's contacts.
195
+
196
+ Info:
197
+ - Android: Contacts
198
+ - iOS: AddressBook
199
+ """
200
+
201
+ CRITICAL_ALERTS = "criticalAlerts"
202
+ """
203
+ Permission for sending critical alerts.
204
+ Allow for sending notifications that override the ringer.
205
+
206
+ Note:
207
+ Only supported on iOS only.
208
+ """
209
+
210
+ IGNORE_BATTERY_OPTIMIZATIONS = "ignoreBatteryOptimizations"
211
+ """
212
+ Permission for accessing ignore battery optimizations.
213
+
214
+ Note:
215
+ Only supported on Android only.
216
+ """
217
+
218
+ LOCATION = "location"
219
+ """
220
+ Permission for accessing the device's location.
221
+
222
+ Info:
223
+ - Android: Fine and Coarse Location
224
+ - iOS: CoreLocation (Always and WhenInUse)
225
+ """
226
+
227
+ LOCATION_ALWAYS = "locationAlways"
228
+ """
229
+ Info:
230
+ iOS: CoreLocation (Always)
231
+ """
232
+
233
+ LOCATION_WHEN_IN_USE = "locationWhenInUse"
234
+ """
235
+ Permission for accessing the device's location when the app is running in the foreground.
236
+
237
+ Info:
238
+ - Android: Fine and Coarse Location
239
+ - iOS: CoreLocation - WhenInUse
240
+ """
241
+
242
+ MANAGE_EXTERNAL_STORAGE = "manageExternalStorage"
243
+ """
244
+ Permission for accessing the device's external storage.
245
+ Allows an application a broad access to external storage in scoped storage.
246
+
247
+ You should request this permission only when your app cannot
248
+ effectively make use of the more privacy-friendly APIs.
249
+ For more information: https://developer.android.com/training/data-storage/manage-all-files
250
+
251
+ Info:
252
+ When the privacy-friendly APIs (i.e. [Storage Access Framework](https://developer.android.com/guide/topics/providers/document-provider)
253
+ or the [MediaStore](https://developer.android.com/training/data-storage/shared/media) APIs)
254
+ is all your app needs, the [PermissionGroup.storage] are the only
255
+ permissions you need to request.
256
+
257
+ If the usage of this permission is needed, you have to fill out
258
+ the Permission Declaration Form upon submitting your app to the Google Play Store.
259
+ More details: https://support.google.com/googleplay/android-developer/answer/9214102#zippy=
260
+
261
+ Note:
262
+ Only supported on Android 11+ (API 30+) only.
263
+ """
264
+
265
+ MEDIA_LIBRARY = "mediaLibrary"
266
+ """
267
+ Permission for accessing the device's media library.
268
+
269
+ Note:
270
+ Only supported on iOS 9.3+ only
271
+ """
272
+
273
+ MICROPHONE = "microphone"
274
+ """
275
+ Permission for accessing the device's microphone.
276
+ """
277
+
278
+ NEARBY_WIFI_DEVICES = "nearbyWifiDevices"
279
+ """
280
+ Permission for connecting to nearby devices via Wi-Fi.
281
+
282
+ Note:
283
+ Only supported on Android 13+ (API 33+) only.
284
+ """
285
+
286
+ NOTIFICATION = "notification"
287
+ """
288
+ Permission for pushing notifications.
289
+ """
290
+
291
+ PHONE = "phone"
292
+ """
293
+ Permission for accessing the device's phone state.
294
+
295
+ Note:
296
+ Only supported on Android only.
297
+ """
298
+
299
+ PHOTOS = "photos"
300
+ """
301
+ Permission for accessing (read & write) the device's photos.
302
+
303
+ If you only want to add photos, you can use
304
+ the `PHOTOS_ADD_ONLY` permission instead (iOS only).
305
+ """
306
+
307
+ PHOTOS_ADD_ONLY = "photosAddOnly"
308
+ """
309
+ Permission for adding photos to the device's photo library (iOS only).
310
+
311
+ If you want to read them as well, use the `Permission.PHOTOS` permission instead.
312
+
313
+ Info:
314
+ iOS: Photos (14+ read & write access level)
315
+ """
316
+
317
+ REMINDERS = "reminders"
318
+ """
319
+ Permission for accessing the device's reminders.
320
+
321
+ Note:
322
+ Only supported on iOS only.
323
+ """
324
+
325
+ REQUEST_INSTALL_PACKAGES = "requestInstallPackages"
326
+ """
327
+ Permission for requesting installing packages.
328
+
329
+ Note:
330
+ Only supported on Android Marshmallow+ (API 23+) only.
331
+ """
332
+
333
+ SCHEDULE_EXACT_ALARM = "scheduleExactAlarm"
334
+ """
335
+ Permission for scheduling exact alarms.
336
+
337
+ Note:
338
+ Only supported on Android 12+ (API 31+) only.
339
+ """
340
+
341
+ SENSORS = "sensors"
342
+ """
343
+ Permission for accessing the device's sensors.
344
+
345
+ Info:
346
+ - Android: Body Sensors
347
+ - iOS: CoreMotion
348
+ """
349
+
350
+ SENSORS_ALWAYS = "sensorsAlways"
351
+ """
352
+ Permission for accessing the device's sensors in background.
353
+
354
+ Note:
355
+ Only supported on Android 13+ (API 33+) only.
356
+ """
357
+
358
+ SMS = "sms"
359
+ """
360
+ Permission for sending and reading SMS messages (Android only).
361
+ """
362
+
363
+ SPEECH = "speech"
364
+ """
365
+ Permission for accessing speech recognition.
366
+
367
+ Info:
368
+ - Android: Requests access to microphone (identical to requesting `Permission.MICROPHONE`).
369
+ - iOS: Requests speech access (different from requesting `Permission.MICROPHONE`).
370
+ """
371
+
372
+ STORAGE = "storage"
373
+ """
374
+ Permission for accessing external storage.
375
+
376
+ Depending on the platform and version, the requirements are slightly different:
377
+
378
+ Info:
379
+ - Android:
380
+ - On Android 13 (API 33) and above, this permission is deprecated and
381
+ always returns `PermissionStatus.denied`. Instead use `Permission.PHOTOS`,
382
+ `Permission.VIDEO`, `Permission.AUDIO` or `Permission.MANAGE_EXTERNAL_STORAGE`.
383
+ For more information see [this](https://pub.dev/packages/permission_handler#faq).
384
+
385
+ - Below Android 13 (API 33), the `READ_EXTERNAL_STORAGE` and
386
+ `WRITE_EXTERNAL_STORAGE` permissions are requested (depending on the
387
+ definitions in the AndroidManifest.xml) file.
388
+ - iOS: Access to folders like `Documents` or `Downloads`. Implicitly granted.
389
+ """
390
+
391
+ SYSTEM_ALERT_WINDOW = "systemAlertWindow"
392
+ """
393
+ Permission for creating system alert window.
394
+ Allows an app to create windows shown on top of all other apps.
395
+
396
+ Note:
397
+ Only supported on Android only.
398
+ """
399
+
400
+ UNKNOWN = "unknown"
401
+ """
402
+ The unknown only used for return type, never requested.
403
+ """
404
+
405
+ VIDEOS = "videos"
406
+ """
407
+ Permission for accessing the device's video files from external storage.
408
+
409
+ Note:
410
+ Only supported on Android 13+ (API 33+) only.
411
+ """