android-notify 1.61.3.dev0__tar.gz → 1.61.4__tar.gz

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.
Files changed (55) hide show
  1. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/PKG-INFO +23 -62
  2. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/README.md +22 -61
  3. android_notify-1.61.4/android_notify/__main__.py +75 -0
  4. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/config.py +33 -4
  5. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/core.py +6 -9
  6. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/channels.py +1 -1
  7. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/facade.py +2 -4
  8. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/helper.py +0 -4
  9. android_notify-1.61.4/android_notify/internal/java_classes.py +85 -0
  10. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/permissions.py +46 -15
  11. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/basic/src/core.py +2 -2
  12. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/flet-working/src/core.py +2 -2
  13. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/main.py +1 -1
  14. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/widgets/images.py +4 -5
  15. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/widgets/texts.py +1 -5
  16. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/PKG-INFO +23 -62
  17. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/pyproject.toml +1 -2
  18. android_notify-1.61.3.dev0/android_notify/__main__.py +0 -24
  19. android_notify-1.61.3.dev0/android_notify/internal/java_classes.py +0 -69
  20. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/__init__.py +0 -0
  21. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/base.py +0 -0
  22. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/fallback-icons/flet-appicon.png +0 -0
  23. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/fallback-icons/pydroid3-appicon.png +0 -0
  24. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/an_types.py +0 -0
  25. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/android.py +0 -0
  26. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/intents.py +0 -0
  27. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/logger.py +0 -0
  28. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/styles.py +0 -0
  29. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/sword.py +0 -0
  30. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/__init__.py +0 -0
  31. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/android_notify_test.py +0 -0
  32. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/base_test.py +0 -0
  33. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/adv/main.py +0 -0
  34. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/adv/tests/__init__.py +0 -0
  35. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/adv/tests/test_android_notify_full.py +0 -0
  36. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/basic/src/main.py +0 -0
  37. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/flet-working/src/main.py +0 -0
  38. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/p4a/hook.py +0 -0
  39. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/serivces/wallpaper.py +0 -0
  40. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_basic_notifications.py +0 -0
  41. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_actions.py +0 -0
  42. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_appearance.py +0 -0
  43. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_behavior.py +0 -0
  44. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_channels.py +0 -0
  45. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_clear.py +0 -0
  46. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_permission.py +0 -0
  47. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_progress.py +0 -0
  48. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_sound.py +0 -0
  49. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_styles.py +0 -0
  50. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/SOURCES.txt +0 -0
  51. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/dependency_links.txt +0 -0
  52. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/entry_points.txt +0 -0
  53. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/requires.txt +0 -0
  54. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/top_level.txt +0 -0
  55. {android_notify-1.61.3.dev0 → android_notify-1.61.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: android-notify
3
- Version: 1.61.3.dev0
3
+ Version: 1.61.4
4
4
  Summary: A Python package that simplifies creating Android notifications in Kivy and Flet apps.
5
5
  Author-email: Fabian <fector101@yahoo.com>
6
6
  License-Expression: MIT
@@ -53,6 +53,8 @@ The Android Notify package provides a simple yet comprehensive way to create and
53
53
  - Persistent notifications
54
54
  - Click handlers and callbacks
55
55
  - Cancel Notifications
56
+ - Use [Custom Sound](https://android-notify.vercel.app/advanced-methods#custom-sound)
57
+ - Vibration [section](https://android-notify.vercel.app/advanced-methods#vibration)
56
58
 
57
59
  ## Quick Start
58
60
 
@@ -80,14 +82,13 @@ In your **`buildozer.spec`** file, ensure you include the following:
80
82
 
81
83
  ```ini
82
84
  # Add pyjnius so ensure it's packaged with the build
83
- requirements = python3, kivy, pyjnius, android-notify==1.61.3.dev0
85
+ requirements = python3, kivy, pyjnius, android-notify
84
86
  # Add permission for notifications
85
87
  android.permissions = POST_NOTIFICATIONS
86
88
  ```
87
89
 
88
90
  </details>
89
91
 
90
-
91
92
  <details>
92
93
  <summary><b>Flet apps:</b></summary>
93
94
  <br/>
@@ -98,7 +99,7 @@ In your `pyproject.toml` file, ensure you include the following:
98
99
  ```toml
99
100
  [tool.flet.android]
100
101
  dependencies = [
101
- "pyjnius","android-notify==1.61.3.dev0"
102
+ "pyjnius","android-notify"
102
103
  ]
103
104
 
104
105
  [tool.flet.android.permission]
@@ -108,23 +109,19 @@ dependencies = [
108
109
 
109
110
  </details>
110
111
 
111
-
112
-
113
112
  <details>
114
113
 
115
114
  <summary><b>On Pydroid 3</b></summary>
116
115
  <br/>
117
116
 
118
117
  On the [pydroid 3](https://play.google.com/store/apps/details?id=ru.iiec.pydroid3) mobile app for running python code you can test some features.
119
- - In pip section where you're asked to insert `Libary name` paste `android-notify==1.61.3.dev0`
118
+ - In pip section where you're asked to insert `Libary name` paste `android-notify`
120
119
  - Minimal working example
121
120
  ```py
122
- # Testing with `android-notify==1.61.3.dev0` on pydroid
123
121
  from kivy.app import App
124
122
  from kivy.uix.boxlayout import BoxLayout
125
123
  from kivy.uix.button import Button
126
- from android_notify import Notification
127
- from android_notify.core import asks_permission_if_needed
124
+ from android_notify import Notification, NotificationHandler
128
125
 
129
126
 
130
127
  class AndroidNotifyDemoApp(App):
@@ -146,9 +143,7 @@ class AndroidNotifyDemoApp(App):
146
143
  def send_notification(self, *args):
147
144
  Notification(
148
145
  title="Hello from Android Notify",
149
- message="This is a basic notification.",
150
- channel_id="android_notify_demo",
151
- channel_name="Android Notify Demo"
146
+ message="This is a basic notification."
152
147
  ).send()
153
148
 
154
149
 
@@ -173,38 +168,11 @@ android-notify -v
173
168
  </details>
174
169
 
175
170
  ## Documentation
176
- For Dev Version use
171
+ For Dev Version usage
177
172
  ```ini
178
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
173
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
179
174
  ```
180
175
 
181
- <details>
182
- <summary> <b> To talk to BroadCast Listener From Buttons </b> </summary>
183
-
184
- - Make things happen without being in your app
185
- ```python
186
- from android_notify import Notification
187
- notification = Notification(title="Receiver Notification")
188
- notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
189
- notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
190
- ```
191
- You can use this [wiki](https://github.com/Fector101/android_notify/wiki/How-to-Use-with-Broadcast-Listener) as a guide create a broadcast listener
192
- </details>
193
-
194
- <details>
195
- <summary> <b> To use colored text in your notifications </b> </summary>
196
-
197
- - Copy the [res](https://github.com/Fector101/android_notify/tree/main/android_notify/res) folder to your app path.
198
- - Lastly in your `buildozer.spec` file
199
- Add `source.include_exts = xml` and `android.add_resources = # path you pasted`
200
- ```python
201
- # Use Hex Code to be Safe
202
- n = Notification(title="Title and Message Color", message="Testing",title_color="red")
203
- n.send()
204
- ```
205
-
206
- </details>
207
-
208
176
  <details>
209
177
  <summary> <b>To use Custom Sounds </b> </summary>
210
178
 
@@ -267,26 +235,6 @@ Private files (e.g., in app's `data/` directory) are automatically copied to ext
267
235
  </details>
268
236
 
269
237
 
270
- <details>
271
- <summary> <b> Vibrate feature</b> </summary>
272
-
273
- ```ini
274
- # buildozer.spec
275
- android.permissions = VIBRATE
276
- ```
277
-
278
- ```python
279
- Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
280
-
281
- n=Notification(title='Vibrate',channel_id='shake')
282
- n.setVibrate() # for less than android 8
283
- n.fVibrate() # To Force Vibrate (when user turned off in settings)
284
- n.send()
285
- ```
286
-
287
- </details>
288
-
289
-
290
238
  <details>
291
239
  <summary> <b> Add Data to Notification</b> </summary>
292
240
 
@@ -324,3 +272,16 @@ Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify
324
272
  <a href="https://www.buymeacoffee.com/fector101" target="_blank">
325
273
  <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
326
274
  </a>
275
+
276
+ ## Bug Reports & Feature Requests
277
+
278
+ Found a bug or have an idea for a new feature?
279
+ Feel free to open an issue [here](https://reference-url-citation.invalid/0)
280
+
281
+ When reporting a bug, try to include:
282
+ - Device name
283
+ - Android version
284
+ - Steps to reproduce the issue
285
+ - Screenshots or logs (if possible)
286
+
287
+ Feature suggestions are also welcome.
@@ -31,6 +31,8 @@ The Android Notify package provides a simple yet comprehensive way to create and
31
31
  - Persistent notifications
32
32
  - Click handlers and callbacks
33
33
  - Cancel Notifications
34
+ - Use [Custom Sound](https://android-notify.vercel.app/advanced-methods#custom-sound)
35
+ - Vibration [section](https://android-notify.vercel.app/advanced-methods#vibration)
34
36
 
35
37
  ## Quick Start
36
38
 
@@ -58,14 +60,13 @@ In your **`buildozer.spec`** file, ensure you include the following:
58
60
 
59
61
  ```ini
60
62
  # Add pyjnius so ensure it's packaged with the build
61
- requirements = python3, kivy, pyjnius, android-notify==1.61.3.dev0
63
+ requirements = python3, kivy, pyjnius, android-notify
62
64
  # Add permission for notifications
63
65
  android.permissions = POST_NOTIFICATIONS
64
66
  ```
65
67
 
66
68
  </details>
67
69
 
68
-
69
70
  <details>
70
71
  <summary><b>Flet apps:</b></summary>
71
72
  <br/>
@@ -76,7 +77,7 @@ In your `pyproject.toml` file, ensure you include the following:
76
77
  ```toml
77
78
  [tool.flet.android]
78
79
  dependencies = [
79
- "pyjnius","android-notify==1.61.3.dev0"
80
+ "pyjnius","android-notify"
80
81
  ]
81
82
 
82
83
  [tool.flet.android.permission]
@@ -86,23 +87,19 @@ dependencies = [
86
87
 
87
88
  </details>
88
89
 
89
-
90
-
91
90
  <details>
92
91
 
93
92
  <summary><b>On Pydroid 3</b></summary>
94
93
  <br/>
95
94
 
96
95
  On the [pydroid 3](https://play.google.com/store/apps/details?id=ru.iiec.pydroid3) mobile app for running python code you can test some features.
97
- - In pip section where you're asked to insert `Libary name` paste `android-notify==1.61.3.dev0`
96
+ - In pip section where you're asked to insert `Libary name` paste `android-notify`
98
97
  - Minimal working example
99
98
  ```py
100
- # Testing with `android-notify==1.61.3.dev0` on pydroid
101
99
  from kivy.app import App
102
100
  from kivy.uix.boxlayout import BoxLayout
103
101
  from kivy.uix.button import Button
104
- from android_notify import Notification
105
- from android_notify.core import asks_permission_if_needed
102
+ from android_notify import Notification, NotificationHandler
106
103
 
107
104
 
108
105
  class AndroidNotifyDemoApp(App):
@@ -124,9 +121,7 @@ class AndroidNotifyDemoApp(App):
124
121
  def send_notification(self, *args):
125
122
  Notification(
126
123
  title="Hello from Android Notify",
127
- message="This is a basic notification.",
128
- channel_id="android_notify_demo",
129
- channel_name="Android Notify Demo"
124
+ message="This is a basic notification."
130
125
  ).send()
131
126
 
132
127
 
@@ -151,38 +146,11 @@ android-notify -v
151
146
  </details>
152
147
 
153
148
  ## Documentation
154
- For Dev Version use
149
+ For Dev Version usage
155
150
  ```ini
156
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
151
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
157
152
  ```
158
153
 
159
- <details>
160
- <summary> <b> To talk to BroadCast Listener From Buttons </b> </summary>
161
-
162
- - Make things happen without being in your app
163
- ```python
164
- from android_notify import Notification
165
- notification = Notification(title="Receiver Notification")
166
- notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
167
- notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
168
- ```
169
- You can use this [wiki](https://github.com/Fector101/android_notify/wiki/How-to-Use-with-Broadcast-Listener) as a guide create a broadcast listener
170
- </details>
171
-
172
- <details>
173
- <summary> <b> To use colored text in your notifications </b> </summary>
174
-
175
- - Copy the [res](https://github.com/Fector101/android_notify/tree/main/android_notify/res) folder to your app path.
176
- - Lastly in your `buildozer.spec` file
177
- Add `source.include_exts = xml` and `android.add_resources = # path you pasted`
178
- ```python
179
- # Use Hex Code to be Safe
180
- n = Notification(title="Title and Message Color", message="Testing",title_color="red")
181
- n.send()
182
- ```
183
-
184
- </details>
185
-
186
154
  <details>
187
155
  <summary> <b>To use Custom Sounds </b> </summary>
188
156
 
@@ -245,26 +213,6 @@ Private files (e.g., in app's `data/` directory) are automatically copied to ext
245
213
  </details>
246
214
 
247
215
 
248
- <details>
249
- <summary> <b> Vibrate feature</b> </summary>
250
-
251
- ```ini
252
- # buildozer.spec
253
- android.permissions = VIBRATE
254
- ```
255
-
256
- ```python
257
- Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
258
-
259
- n=Notification(title='Vibrate',channel_id='shake')
260
- n.setVibrate() # for less than android 8
261
- n.fVibrate() # To Force Vibrate (when user turned off in settings)
262
- n.send()
263
- ```
264
-
265
- </details>
266
-
267
-
268
216
  <details>
269
217
  <summary> <b> Add Data to Notification</b> </summary>
270
218
 
@@ -302,3 +250,16 @@ Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify
302
250
  <a href="https://www.buymeacoffee.com/fector101" target="_blank">
303
251
  <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
304
252
  </a>
253
+
254
+ ## Bug Reports & Feature Requests
255
+
256
+ Found a bug or have an idea for a new feature?
257
+ Feel free to open an issue [here](https://reference-url-citation.invalid/0)
258
+
259
+ When reporting a bug, try to include:
260
+ - Device name
261
+ - Android version
262
+ - Steps to reproduce the issue
263
+ - Screenshots or logs (if possible)
264
+
265
+ Feature suggestions are also welcome.
@@ -0,0 +1,75 @@
1
+ import argparse
2
+ import os
3
+ import shutil
4
+ from .config import __version__
5
+
6
+ BUILD_PATHS = [
7
+ os.path.join(".buildozer", "android", "platform", "build-arm64-v8a_armeabi-v7a", "build", "python-installs"),
8
+ os.path.join(".buildozer", "android", "platform", "build-arm64-v8a_armeabi-v7a", "dists"),
9
+ # ".buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/python-installs",
10
+ # ".buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists",
11
+ ]
12
+
13
+ def print_version():
14
+ text = f"android_notify: v{__version__}"
15
+ border = '+'+'-'*(len(text) + 2)+'+'
16
+ print(border)
17
+ print(f'| {text} |')
18
+ print(border)
19
+
20
+ def cmd_prune(args):
21
+ project_path = str(os.path.abspath(args.path))
22
+ items = []
23
+
24
+ for rel in BUILD_PATHS:
25
+ root = os.path.join(project_path, rel)
26
+ if not os.path.isdir(root):
27
+ continue
28
+ for dirpath, dir_names, filenames in os.walk(root):
29
+ for name in dir_names + filenames:
30
+ if name.startswith("android_notify"):
31
+ items.append(os.path.join(dirpath, name))
32
+
33
+ if not items:
34
+ print("No android_notify items found.")
35
+ return
36
+
37
+ print("\n=== android_notify items found ===")
38
+ for i, item in enumerate(items, 1):
39
+ print(f" {i}. {item}")
40
+ print("==================================\n")
41
+
42
+ ans = input("Delete these? (y/N) ").strip().lower()
43
+ if ans == "y":
44
+ items.sort(key=len, reverse=True)
45
+ for item in items:
46
+ if not os.path.exists(item):
47
+ continue
48
+ if os.path.isdir(item):
49
+ shutil.rmtree(item)
50
+ else:
51
+ os.remove(item)
52
+ print(f" Deleted: {item}")
53
+ print("Done.")
54
+ else:
55
+ print("Skipped.")
56
+
57
+ def main():
58
+ parser = argparse.ArgumentParser(description="Android Notify CLI")
59
+ parser.add_argument('-v', '--version', action='store_true', help="Show the version of android_notify")
60
+
61
+ subparsers = parser.add_subparsers(dest='command', help='Available commands')
62
+ prune_parser = subparsers.add_parser('prune', help='Remove old android_notify build artifacts from .buildozer')
63
+ prune_parser.add_argument('-p', '--path', default='.', help='Path to the project directory (default: current directory)')
64
+
65
+ args = parser.parse_args()
66
+
67
+ if args.version:
68
+ print_version()
69
+ elif args.command == 'prune':
70
+ cmd_prune(args)
71
+ elif args.command is None:
72
+ parser.print_help()
73
+
74
+ if __name__ == "__main__":
75
+ main()
@@ -1,12 +1,9 @@
1
1
  import os
2
2
 
3
- __version__ = "1.61.3.dev0"
3
+ __version__ = "1.61.4"
4
4
 
5
-
6
- from .internal.java_classes import autoclass, cast, NotificationManager
7
5
  from .internal.logger import logger
8
6
 
9
-
10
7
  def on_kivy_android():
11
8
  kivy_build = os.environ.get('KIVY_BUILD', '')
12
9
  if kivy_build in {'android'}:
@@ -27,6 +24,37 @@ def on_android_platform():
27
24
  return on_kivy_android() or on_flet_app()
28
25
 
29
26
 
27
+ if on_android_platform():
28
+ try:
29
+ from jnius import cast, autoclass
30
+ except ModuleNotFoundError:
31
+ cast = lambda x, y: x
32
+ autoclass = lambda x: None
33
+ else:
34
+ cast = lambda x, y: x
35
+ autoclass = lambda x: None
36
+
37
+
38
+ def on_pydroid_app():
39
+ package_name = "ru.iiec.pydroid3"
40
+ if package_name in os.environ.get("PYTHONHOME",""):
41
+ return True
42
+ elif package_name in os.path.dirname(os.path.abspath(__file__)):
43
+ return True
44
+ elif on_android_platform():
45
+ return package_name == get_package_name()
46
+ return False
47
+
48
+
49
+ def has_androidx_dependency():
50
+ """Check if androidx dependencies are available"""
51
+ try:
52
+ _=autoclass('androidx.core.app.NotificationCompat')
53
+ return True
54
+ except Exception:
55
+ return False
56
+
57
+
30
58
  def get_activity_class_name():
31
59
  ACTIVITY_CLASS_NAME = os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME") # flet python
32
60
  if not ACTIVITY_CLASS_NAME:
@@ -99,6 +127,7 @@ def get_notification_manager():
99
127
  if not on_android_platform():
100
128
  logger.warning("Can't get notification manager, Not on Android.")
101
129
  return None
130
+ NotificationManager = autoclass('android.app.NotificationManager')
102
131
 
103
132
  context = get_python_activity_context()
104
133
  notification_service = context.getSystemService(context.NOTIFICATION_SERVICE)
@@ -3,15 +3,12 @@ import random
3
3
  import os
4
4
 
5
5
  from android_notify.internal.logger import logger
6
- from android_notify.config import get_python_activity, on_android_platform, get_python_activity_context
6
+
7
+ from android_notify.config import get_python_activity, on_android_platform, get_python_activity_context, on_flet_app, on_pydroid_app
7
8
  from android_notify.internal.permissions import has_notification_permission, ask_notification_permission
8
9
  from android_notify.internal.java_classes import autoclass, BuildVersion, BitmapFactory, NotificationChannel, NotificationManagerCompat, NotificationCompat, NotificationCompatBuilder, \
9
- NotificationCompatBigTextStyle, NotificationCompatBigPictureStyle, NotificationCompatInboxStyle
10
-
11
-
10
+ NotificationCompatBigTextStyle, NotificationCompatBigPictureStyle, NotificationCompatInboxStyle, IconClass
12
11
 
13
- def on_flet_app():
14
- return os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME")
15
12
 
16
13
 
17
14
  if on_android_platform():
@@ -60,9 +57,8 @@ def get_image_uri(relative_path):
60
57
 
61
58
  def get_icon_object(uri):
62
59
  context = get_python_activity_context()
63
- IconCompat = autoclass('android.graphics.drawable.Icon')
64
60
  bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
65
- return IconCompat.createWithBitmap(bitmap)
61
+ return IconClass.createWithBitmap(bitmap)
66
62
 
67
63
 
68
64
  def insert_app_icon(builder, custom_icon_path):
@@ -115,7 +111,8 @@ def send_notification(
115
111
  return None
116
112
  context = get_python_activity_context()
117
113
 
118
- asks_permission_if_needed(legacy=True)
114
+ use_legacy = on_flet_app() or on_pydroid_app()
115
+ asks_permission_if_needed(legacy=use_legacy)
119
116
  channel_id = channel_name.replace(' ', '_').lower().lower() if not channel_id else channel_id
120
117
  # Get notification manager
121
118
  notification_manager = context.getSystemService(context.NOTIFICATION_SERVICE)
@@ -46,7 +46,7 @@ def create_channel(id__, name: str, description='', importance: Importance = 'ur
46
46
 
47
47
  notification_manager = get_notification_manager()
48
48
  android_importance_value = get_android_importance(importance)
49
-
49
+
50
50
  if sound_path:
51
51
  sound_uri = get_sound_uri_from_path(sound_path)
52
52
  else:
@@ -149,11 +149,9 @@ class File:
149
149
  logger.debug(f"[MOCK] File.getAbsolutePath called, returning {self.path}")
150
150
  return self.path
151
151
 
152
-
153
152
  class NotificationManager:
154
153
  pass
155
154
 
156
-
157
155
  class NotificationChannel:
158
156
  def __init__(self, channel_id, channel_name, importance):
159
157
  self.description = None
@@ -189,10 +187,10 @@ class NotificationChannel:
189
187
  logger.debug(f"[MOCK] NotificationChannel.setVibrationPattern called, list_of_numbers={list_of_numbers}")
190
188
 
191
189
 
192
- class IconCompat:
190
+ class IconClass:
193
191
  @classmethod
194
192
  def createWithBitmap(cls, bitmap):
195
- logger.debug(f"[MOCK] IconCompat.createWithBitmap called with bitmap={bitmap}")
193
+ logger.debug(f"[MOCK] IconClass.createWithBitmap called with bitmap={bitmap}")
196
194
 
197
195
 
198
196
  class Color:
@@ -3,7 +3,6 @@
3
3
  import inspect, os, re
4
4
  from .logger import logger
5
5
 
6
-
7
6
  def can_accept_arguments(func, *args, **kwargs):
8
7
  try:
9
8
  sig = inspect.signature(func)
@@ -55,6 +54,3 @@ def execute_callback(callback,arg, from_who="user"):
55
54
  callback()
56
55
  except Exception as on_permissions_result_callback_error:
57
56
  logger.exception(on_permissions_result_callback_error)
58
-
59
- def on_pydroid_app():
60
- return "ru.iiec.pydroid3" in os.path.dirname(os.path.abspath(__file__))
@@ -0,0 +1,85 @@
1
+
2
+ from android_notify.config import has_androidx_dependency,on_pydroid_app, on_android_platform,on_flet_app
3
+ from .logger import logger
4
+
5
+ if on_android_platform():
6
+ try:
7
+ from jnius import cast, autoclass
8
+ except ModuleNotFoundError:
9
+ cast = lambda x, y: x
10
+ autoclass = lambda x: None
11
+ logger.exception("add pyjnius to dependencies list")
12
+
13
+ # Leaving this as a broad Exception for unforeseen case so apps don't crash
14
+ # noinspection PyBroadException
15
+ try:
16
+ # Get the required Java classes needs to run on android to import
17
+ Bundle = autoclass('android.os.Bundle')
18
+ String = autoclass('java.lang.String')
19
+ Intent = autoclass('android.content.Intent')
20
+ PendingIntent = autoclass('android.app.PendingIntent')
21
+ BitmapFactory = autoclass('android.graphics.BitmapFactory')
22
+ BuildVersion = autoclass('android.os.Build$VERSION')
23
+ NotificationManager = autoclass('android.app.NotificationManager')
24
+ NotificationChannel = autoclass('android.app.NotificationChannel')
25
+ RemoteViews = autoclass('android.widget.RemoteViews')
26
+ Settings = autoclass("android.provider.Settings")
27
+ Uri = autoclass("android.net.Uri")
28
+ Manifest = autoclass('android.Manifest$permission')
29
+ Context = autoclass('android.content.Context')
30
+ PackageManager = autoclass("android.content.pm.PackageManager")
31
+ AudioAttributes = autoclass('android.media.AudioAttributes')
32
+ AudioAttributesBuilder = autoclass('android.media.AudioAttributes$Builder')
33
+ File = autoclass('java.io.File')
34
+ Color = autoclass('android.graphics.Color')
35
+ except Exception as e:
36
+ from .facade import *
37
+ logger.exception("Didn't get Basic Java Classes")
38
+
39
+ if on_flet_app() or on_pydroid_app() or not has_androidx_dependency():
40
+ # Leaving this as a broad Exception for unforeseen case so apps don't crash
41
+ # noinspection PyBroadException
42
+ try:
43
+ IconClass = autoclass('android.graphics.drawable.Icon')
44
+ NotificationCompat = autoclass("android.app.Notification")
45
+ NotificationManagerCompat = autoclass('android.app.NotificationManager')
46
+ NotificationCompatBuilder = autoclass('android.app.Notification$Builder')
47
+
48
+ NotificationCompatBigTextStyle = autoclass('android.app.Notification$BigTextStyle')
49
+ NotificationCompatBigPictureStyle = autoclass('android.app.Notification$BigPictureStyle')
50
+ NotificationCompatInboxStyle = autoclass('android.app.Notification$InboxStyle')
51
+ NotificationCompatDecoratedCustomViewStyle = autoclass('android.app.Notification$DecoratedCustomViewStyle')
52
+ except Exception as styles_import_error:
53
+ logger.exception(styles_import_error)
54
+ from .facade import *
55
+ elif has_androidx_dependency():
56
+
57
+ # Leaving this as a broad Exception for unforeseen case so apps don't crash
58
+ # noinspection PyBroadException
59
+ try:
60
+ IconClass = autoclass('androidx.core.graphics.drawable.IconCompat')
61
+ NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
62
+ NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
63
+ NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
64
+
65
+ # Notification Design
66
+ NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
67
+ NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
68
+ NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
69
+ NotificationCompatDecoratedCustomViewStyle = autoclass('androidx.core.app.NotificationCompat$DecoratedCustomViewStyle')
70
+
71
+ except Exception as dependencies_import_error:
72
+ logger.exception("""
73
+ Dependency Error: Add the following in buildozer.spec:
74
+ * android.gradle_dependencies = androidx.core:core:1.12.0
75
+ * android.enable_androidx = True
76
+ """)
77
+
78
+ from .facade import *
79
+ else:
80
+ cast = lambda x, y: x
81
+ autoclass = lambda x: None
82
+ # noinspection PyUnresolvedReferences
83
+ from .facade import *
84
+ logger.warning("Did not initialize java classes, Not on Android")
85
+
@@ -4,11 +4,49 @@ For Permission Related Blocks
4
4
  import os.path
5
5
 
6
6
  from .logger import logger
7
- from android_notify.config import on_android_platform, on_flet_app, get_python_activity_context
7
+ from android_notify.config import on_android_platform, on_flet_app, get_python_activity_context, on_pydroid_app, has_androidx_dependency
8
8
  from android_notify.internal.java_classes import autoclass, BuildVersion, Manifest, Intent, String, Settings, Uri, PackageManager, NotificationManagerCompat
9
- from android_notify.internal.helper import execute_callback, on_pydroid_app
9
+ from android_notify.internal.helper import execute_callback
10
10
 
11
11
 
12
+ def check_notification_permission_legacy_android12_below():
13
+ # NotificationManagerCompat is actually NotificationManager from android_notify.internal.java_classes
14
+ context = get_python_activity_context()
15
+ nm = context.getSystemService(NotificationManagerCompat)
16
+ return nm.areNotificationsEnabled()
17
+
18
+ def check_notification_permission_androidx_android12_below():
19
+ context = get_python_activity_context()
20
+ func_from = getattr(NotificationManagerCompat, "from")
21
+ compat_manager = func_from(context)
22
+ return compat_manager.areNotificationsEnabled()
23
+
24
+ def check_notification_permission_legacy_android12_above():
25
+ # NotificationManagerCompat is actually NotificationManager from android_notify.internal.java_classes
26
+ context = get_python_activity_context()
27
+ permission = Manifest.POST_NOTIFICATIONS
28
+ return PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(permission)
29
+
30
+ def check_notification_permission_androidx_android12_above():
31
+ # Unused keeping for future reference
32
+ context = get_python_activity_context()
33
+ permission = Manifest.POST_NOTIFICATIONS
34
+ ContextCompat = autoclass('androidx.core.content.ContextCompat')
35
+ # For flet
36
+ # if you get error `Failed to find class: androidx/core/app/ActivityCompat`
37
+ # in proguard-rules.pro add `-keep class androidx.core.app.ActivityCompat { *; }`
38
+ return ContextCompat.checkSelfPermission(context, permission)
39
+
40
+ def ask_notification_permission_androidx():
41
+ # Unused keeping for future reference
42
+ # TODO Callback when user answers request question
43
+ # Can't bind activity result method is from p4a which is only on kivy
44
+ context = get_python_activity_context()
45
+ ActivityCompat = autoclass('androidx.core.app.ActivityCompat')
46
+ permission = Manifest.POST_NOTIFICATIONS
47
+ ActivityCompat.requestPermissions(context, [permission], 101)
48
+ return None
49
+
12
50
  def has_notification_permission():
13
51
  """
14
52
  Checks if device has permission to send notifications
@@ -19,24 +57,20 @@ def has_notification_permission():
19
57
 
20
58
  if BuildVersion.SDK_INT < 33: # Android 12 and below
21
59
  try:
22
- # NotificationManagerCompat is actually NotificationManager from android_notify.internal.java_classes
23
- context = get_python_activity_context()
24
- nm = context.getSystemService(NotificationManagerCompat)
25
- return nm.areNotificationsEnabled()
60
+ if on_flet_app() or on_pydroid_app() or not has_androidx_dependency():
61
+ return check_notification_permission_legacy_android12_below()
62
+ elif has_androidx_dependency():
63
+ return check_notification_permission_androidx_android12_below()
26
64
  except Exception as error_checking_permission:
27
65
  logger.exception(f"On Android 12 and below Error checking permission: {error_checking_permission}")
28
66
  return None
29
67
 
30
- if on_flet_app():
31
- context = get_python_activity_context()
32
- permission = Manifest.POST_NOTIFICATIONS
33
-
34
- return PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(permission)
68
+ if on_flet_app() or on_pydroid_app() or not has_androidx_dependency():
69
+ return check_notification_permission_legacy_android12_above()
35
70
  else:
36
71
  from android.permissions import Permission, check_permission # type: ignore
37
72
  return check_permission(Permission.POST_NOTIFICATIONS)
38
73
 
39
-
40
74
  def ask_notification_permission(callback=None, set_requesting_state=None, legacy=False):
41
75
  if not on_android_platform():
42
76
  logger.warning("Can't ask permission when not on android")
@@ -91,7 +125,6 @@ def ask_notification_permission(callback=None, set_requesting_state=None, legacy
91
125
  request_permissions([Permission.POST_NOTIFICATIONS], on_permissions_result)
92
126
  return None
93
127
 
94
-
95
128
  def open_notification_settings_screen():
96
129
  """In MDApp().on_resume()
97
130
 
@@ -126,7 +159,6 @@ def open_notification_settings_screen():
126
159
 
127
160
  # https://stackoverflow.com/a/45192258/19961621
128
161
 
129
-
130
162
  def can_show_permission_request_popup():
131
163
  """
132
164
  Check if we can show permission request popup for POST_NOTIFICATIONS
@@ -143,7 +175,6 @@ def can_show_permission_request_popup():
143
175
 
144
176
  return context.shouldShowRequestPermissionRationale(Manifest.POST_NOTIFICATIONS)
145
177
 
146
-
147
178
  def is_first_permission_ask():
148
179
  from importlib.resources import files
149
180
  buffer_file_name = "ASKED_PERMISSION.txt"
@@ -105,10 +105,10 @@ def get_image_uri(relative_path):
105
105
 
106
106
  def get_icon_object(uri):
107
107
  BitmapFactory = autoclass('android.graphics.BitmapFactory')
108
- IconCompat = autoclass('androidx.core.graphics.drawable.IconCompat')
108
+ IconClass = autoclass('android.graphics.drawable.Icon')
109
109
 
110
110
  bitmap= BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
111
- return IconCompat.createWithBitmap(bitmap)
111
+ return IconClass.createWithBitmap(bitmap)
112
112
 
113
113
  def insert_app_icon(builder,custom_icon_path):
114
114
  if custom_icon_path:
@@ -105,10 +105,10 @@ def get_image_uri(relative_path):
105
105
 
106
106
  def get_icon_object(uri):
107
107
  BitmapFactory = autoclass('android.graphics.BitmapFactory')
108
- IconCompat = autoclass('androidx.core.graphics.drawable.IconCompat')
108
+ IconClass = autoclass('android.graphics.drawable.Icon')
109
109
 
110
110
  bitmap= BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
111
- return IconCompat.createWithBitmap(bitmap)
111
+ return IconClass.createWithBitmap(bitmap)
112
112
 
113
113
  def insert_app_icon(builder,custom_icon_path):
114
114
  if custom_icon_path:
@@ -102,7 +102,7 @@ class AndroidNotifyDemoApp(MDApp):
102
102
 
103
103
  def get_free_port_():
104
104
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
105
- s.bind(("", 0)) # bind to a random free port
105
+ s.bind(("127.0.0.1", 0)) # bind to a random free port on loopback only
106
106
  port = s.getsockname()[1]
107
107
  s.close()
108
108
  return port
@@ -3,8 +3,8 @@ For image related things
3
3
  """
4
4
  import os
5
5
 
6
- from android_notify.config import app_storage_path, on_flet_app, on_android_platform, get_python_activity_context
7
- from android_notify.internal.java_classes import autoclass, BitmapFactory, Uri, BuildVersion, Color
6
+ from android_notify.config import app_storage_path, on_flet_app, on_android_platform, get_python_activity_context, on_pydroid_app
7
+ from android_notify.internal.java_classes import autoclass, BitmapFactory, Uri, BuildVersion, Color, IconClass
8
8
  from android_notify.internal.helper import get_package_path
9
9
  from android_notify.internal.logger import logger
10
10
 
@@ -94,7 +94,7 @@ def find_and_set_default_icon(builder):
94
94
  fallback_icon_path = None
95
95
  if on_flet_app():
96
96
  fallback_icon_path = icon_finder("flet-appicon.png")
97
- elif "ru.iiec.pydroid3" in os.path.dirname(os.path.abspath(__file__)):
97
+ elif on_pydroid_app():
98
98
  fallback_icon_path = icon_finder("pydroid3-appicon.png")
99
99
 
100
100
  if fallback_icon_path:
@@ -128,8 +128,7 @@ def set_small_icon_with_bitmap(bitmap, builder):
128
128
  logger.warning("Bitmap Insert as Icon Not available below Android 6")
129
129
  return False
130
130
  try:
131
- IconCompat = autoclass('android.graphics.drawable.Icon')
132
- icon = IconCompat.createWithBitmap(bitmap)
131
+ icon = IconClass.createWithBitmap(bitmap)
133
132
  builder.setSmallIcon(icon)
134
133
  return True
135
134
  except Exception as autoclass_icon_error:
@@ -106,7 +106,7 @@ def set_lines(builder, lines):
106
106
 
107
107
 
108
108
 
109
- from android_notify.internal.java_classes import Color, RemoteViews
109
+ from android_notify.internal.java_classes import Color, RemoteViews, NotificationCompatDecoratedCustomViewStyle
110
110
  from android_notify.internal.logger import logger
111
111
  from android_notify.config import get_python_activity_context
112
112
 
@@ -121,10 +121,6 @@ def setLayoutText(layout, text_id, text, color):
121
121
 
122
122
  def set_custom_colors(builder, title, message, title_color, message_color):
123
123
  # Load layout
124
- from android_notify.internal.java_classes import autoclass
125
- NotificationCompatDecoratedCustomViewStyle = autoclass(
126
- 'android.app.Notification$DecoratedCustomViewStyle')
127
-
128
124
  context = get_python_activity_context()
129
125
  resources = context.getResources()
130
126
  package_name = context.getPackageName()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: android-notify
3
- Version: 1.61.3.dev0
3
+ Version: 1.61.4
4
4
  Summary: A Python package that simplifies creating Android notifications in Kivy and Flet apps.
5
5
  Author-email: Fabian <fector101@yahoo.com>
6
6
  License-Expression: MIT
@@ -53,6 +53,8 @@ The Android Notify package provides a simple yet comprehensive way to create and
53
53
  - Persistent notifications
54
54
  - Click handlers and callbacks
55
55
  - Cancel Notifications
56
+ - Use [Custom Sound](https://android-notify.vercel.app/advanced-methods#custom-sound)
57
+ - Vibration [section](https://android-notify.vercel.app/advanced-methods#vibration)
56
58
 
57
59
  ## Quick Start
58
60
 
@@ -80,14 +82,13 @@ In your **`buildozer.spec`** file, ensure you include the following:
80
82
 
81
83
  ```ini
82
84
  # Add pyjnius so ensure it's packaged with the build
83
- requirements = python3, kivy, pyjnius, android-notify==1.61.3.dev0
85
+ requirements = python3, kivy, pyjnius, android-notify
84
86
  # Add permission for notifications
85
87
  android.permissions = POST_NOTIFICATIONS
86
88
  ```
87
89
 
88
90
  </details>
89
91
 
90
-
91
92
  <details>
92
93
  <summary><b>Flet apps:</b></summary>
93
94
  <br/>
@@ -98,7 +99,7 @@ In your `pyproject.toml` file, ensure you include the following:
98
99
  ```toml
99
100
  [tool.flet.android]
100
101
  dependencies = [
101
- "pyjnius","android-notify==1.61.3.dev0"
102
+ "pyjnius","android-notify"
102
103
  ]
103
104
 
104
105
  [tool.flet.android.permission]
@@ -108,23 +109,19 @@ dependencies = [
108
109
 
109
110
  </details>
110
111
 
111
-
112
-
113
112
  <details>
114
113
 
115
114
  <summary><b>On Pydroid 3</b></summary>
116
115
  <br/>
117
116
 
118
117
  On the [pydroid 3](https://play.google.com/store/apps/details?id=ru.iiec.pydroid3) mobile app for running python code you can test some features.
119
- - In pip section where you're asked to insert `Libary name` paste `android-notify==1.61.3.dev0`
118
+ - In pip section where you're asked to insert `Libary name` paste `android-notify`
120
119
  - Minimal working example
121
120
  ```py
122
- # Testing with `android-notify==1.61.3.dev0` on pydroid
123
121
  from kivy.app import App
124
122
  from kivy.uix.boxlayout import BoxLayout
125
123
  from kivy.uix.button import Button
126
- from android_notify import Notification
127
- from android_notify.core import asks_permission_if_needed
124
+ from android_notify import Notification, NotificationHandler
128
125
 
129
126
 
130
127
  class AndroidNotifyDemoApp(App):
@@ -146,9 +143,7 @@ class AndroidNotifyDemoApp(App):
146
143
  def send_notification(self, *args):
147
144
  Notification(
148
145
  title="Hello from Android Notify",
149
- message="This is a basic notification.",
150
- channel_id="android_notify_demo",
151
- channel_name="Android Notify Demo"
146
+ message="This is a basic notification."
152
147
  ).send()
153
148
 
154
149
 
@@ -173,38 +168,11 @@ android-notify -v
173
168
  </details>
174
169
 
175
170
  ## Documentation
176
- For Dev Version use
171
+ For Dev Version usage
177
172
  ```ini
178
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
173
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
179
174
  ```
180
175
 
181
- <details>
182
- <summary> <b> To talk to BroadCast Listener From Buttons </b> </summary>
183
-
184
- - Make things happen without being in your app
185
- ```python
186
- from android_notify import Notification
187
- notification = Notification(title="Receiver Notification")
188
- notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
189
- notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
190
- ```
191
- You can use this [wiki](https://github.com/Fector101/android_notify/wiki/How-to-Use-with-Broadcast-Listener) as a guide create a broadcast listener
192
- </details>
193
-
194
- <details>
195
- <summary> <b> To use colored text in your notifications </b> </summary>
196
-
197
- - Copy the [res](https://github.com/Fector101/android_notify/tree/main/android_notify/res) folder to your app path.
198
- - Lastly in your `buildozer.spec` file
199
- Add `source.include_exts = xml` and `android.add_resources = # path you pasted`
200
- ```python
201
- # Use Hex Code to be Safe
202
- n = Notification(title="Title and Message Color", message="Testing",title_color="red")
203
- n.send()
204
- ```
205
-
206
- </details>
207
-
208
176
  <details>
209
177
  <summary> <b>To use Custom Sounds </b> </summary>
210
178
 
@@ -267,26 +235,6 @@ Private files (e.g., in app's `data/` directory) are automatically copied to ext
267
235
  </details>
268
236
 
269
237
 
270
- <details>
271
- <summary> <b> Vibrate feature</b> </summary>
272
-
273
- ```ini
274
- # buildozer.spec
275
- android.permissions = VIBRATE
276
- ```
277
-
278
- ```python
279
- Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
280
-
281
- n=Notification(title='Vibrate',channel_id='shake')
282
- n.setVibrate() # for less than android 8
283
- n.fVibrate() # To Force Vibrate (when user turned off in settings)
284
- n.send()
285
- ```
286
-
287
- </details>
288
-
289
-
290
238
  <details>
291
239
  <summary> <b> Add Data to Notification</b> </summary>
292
240
 
@@ -324,3 +272,16 @@ Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify
324
272
  <a href="https://www.buymeacoffee.com/fector101" target="_blank">
325
273
  <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
326
274
  </a>
275
+
276
+ ## Bug Reports & Feature Requests
277
+
278
+ Found a bug or have an idea for a new feature?
279
+ Feel free to open an issue [here](https://reference-url-citation.invalid/0)
280
+
281
+ When reporting a bug, try to include:
282
+ - Device name
283
+ - Android version
284
+ - Steps to reproduce the issue
285
+ - Screenshots or logs (if possible)
286
+
287
+ Feature suggestions are also welcome.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "android-notify"
7
- version = "1.61.3.dev0"
7
+ version = "1.61.4"
8
8
  description = "A Python package that simplifies creating Android notifications in Kivy and Flet apps."
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
 
@@ -13,7 +13,6 @@ authors = [
13
13
  ]
14
14
 
15
15
  license = "MIT"
16
-
17
16
  dependencies = [
18
17
  "pyjnius"
19
18
  ]
@@ -1,24 +0,0 @@
1
- import argparse
2
- from .config import __version__
3
-
4
- def print_version():
5
- text = f"android_notify: v{__version__}"
6
- border = '+'+'-'*(len(text) + 2)+'+'
7
- print(border)
8
- print(f'| {text} |')
9
- print(border)
10
-
11
- def main():
12
- parser = argparse.ArgumentParser(description="Android Notify CLI")
13
- parser.add_argument('-v','--version', action='store_true', help="Show the version of android_notify")
14
- args = parser.parse_args()
15
-
16
- if args.version:
17
- print_version()
18
- # # Placeholder for the main functionality
19
- # print("Android Notify CLI is running...")
20
- # DEV: pip install -e ., when edit and test project locally
21
-
22
-
23
- if __name__ == "__main__":
24
- main()
@@ -1,69 +0,0 @@
1
- import os
2
-
3
- from .logger import logger
4
-
5
- def on_android_platform():
6
- kivy_build = os.environ.get('KIVY_BUILD', '')
7
- if kivy_build in {'android'}:
8
- return True
9
- elif 'P4A_BOOTSTRAP' in os.environ:
10
- return True
11
- elif 'ANDROID_ARGUMENT' in os.environ:
12
- return True
13
- return os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME")
14
-
15
-
16
- if on_android_platform():
17
- try:
18
- from jnius import cast, autoclass
19
- except ModuleNotFoundError:
20
- cast = lambda x, y: x
21
- autoclass = lambda x: None
22
- logger.exception("run pip install pyjnius")
23
-
24
- # Leaving this as a broad Exception for unforeseen case so apps don't crash
25
- # noinspection PyBroadException
26
- try:
27
- # Get the required Java classes needs to run on android to import
28
- Bundle = autoclass('android.os.Bundle')
29
- String = autoclass('java.lang.String')
30
- Intent = autoclass('android.content.Intent')
31
- PendingIntent = autoclass('android.app.PendingIntent')
32
- BitmapFactory = autoclass('android.graphics.BitmapFactory')
33
- BuildVersion = autoclass('android.os.Build$VERSION')
34
- NotificationManager = autoclass('android.app.NotificationManager')
35
- NotificationChannel = autoclass('android.app.NotificationChannel')
36
- RemoteViews = autoclass('android.widget.RemoteViews')
37
- Settings = autoclass("android.provider.Settings")
38
- Uri = autoclass("android.net.Uri")
39
- Manifest = autoclass('android.Manifest$permission')
40
- Color = autoclass('android.graphics.Color')
41
- Context = autoclass('android.content.Context')
42
- PackageManager = autoclass("android.content.pm.PackageManager")
43
- AudioAttributes = autoclass('android.media.AudioAttributes')
44
- AudioAttributesBuilder = autoclass('android.media.AudioAttributes$Builder')
45
- File = autoclass('java.io.File')
46
- except Exception as e:
47
- from .facade import *
48
- logger.exception("Didn't get Basic Java Classes")
49
-
50
- # noinspection PyBroadException
51
- try:
52
- NotificationManagerCompat = NotificationManager # I need other files identical to main branch so it's easier to maintain
53
- NotificationCompat = autoclass("android.app.Notification")
54
- NotificationCompatBuilder = autoclass('android.app.Notification$Builder')
55
- NotificationCompatBigTextStyle = autoclass('android.app.Notification$BigTextStyle')
56
- NotificationCompatBigPictureStyle = autoclass('android.app.Notification$BigPictureStyle')
57
- NotificationCompatInboxStyle = autoclass('android.app.Notification$InboxStyle')
58
-
59
- except Exception as styles_import_error:
60
- logger.exception(styles_import_error)
61
- from .facade import *
62
-
63
- else:
64
- cast = lambda x, y: x
65
- autoclass = lambda x: None
66
- # noinspection PyUnresolvedReferences
67
- from .facade import *
68
- logger.warning("Did not initialize java classes, Not on Android")
69
-