android-notify 1.61.0__tar.gz → 1.61.0.dev0__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 (53) hide show
  1. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/PKG-INFO +28 -43
  2. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/README.md +27 -42
  3. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/config.py +2 -1
  4. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/core.py +3 -4
  5. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/helper.py +4 -1
  6. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/java_classes.py +10 -17
  7. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/permissions.py +9 -22
  8. android_notify-1.61.0.dev0/android_notify/tests/flet/basic/src/core.py +221 -0
  9. android_notify-1.61.0.dev0/android_notify/tests/flet/flet-working/src/core.py +221 -0
  10. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/widgets/images.py +2 -1
  11. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/widgets/texts.py +5 -1
  12. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify.egg-info/PKG-INFO +28 -43
  13. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify.egg-info/SOURCES.txt +2 -0
  14. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/pyproject.toml +1 -1
  15. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/__init__.py +0 -0
  16. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/__main__.py +0 -0
  17. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/base.py +0 -0
  18. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/fallback-icons/flet-appicon.png +0 -0
  19. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/fallback-icons/pydroid3-appicon.png +0 -0
  20. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/an_types.py +0 -0
  21. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/android.py +0 -0
  22. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/channels.py +0 -0
  23. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/facade.py +0 -0
  24. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/intents.py +0 -0
  25. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/internal/logger.py +0 -0
  26. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/styles.py +0 -0
  27. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/sword.py +0 -0
  28. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/__init__.py +0 -0
  29. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/android_notify_test.py +0 -0
  30. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/base_test.py +0 -0
  31. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/flet/adv/main.py +0 -0
  32. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/flet/adv/tests/__init__.py +0 -0
  33. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/flet/adv/tests/test_android_notify_full.py +0 -0
  34. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/flet/basic/src/main.py +0 -0
  35. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/flet/flet-working/src/main.py +0 -0
  36. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/main.py +0 -0
  37. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/p4a/hook.py +0 -0
  38. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/serivces/wallpaper.py +0 -0
  39. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_basic_notifications.py +0 -0
  40. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_actions.py +0 -0
  41. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_appearance.py +0 -0
  42. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_behavior.py +0 -0
  43. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_channels.py +0 -0
  44. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_clear.py +0 -0
  45. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_permission.py +0 -0
  46. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_progress.py +0 -0
  47. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_sound.py +0 -0
  48. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify/tests/test_notification_styles.py +0 -0
  49. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify.egg-info/dependency_links.txt +0 -0
  50. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify.egg-info/entry_points.txt +0 -0
  51. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify.egg-info/requires.txt +0 -0
  52. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/android_notify.egg-info/top_level.txt +0 -0
  53. {android_notify-1.61.0 → android_notify-1.61.0.dev0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: android-notify
3
- Version: 1.61.0
3
+ Version: 1.61.0.dev0
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
@@ -81,14 +81,9 @@ In your **`buildozer.spec`** file, ensure you include the following:
81
81
 
82
82
  ```ini
83
83
  # Add pyjnius so ensure it's packaged with the build
84
- requirements = python3, kivy, pyjnius, android-notify
84
+ requirements = python3, kivy, pyjnius, android-notify==1.61.0.dev0
85
85
  # Add permission for notifications
86
86
  android.permissions = POST_NOTIFICATIONS
87
-
88
- # Required dependency (write exactly as shown, no quotation marks)
89
- android.gradle_dependencies = androidx.core:core-ktx:1.15.0
90
- android.enable_androidx = True
91
- android.api = 35
92
87
  ```
93
88
 
94
89
  </details>
@@ -98,7 +93,7 @@ android.api = 35
98
93
  <summary><b>Flet apps:</b></summary>
99
94
  <br/>
100
95
 
101
- In your `pyproject.toml` file, ensure you include the following:
96
+ In your `pyproject.toml` file, ensure you include the following:
102
97
 
103
98
 
104
99
  ```toml
@@ -114,35 +109,7 @@ dependencies = [
114
109
 
115
110
  </details>
116
111
 
117
- <details>
118
-
119
- <summary><b>Desktop</b></summary>
120
- <br/>
121
-
122
- For IDE IntelliSense Can be installed via `pip install`:
123
-
124
- ```bash
125
- pip install android_notify
126
- android-notify -v
127
- ```
128
-
129
- </details>
130
-
131
- ------
132
- ## Installing without Androidx
133
- How to use without `gradle_dependencies`
134
- Use `android-notify==1.61.0.dev0` to install via `pip`
135
-
136
- <details>
137
- <summary><b>In Kivy</b></summary>
138
- <br/>
139
-
140
- ```ini
141
- # buildozer.spec
142
- requirements = python3, kivy, pyjnius, android-notify==1.61.0.dev0
143
- ```
144
112
 
145
- </details>
146
113
 
147
114
  <details>
148
115
 
@@ -180,7 +147,9 @@ class AndroidNotifyDemoApp(App):
180
147
  def send_notification(self, *args):
181
148
  Notification(
182
149
  title="Hello from Android Notify",
183
- message="This is a basic notification."
150
+ message="This is a basic notification.",
151
+ channel_id="android_notify_demo",
152
+ channel_name="Android Notify Demo"
184
153
  ).send()
185
154
 
186
155
 
@@ -191,11 +160,23 @@ if __name__ == "__main__":
191
160
  </details>
192
161
 
193
162
 
163
+ <details>
164
+
165
+ <summary><b>Desktop</b></summary>
166
+ <br/>
167
+
168
+ For IDE IntelliSense Can be installed via `pip install`:
169
+
170
+ ```bash
171
+ pip install android_notify
172
+ android-notify -v
173
+ ```
174
+ </details>
194
175
 
195
176
  ## Documentation
196
- For Dev Version usage
177
+ For Dev Version use
197
178
  ```ini
198
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
179
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
199
180
  ```
200
181
 
201
182
  <details>
@@ -204,7 +185,7 @@ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_noti
204
185
  - Make things happen without being in your app
205
186
  ```python
206
187
  from android_notify import Notification
207
- notification = Notification(title="Reciver Notification")
188
+ notification = Notification(title="Receiver Notification")
208
189
  notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
209
190
  notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
210
191
  ```
@@ -267,7 +248,7 @@ Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
267
248
 
268
249
  n=Notification(title='Vibrate',channel_id='shake')
269
250
  n.setVibrate() # for less than android 8
270
- n.fVibrate() # To Force Vibrate
251
+ n.fVibrate() # To Force Vibrate (when user turned off in settings)
271
252
  n.send()
272
253
  ```
273
254
 
@@ -305,5 +286,9 @@ from android_notify import Notification, NotificationHandler
305
286
 
306
287
  ## ☕ Support the Project
307
288
 
308
- If you find this project helpful, your support would help me continue working on open-source projects
309
- [donate](https://www.buymeacoffee.com/fector101)
289
+ If you find this project helpful, consider buying me a coffee! 😊
290
+ Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify/) Your support helps maintain and improve the project.
291
+
292
+ <a href="https://www.buymeacoffee.com/fector101" target="_blank">
293
+ <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
294
+ </a>
@@ -58,14 +58,9 @@ In your **`buildozer.spec`** file, ensure you include the following:
58
58
 
59
59
  ```ini
60
60
  # Add pyjnius so ensure it's packaged with the build
61
- requirements = python3, kivy, pyjnius, android-notify
61
+ requirements = python3, kivy, pyjnius, android-notify==1.61.0.dev0
62
62
  # Add permission for notifications
63
63
  android.permissions = POST_NOTIFICATIONS
64
-
65
- # Required dependency (write exactly as shown, no quotation marks)
66
- android.gradle_dependencies = androidx.core:core-ktx:1.15.0
67
- android.enable_androidx = True
68
- android.api = 35
69
64
  ```
70
65
 
71
66
  </details>
@@ -75,7 +70,7 @@ android.api = 35
75
70
  <summary><b>Flet apps:</b></summary>
76
71
  <br/>
77
72
 
78
- In your `pyproject.toml` file, ensure you include the following:
73
+ In your `pyproject.toml` file, ensure you include the following:
79
74
 
80
75
 
81
76
  ```toml
@@ -91,35 +86,7 @@ dependencies = [
91
86
 
92
87
  </details>
93
88
 
94
- <details>
95
-
96
- <summary><b>Desktop</b></summary>
97
- <br/>
98
-
99
- For IDE IntelliSense Can be installed via `pip install`:
100
-
101
- ```bash
102
- pip install android_notify
103
- android-notify -v
104
- ```
105
-
106
- </details>
107
-
108
- ------
109
- ## Installing without Androidx
110
- How to use without `gradle_dependencies`
111
- Use `android-notify==1.61.0.dev0` to install via `pip`
112
-
113
- <details>
114
- <summary><b>In Kivy</b></summary>
115
- <br/>
116
-
117
- ```ini
118
- # buildozer.spec
119
- requirements = python3, kivy, pyjnius, android-notify==1.61.0.dev0
120
- ```
121
89
 
122
- </details>
123
90
 
124
91
  <details>
125
92
 
@@ -157,7 +124,9 @@ class AndroidNotifyDemoApp(App):
157
124
  def send_notification(self, *args):
158
125
  Notification(
159
126
  title="Hello from Android Notify",
160
- message="This is a basic notification."
127
+ message="This is a basic notification.",
128
+ channel_id="android_notify_demo",
129
+ channel_name="Android Notify Demo"
161
130
  ).send()
162
131
 
163
132
 
@@ -168,11 +137,23 @@ if __name__ == "__main__":
168
137
  </details>
169
138
 
170
139
 
140
+ <details>
141
+
142
+ <summary><b>Desktop</b></summary>
143
+ <br/>
144
+
145
+ For IDE IntelliSense Can be installed via `pip install`:
146
+
147
+ ```bash
148
+ pip install android_notify
149
+ android-notify -v
150
+ ```
151
+ </details>
171
152
 
172
153
  ## Documentation
173
- For Dev Version usage
154
+ For Dev Version use
174
155
  ```ini
175
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
156
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
176
157
  ```
177
158
 
178
159
  <details>
@@ -181,7 +162,7 @@ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_noti
181
162
  - Make things happen without being in your app
182
163
  ```python
183
164
  from android_notify import Notification
184
- notification = Notification(title="Reciver Notification")
165
+ notification = Notification(title="Receiver Notification")
185
166
  notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
186
167
  notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
187
168
  ```
@@ -244,7 +225,7 @@ Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
244
225
 
245
226
  n=Notification(title='Vibrate',channel_id='shake')
246
227
  n.setVibrate() # for less than android 8
247
- n.fVibrate() # To Force Vibrate
228
+ n.fVibrate() # To Force Vibrate (when user turned off in settings)
248
229
  n.send()
249
230
  ```
250
231
 
@@ -282,5 +263,9 @@ from android_notify import Notification, NotificationHandler
282
263
 
283
264
  ## ☕ Support the Project
284
265
 
285
- If you find this project helpful, your support would help me continue working on open-source projects
286
- [donate](https://www.buymeacoffee.com/fector101)
266
+ If you find this project helpful, consider buying me a coffee! 😊
267
+ Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify/) Your support helps maintain and improve the project.
268
+
269
+ <a href="https://www.buymeacoffee.com/fector101" target="_blank">
270
+ <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
271
+ </a>
@@ -1,6 +1,7 @@
1
1
  import os
2
2
 
3
- __version__ = "1.61.0"
3
+ __version__ = "1.61.0.dev0"
4
+
4
5
 
5
6
  from .internal.java_classes import autoclass, cast, NotificationManager
6
7
  from .internal.logger import logger
@@ -6,7 +6,7 @@ from android_notify.internal.logger import logger
6
6
  from android_notify.config import get_python_activity, on_android_platform, get_python_activity_context
7
7
  from android_notify.internal.permissions import has_notification_permission, ask_notification_permission
8
8
  from android_notify.internal.java_classes import autoclass, BuildVersion, BitmapFactory, NotificationChannel, NotificationManagerCompat, NotificationCompat, NotificationCompatBuilder, \
9
- NotificationCompatBigTextStyle, NotificationCompatBigPictureStyle, NotificationCompatInboxStyle, IconCompat
9
+ NotificationCompatBigTextStyle, NotificationCompatBigPictureStyle, NotificationCompatInboxStyle
10
10
 
11
11
 
12
12
 
@@ -60,6 +60,7 @@ def get_image_uri(relative_path):
60
60
 
61
61
  def get_icon_object(uri):
62
62
  context = get_python_activity_context()
63
+ IconCompat = autoclass('android.graphics.drawable.Icon')
63
64
  bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
64
65
  return IconCompat.createWithBitmap(bitmap)
65
66
 
@@ -114,9 +115,7 @@ def send_notification(
114
115
  return None
115
116
  context = get_python_activity_context()
116
117
 
117
-
118
- asks_permission_if_needed()
119
-
118
+ asks_permission_if_needed(legacy=True)
120
119
  channel_id = channel_name.replace(' ', '_').lower().lower() if not channel_id else channel_id
121
120
  # Get notification manager
122
121
  notification_manager = context.getSystemService(context.NOTIFICATION_SERVICE)
@@ -54,4 +54,7 @@ def execute_callback(callback,arg, from_who="user"):
54
54
  else:
55
55
  callback()
56
56
  except Exception as on_permissions_result_callback_error:
57
- logger.exception(on_permissions_result_callback_error)
57
+ 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__))
@@ -39,31 +39,24 @@ if on_android_platform():
39
39
  Manifest = autoclass('android.Manifest$permission')
40
40
  Color = autoclass('android.graphics.Color')
41
41
  Context = autoclass('android.content.Context')
42
+ PackageManager = autoclass("android.content.pm.PackageManager")
42
43
  except Exception as e:
43
44
  from .facade import *
44
45
  logger.exception("Didn't get Basic Java Classes")
45
46
 
46
47
  # noinspection PyBroadException
47
48
  try:
48
- NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
49
- NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
50
- NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
51
- IconCompat = autoclass('androidx.core.graphics.drawable.IconCompat')
52
-
53
- # Notification Design
54
- NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
55
- NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
56
- NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
57
- NotificationCompatDecoratedCustomViewStyle = autoclass('androidx.core.app.NotificationCompat$DecoratedCustomViewStyle')
58
-
59
- except Exception as dependencies_import_error:
60
- logger.exception("""
61
- Dependency Error: Add the following in buildozer.spec:
62
- * android.gradle_dependencies = androidx.core:core-ktx:1.15.0, androidx.core:core:1.6.0
63
- * android.enable_androidx = True
64
- """)
49
+ NotificationManagerCompat = NotificationManager # I need other files identical to main branch so it's easier to maintain
50
+ NotificationCompat = autoclass("android.app.Notification")
51
+ NotificationCompatBuilder = autoclass('android.app.Notification$Builder')
52
+ NotificationCompatBigTextStyle = autoclass('android.app.Notification$BigTextStyle')
53
+ NotificationCompatBigPictureStyle = autoclass('android.app.Notification$BigPictureStyle')
54
+ NotificationCompatInboxStyle = autoclass('android.app.Notification$InboxStyle')
65
55
 
56
+ except Exception as styles_import_error:
57
+ logger.exception(styles_import_error)
66
58
  from .facade import *
59
+
67
60
  else:
68
61
  cast = lambda x, y: x
69
62
  autoclass = lambda x: None
@@ -5,8 +5,8 @@ import os.path
5
5
 
6
6
  from .logger import logger
7
7
  from android_notify.config import on_android_platform, on_flet_app, get_python_activity_context
8
- from android_notify.internal.java_classes import autoclass, BuildVersion, Manifest, Intent, String, Settings, Uri, NotificationManagerCompat
9
- from android_notify.internal.helper import execute_callback
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
10
10
 
11
11
 
12
12
  def has_notification_permission():
@@ -19,10 +19,10 @@ def has_notification_permission():
19
19
 
20
20
  if BuildVersion.SDK_INT < 33: # Android 12 and below
21
21
  try:
22
+ # NotificationManagerCompat is actually NotificationManager from android_notify.internal.java_classes
22
23
  context = get_python_activity_context()
23
- func_from = getattr(NotificationManagerCompat, "from")
24
- compat_manager = func_from(context)
25
- return compat_manager.areNotificationsEnabled()
24
+ nm = context.getSystemService(NotificationManagerCompat)
25
+ return nm.areNotificationsEnabled()
26
26
  except Exception as error_checking_permission:
27
27
  logger.exception(f"On Android 12 and below Error checking permission: {error_checking_permission}")
28
28
  return None
@@ -30,10 +30,8 @@ def has_notification_permission():
30
30
  if on_flet_app():
31
31
  context = get_python_activity_context()
32
32
  permission = Manifest.POST_NOTIFICATIONS
33
- ContextCompat = autoclass('androidx.core.content.ContextCompat')
34
- # if you get error `Failed to find class: androidx/core/app/ActivityCompat`
35
- # in proguard-rules.pro add `-keep class androidx.core.app.ActivityCompat { *; }`
36
- return ContextCompat.checkSelfPermission(context, permission)
33
+
34
+ return PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(permission)
37
35
  else:
38
36
  from android.permissions import Permission, check_permission # type: ignore
39
37
  return check_permission(Permission.POST_NOTIFICATIONS)
@@ -82,21 +80,10 @@ def ask_notification_permission(callback=None, set_requesting_state=None, legacy
82
80
  execute_callback(callback, grants[0])
83
81
  execute_callback(set_requesting_state, False,from_who="package")
84
82
 
85
- if legacy:
83
+ if legacy or on_flet_app() or on_pydroid_app():
86
84
  # TODO Handle activity with request code
87
- PackageManager = autoclass("android.content.pm.PackageManager")
88
- permission = Manifest.POST_NOTIFICATIONS
89
-
90
- granted = context.checkSelfPermission(permission)
91
- if granted != PackageManager.PERMISSION_GRANTED:
92
- context.requestPermissions([permission], 101)
93
- return None
94
- elif on_flet_app():
95
- # TODO Callback when user answers request question
96
- # Can't bind activity result method is from p4a which is only on kivy
97
- ActivityCompat = autoclass('androidx.core.app.ActivityCompat')
98
85
  permission = Manifest.POST_NOTIFICATIONS
99
- ActivityCompat.requestPermissions(context, [permission], 101)
86
+ context.requestPermissions([permission], 101)
100
87
  return None
101
88
  else:
102
89
  from android.permissions import request_permissions, Permission # type: ignore
@@ -0,0 +1,221 @@
1
+ """ Non-Advanced Stuff """
2
+ import random
3
+ import os
4
+ ON_ANDROID = False
5
+
6
+ def on_flet_app():
7
+ return os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME")
8
+
9
+ def get_activity_class_name():
10
+ ACTIVITY_CLASS_NAME = os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME") # flet python
11
+ if not ACTIVITY_CLASS_NAME:
12
+ try:
13
+ from android import config
14
+ ACTIVITY_CLASS_NAME = getattr(config, "JAVA_NAMESPACE", None)
15
+ except (ImportError, AttributeError):
16
+ ACTIVITY_CLASS_NAME = 'org.kivy.android'
17
+ return ACTIVITY_CLASS_NAME
18
+
19
+ try:
20
+
21
+ from jnius import autoclass # Needs Java to be installed
22
+ # Get the required Java classes
23
+ ACTIVITY_CLASS_NAME = get_activity_class_name()
24
+ PythonActivity = autoclass(ACTIVITY_CLASS_NAME)
25
+ context = PythonActivity.mActivity # Get the app's context
26
+ NotificationChannel = autoclass('android.app.NotificationChannel')
27
+ String = autoclass('java.lang.String')
28
+ Intent = autoclass('android.content.Intent')
29
+ PendingIntent = autoclass('android.app.PendingIntent')
30
+ BitmapFactory = autoclass('android.graphics.BitmapFactory')
31
+ BuildVersion = autoclass('android.os.Build$VERSION')
32
+ ON_ANDROID=True
33
+ except Exception as e:
34
+ print('\nThis Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" to see design patterns and more info.\n')
35
+
36
+ if ON_ANDROID:
37
+ try:
38
+ NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
39
+ NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
40
+
41
+ # Notification Design
42
+ NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
43
+ NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
44
+ NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
45
+ NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
46
+ except Exception as e:
47
+ print("""\n
48
+ Dependency Error: Add the following in buildozer.spec:
49
+ * android.gradle_dependencies = androidx.core:core-ktx:1.15.0, androidx.core:core:1.6.0
50
+ * android.enable_androidx = True
51
+ * android.permissions = POST_NOTIFICATIONS\n
52
+ """)
53
+
54
+
55
+ def get_app_root_path():
56
+ if on_flet_app():
57
+ return os.path.join(context.getFilesDir().getAbsolutePath(),'flet')
58
+ else:
59
+ from android.storage import app_storage_path # type: ignore
60
+ return app_storage_path()
61
+
62
+ def asks_permission_if_needed():
63
+ """
64
+ Ask for permission to send notifications if needed.
65
+ """
66
+ if on_flet_app():
67
+ VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')
68
+ ContextCompat = autoclass('androidx.core.content.ContextCompat')
69
+ # if you get error `Failed to find class: androidx/core/app/ActivityCompat`
70
+ #in proguard-rules.pro add `-keep class androidx.core.app.ActivityCompat { *; }`
71
+ ActivityCompat = autoclass('androidx.core.app.ActivityCompat')
72
+ Manifest = autoclass('android.Manifest$permission')
73
+ VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')
74
+
75
+ if BuildVersion.SDK_INT >= VERSION_CODES.TIRAMISU:
76
+ permission = Manifest.POST_NOTIFICATIONS
77
+ granted = ContextCompat.checkSelfPermission(context, permission)
78
+
79
+ if granted != 0: # PackageManager.PERMISSION_GRANTED == 0
80
+ ActivityCompat.requestPermissions(context, [permission], 101)
81
+ else: # android package is from p4a which is for kivy
82
+ try:
83
+ from android.permissions import request_permissions, Permission,check_permission # type: ignore
84
+ permissions=[Permission.POST_NOTIFICATIONS]
85
+ if not all(check_permission(p) for p in permissions):
86
+ request_permissions(permissions)
87
+ except Exception as e:
88
+ print("android_notify- error trying to request notification access: ", e)
89
+
90
+ def get_image_uri(relative_path):
91
+ """
92
+ Get the absolute URI for an image in the assets folder.
93
+ :param relative_path: The relative path to the image (e.g., 'assets/imgs/icon.png').
94
+ :return: Absolute URI java Object (e.g., 'file:///path/to/file.png').
95
+ """
96
+ app_root_path = get_app_root_path()
97
+ output_path = os.path.join(app_root_path,'app', relative_path)
98
+ # print(output_path,'output_path') # /data/user/0/org.laner.lan_ft/files/app/assets/imgs/icon.png
99
+
100
+ if not os.path.exists(output_path):
101
+ raise FileNotFoundError(f"\nImage not found at path: {output_path}\n")
102
+
103
+ Uri = autoclass('android.net.Uri')
104
+ return Uri.parse(f"file://{output_path}")
105
+
106
+ def get_icon_object(uri):
107
+ BitmapFactory = autoclass('android.graphics.BitmapFactory')
108
+ IconCompat = autoclass('androidx.core.graphics.drawable.IconCompat')
109
+
110
+ bitmap= BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
111
+ return IconCompat.createWithBitmap(bitmap)
112
+
113
+ def insert_app_icon(builder,custom_icon_path):
114
+ if custom_icon_path:
115
+ try:
116
+ uri = get_image_uri(custom_icon_path)
117
+ icon = get_icon_object(uri)
118
+ builder.setSmallIcon(icon)
119
+ except Exception as e:
120
+ print('android_notify- error: ',e)
121
+ builder.setSmallIcon(context.getApplicationInfo().icon)
122
+ else:
123
+ print('Found res icon -->',context.getApplicationInfo().icon,'<--')
124
+ builder.setSmallIcon(context.getApplicationInfo().icon)
125
+
126
+ def send_notification(
127
+ title:str,
128
+ message:str,
129
+ style=None,
130
+ img_path=None,
131
+ channel_name="Default Channel",
132
+ channel_id:str="default_channel",
133
+ custom_app_icon_path="",
134
+
135
+ big_picture_path='',
136
+ large_icon_path='',
137
+ big_text="",
138
+ lines=""
139
+ ):
140
+ """
141
+ Send a notification on Android.
142
+
143
+ :param title: Title of the notification.
144
+ :param message: Message body.
145
+ :param style: Style of the notification ('big_text', 'big_picture', 'inbox', 'large_icon').
146
+ :param img_path: Path to the image resource.
147
+ :param channel_id: Notification channel ID.(Default is lowercase channel name arg in lowercase)
148
+ """
149
+ if not ON_ANDROID:
150
+ print('This Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" for Documentation.')
151
+ return
152
+
153
+ asks_permission_if_needed()
154
+ channel_id=channel_name.replace(' ','_').lower().lower() if not channel_id else channel_id
155
+ # Get notification manager
156
+ notification_manager = context.getSystemService(context.NOTIFICATION_SERVICE)
157
+
158
+ # importance= autoclass('android.app.NotificationManager').IMPORTANCE_HIGH # also works #NotificationManager.IMPORTANCE_DEFAULT
159
+ importance= NotificationManagerCompat.IMPORTANCE_HIGH #autoclass('android.app.NotificationManager').IMPORTANCE_HIGH also works #NotificationManager.IMPORTANCE_DEFAULT
160
+
161
+ # Notification Channel (Required for Android 8.0+)
162
+ if BuildVersion.SDK_INT >= 26:
163
+ channel = NotificationChannel(channel_id, channel_name,importance)
164
+ notification_manager.createNotificationChannel(channel)
165
+
166
+ # Build the notification
167
+ builder = NotificationCompatBuilder(context, channel_id)
168
+ builder.setContentTitle(title)
169
+ builder.setContentText(message)
170
+ insert_app_icon(builder,custom_app_icon_path)
171
+ builder.setDefaults(NotificationCompat.DEFAULT_ALL)
172
+ builder.setPriority(NotificationCompat.PRIORITY_HIGH)
173
+
174
+ if img_path:
175
+ print('android_notify- img_path arg deprecated use "large_icon_path or big_picture_path or custom_app_icon_path"instead ')
176
+
177
+ big_picture = None
178
+ if big_picture_path:
179
+ try:
180
+ big_picture = get_image_uri(big_picture_path)
181
+ except FileNotFoundError as e:
182
+ print('android_notify- Error Getting Uri for big_picture_path: ',e)
183
+
184
+ large_icon = None
185
+ if large_icon_path:
186
+ try:
187
+ large_icon = get_image_uri(large_icon_path)
188
+ except FileNotFoundError as e:
189
+ print('android_notify- Error Getting Uri for large_icon_path: ',e)
190
+
191
+
192
+ # Apply notification styles
193
+ try:
194
+ if big_text:
195
+ big_text_style = NotificationCompatBigTextStyle()
196
+ big_text_style.bigText(big_text)
197
+ builder.setStyle(big_text_style)
198
+
199
+ elif lines:
200
+ inbox_style = NotificationCompatInboxStyle()
201
+ for line in lines.split("\n"):
202
+ inbox_style.addLine(line)
203
+ builder.setStyle(inbox_style)
204
+
205
+ if large_icon:
206
+ bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(large_icon))
207
+ builder.setLargeIcon(bitmap)
208
+
209
+ if big_picture:
210
+ bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(big_picture))
211
+ builder.setLargeIcon(bitmap)
212
+ big_picture_style = NotificationCompatBigPictureStyle().bigPicture(bitmap)
213
+ builder.setStyle(big_picture_style)
214
+
215
+ except Exception as e:
216
+ print('android_notify- Error Failed Adding Style: ',e)
217
+ # Display the notification
218
+ notification_id = random.randint(0, 100)
219
+ notification_manager.notify(notification_id, builder.build())
220
+ return notification_id
221
+
@@ -0,0 +1,221 @@
1
+ """ Non-Advanced Stuff """
2
+ import random
3
+ import os
4
+ ON_ANDROID = False
5
+
6
+ def on_flet_app():
7
+ return os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME")
8
+
9
+ def get_activity_class_name():
10
+ ACTIVITY_CLASS_NAME = os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME") # flet python
11
+ if not ACTIVITY_CLASS_NAME:
12
+ try:
13
+ from android import config
14
+ ACTIVITY_CLASS_NAME = getattr(config, "JAVA_NAMESPACE", None)
15
+ except (ImportError, AttributeError):
16
+ ACTIVITY_CLASS_NAME = 'org.kivy.android'
17
+ return ACTIVITY_CLASS_NAME
18
+
19
+ try:
20
+
21
+ from jnius import autoclass # Needs Java to be installed
22
+ # Get the required Java classes
23
+ ACTIVITY_CLASS_NAME = get_activity_class_name()
24
+ PythonActivity = autoclass(ACTIVITY_CLASS_NAME)
25
+ context = PythonActivity.mActivity # Get the app's context
26
+ NotificationChannel = autoclass('android.app.NotificationChannel')
27
+ String = autoclass('java.lang.String')
28
+ Intent = autoclass('android.content.Intent')
29
+ PendingIntent = autoclass('android.app.PendingIntent')
30
+ BitmapFactory = autoclass('android.graphics.BitmapFactory')
31
+ BuildVersion = autoclass('android.os.Build$VERSION')
32
+ ON_ANDROID=True
33
+ except Exception as e:
34
+ print('\nThis Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" to see design patterns and more info.\n')
35
+
36
+ if ON_ANDROID:
37
+ try:
38
+ NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
39
+ NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
40
+
41
+ # Notification Design
42
+ NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
43
+ NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
44
+ NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
45
+ NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
46
+ except Exception as e:
47
+ print("""\n
48
+ Dependency Error: Add the following in buildozer.spec:
49
+ * android.gradle_dependencies = androidx.core:core-ktx:1.15.0, androidx.core:core:1.6.0
50
+ * android.enable_androidx = True
51
+ * android.permissions = POST_NOTIFICATIONS\n
52
+ """)
53
+
54
+
55
+ def get_app_root_path():
56
+ if on_flet_app():
57
+ return os.path.join(context.getFilesDir().getAbsolutePath(),'flet')
58
+ else:
59
+ from android.storage import app_storage_path # type: ignore
60
+ return app_storage_path()
61
+
62
+ def asks_permission_if_needed():
63
+ """
64
+ Ask for permission to send notifications if needed.
65
+ """
66
+ if on_flet_app():
67
+ VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')
68
+ ContextCompat = autoclass('androidx.core.content.ContextCompat')
69
+ # if you get error `Failed to find class: androidx/core/app/ActivityCompat`
70
+ #in proguard-rules.pro add `-keep class androidx.core.app.ActivityCompat { *; }`
71
+ ActivityCompat = autoclass('androidx.core.app.ActivityCompat')
72
+ Manifest = autoclass('android.Manifest$permission')
73
+ VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')
74
+
75
+ if BuildVersion.SDK_INT >= VERSION_CODES.TIRAMISU:
76
+ permission = Manifest.POST_NOTIFICATIONS
77
+ granted = ContextCompat.checkSelfPermission(context, permission)
78
+
79
+ if granted != 0: # PackageManager.PERMISSION_GRANTED == 0
80
+ ActivityCompat.requestPermissions(context, [permission], 101)
81
+ else: # android package is from p4a which is for kivy
82
+ try:
83
+ from android.permissions import request_permissions, Permission,check_permission # type: ignore
84
+ permissions=[Permission.POST_NOTIFICATIONS]
85
+ if not all(check_permission(p) for p in permissions):
86
+ request_permissions(permissions)
87
+ except Exception as e:
88
+ print("android_notify- error trying to request notification access: ", e)
89
+
90
+ def get_image_uri(relative_path):
91
+ """
92
+ Get the absolute URI for an image in the assets folder.
93
+ :param relative_path: The relative path to the image (e.g., 'assets/imgs/icon.png').
94
+ :return: Absolute URI java Object (e.g., 'file:///path/to/file.png').
95
+ """
96
+ app_root_path = get_app_root_path()
97
+ output_path = os.path.join(app_root_path,'app', relative_path)
98
+ # print(output_path,'output_path') # /data/user/0/org.laner.lan_ft/files/app/assets/imgs/icon.png
99
+
100
+ if not os.path.exists(output_path):
101
+ raise FileNotFoundError(f"\nImage not found at path: {output_path}\n")
102
+
103
+ Uri = autoclass('android.net.Uri')
104
+ return Uri.parse(f"file://{output_path}")
105
+
106
+ def get_icon_object(uri):
107
+ BitmapFactory = autoclass('android.graphics.BitmapFactory')
108
+ IconCompat = autoclass('androidx.core.graphics.drawable.IconCompat')
109
+
110
+ bitmap= BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
111
+ return IconCompat.createWithBitmap(bitmap)
112
+
113
+ def insert_app_icon(builder,custom_icon_path):
114
+ if custom_icon_path:
115
+ try:
116
+ uri = get_image_uri(custom_icon_path)
117
+ icon = get_icon_object(uri)
118
+ builder.setSmallIcon(icon)
119
+ except Exception as e:
120
+ print('android_notify- error: ',e)
121
+ builder.setSmallIcon(context.getApplicationInfo().icon)
122
+ else:
123
+ print('Found res icon -->',context.getApplicationInfo().icon,'<--')
124
+ builder.setSmallIcon(context.getApplicationInfo().icon)
125
+
126
+ def send_notification(
127
+ title:str,
128
+ message:str,
129
+ style=None,
130
+ img_path=None,
131
+ channel_name="Default Channel",
132
+ channel_id:str="default_channel",
133
+ custom_app_icon_path="",
134
+
135
+ big_picture_path='',
136
+ large_icon_path='',
137
+ big_text="",
138
+ lines=""
139
+ ):
140
+ """
141
+ Send a notification on Android.
142
+
143
+ :param title: Title of the notification.
144
+ :param message: Message body.
145
+ :param style: Style of the notification ('big_text', 'big_picture', 'inbox', 'large_icon').
146
+ :param img_path: Path to the image resource.
147
+ :param channel_id: Notification channel ID.(Default is lowercase channel name arg in lowercase)
148
+ """
149
+ if not ON_ANDROID:
150
+ print('This Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" for Documentation.')
151
+ return
152
+
153
+ asks_permission_if_needed()
154
+ channel_id=channel_name.replace(' ','_').lower().lower() if not channel_id else channel_id
155
+ # Get notification manager
156
+ notification_manager = context.getSystemService(context.NOTIFICATION_SERVICE)
157
+
158
+ # importance= autoclass('android.app.NotificationManager').IMPORTANCE_HIGH # also works #NotificationManager.IMPORTANCE_DEFAULT
159
+ importance= NotificationManagerCompat.IMPORTANCE_HIGH #autoclass('android.app.NotificationManager').IMPORTANCE_HIGH also works #NotificationManager.IMPORTANCE_DEFAULT
160
+
161
+ # Notification Channel (Required for Android 8.0+)
162
+ if BuildVersion.SDK_INT >= 26:
163
+ channel = NotificationChannel(channel_id, channel_name,importance)
164
+ notification_manager.createNotificationChannel(channel)
165
+
166
+ # Build the notification
167
+ builder = NotificationCompatBuilder(context, channel_id)
168
+ builder.setContentTitle(title)
169
+ builder.setContentText(message)
170
+ insert_app_icon(builder,custom_app_icon_path)
171
+ builder.setDefaults(NotificationCompat.DEFAULT_ALL)
172
+ builder.setPriority(NotificationCompat.PRIORITY_HIGH)
173
+
174
+ if img_path:
175
+ print('android_notify- img_path arg deprecated use "large_icon_path or big_picture_path or custom_app_icon_path"instead ')
176
+
177
+ big_picture = None
178
+ if big_picture_path:
179
+ try:
180
+ big_picture = get_image_uri(big_picture_path)
181
+ except FileNotFoundError as e:
182
+ print('android_notify- Error Getting Uri for big_picture_path: ',e)
183
+
184
+ large_icon = None
185
+ if large_icon_path:
186
+ try:
187
+ large_icon = get_image_uri(large_icon_path)
188
+ except FileNotFoundError as e:
189
+ print('android_notify- Error Getting Uri for large_icon_path: ',e)
190
+
191
+
192
+ # Apply notification styles
193
+ try:
194
+ if big_text:
195
+ big_text_style = NotificationCompatBigTextStyle()
196
+ big_text_style.bigText(big_text)
197
+ builder.setStyle(big_text_style)
198
+
199
+ elif lines:
200
+ inbox_style = NotificationCompatInboxStyle()
201
+ for line in lines.split("\n"):
202
+ inbox_style.addLine(line)
203
+ builder.setStyle(inbox_style)
204
+
205
+ if large_icon:
206
+ bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(large_icon))
207
+ builder.setLargeIcon(bitmap)
208
+
209
+ if big_picture:
210
+ bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(big_picture))
211
+ builder.setLargeIcon(bitmap)
212
+ big_picture_style = NotificationCompatBigPictureStyle().bigPicture(bitmap)
213
+ builder.setStyle(big_picture_style)
214
+
215
+ except Exception as e:
216
+ print('android_notify- Error Failed Adding Style: ',e)
217
+ # Display the notification
218
+ notification_id = random.randint(0, 100)
219
+ notification_manager.notify(notification_id, builder.build())
220
+ return notification_id
221
+
@@ -4,7 +4,7 @@ For image related things
4
4
  import os
5
5
 
6
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, IconCompat
7
+ from android_notify.internal.java_classes import autoclass, BitmapFactory, Uri, BuildVersion, Color
8
8
  from android_notify.internal.helper import get_package_path
9
9
  from android_notify.internal.logger import logger
10
10
 
@@ -128,6 +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')
131
132
  icon = IconCompat.createWithBitmap(bitmap)
132
133
  builder.setSmallIcon(icon)
133
134
  return True
@@ -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, NotificationCompatDecoratedCustomViewStyle
109
+ from android_notify.internal.java_classes import Color, RemoteViews
110
110
  from android_notify.internal.logger import logger
111
111
  from android_notify.config import get_python_activity_context
112
112
 
@@ -121,6 +121,10 @@ 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
+
124
128
  context = get_python_activity_context()
125
129
  resources = context.getResources()
126
130
  package_name = context.getPackageName()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: android-notify
3
- Version: 1.61.0
3
+ Version: 1.61.0.dev0
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
@@ -81,14 +81,9 @@ In your **`buildozer.spec`** file, ensure you include the following:
81
81
 
82
82
  ```ini
83
83
  # Add pyjnius so ensure it's packaged with the build
84
- requirements = python3, kivy, pyjnius, android-notify
84
+ requirements = python3, kivy, pyjnius, android-notify==1.61.0.dev0
85
85
  # Add permission for notifications
86
86
  android.permissions = POST_NOTIFICATIONS
87
-
88
- # Required dependency (write exactly as shown, no quotation marks)
89
- android.gradle_dependencies = androidx.core:core-ktx:1.15.0
90
- android.enable_androidx = True
91
- android.api = 35
92
87
  ```
93
88
 
94
89
  </details>
@@ -98,7 +93,7 @@ android.api = 35
98
93
  <summary><b>Flet apps:</b></summary>
99
94
  <br/>
100
95
 
101
- In your `pyproject.toml` file, ensure you include the following:
96
+ In your `pyproject.toml` file, ensure you include the following:
102
97
 
103
98
 
104
99
  ```toml
@@ -114,35 +109,7 @@ dependencies = [
114
109
 
115
110
  </details>
116
111
 
117
- <details>
118
-
119
- <summary><b>Desktop</b></summary>
120
- <br/>
121
-
122
- For IDE IntelliSense Can be installed via `pip install`:
123
-
124
- ```bash
125
- pip install android_notify
126
- android-notify -v
127
- ```
128
-
129
- </details>
130
-
131
- ------
132
- ## Installing without Androidx
133
- How to use without `gradle_dependencies`
134
- Use `android-notify==1.61.0.dev0` to install via `pip`
135
-
136
- <details>
137
- <summary><b>In Kivy</b></summary>
138
- <br/>
139
-
140
- ```ini
141
- # buildozer.spec
142
- requirements = python3, kivy, pyjnius, android-notify==1.61.0.dev0
143
- ```
144
112
 
145
- </details>
146
113
 
147
114
  <details>
148
115
 
@@ -180,7 +147,9 @@ class AndroidNotifyDemoApp(App):
180
147
  def send_notification(self, *args):
181
148
  Notification(
182
149
  title="Hello from Android Notify",
183
- message="This is a basic notification."
150
+ message="This is a basic notification.",
151
+ channel_id="android_notify_demo",
152
+ channel_name="Android Notify Demo"
184
153
  ).send()
185
154
 
186
155
 
@@ -191,11 +160,23 @@ if __name__ == "__main__":
191
160
  </details>
192
161
 
193
162
 
163
+ <details>
164
+
165
+ <summary><b>Desktop</b></summary>
166
+ <br/>
167
+
168
+ For IDE IntelliSense Can be installed via `pip install`:
169
+
170
+ ```bash
171
+ pip install android_notify
172
+ android-notify -v
173
+ ```
174
+ </details>
194
175
 
195
176
  ## Documentation
196
- For Dev Version usage
177
+ For Dev Version use
197
178
  ```ini
198
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
179
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
199
180
  ```
200
181
 
201
182
  <details>
@@ -204,7 +185,7 @@ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_noti
204
185
  - Make things happen without being in your app
205
186
  ```python
206
187
  from android_notify import Notification
207
- notification = Notification(title="Reciver Notification")
188
+ notification = Notification(title="Receiver Notification")
208
189
  notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
209
190
  notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
210
191
  ```
@@ -267,7 +248,7 @@ Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
267
248
 
268
249
  n=Notification(title='Vibrate',channel_id='shake')
269
250
  n.setVibrate() # for less than android 8
270
- n.fVibrate() # To Force Vibrate
251
+ n.fVibrate() # To Force Vibrate (when user turned off in settings)
271
252
  n.send()
272
253
  ```
273
254
 
@@ -305,5 +286,9 @@ from android_notify import Notification, NotificationHandler
305
286
 
306
287
  ## ☕ Support the Project
307
288
 
308
- If you find this project helpful, your support would help me continue working on open-source projects
309
- [donate](https://www.buymeacoffee.com/fector101)
289
+ If you find this project helpful, consider buying me a coffee! 😊
290
+ Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify/) Your support helps maintain and improve the project.
291
+
292
+ <a href="https://www.buymeacoffee.com/fector101" target="_blank">
293
+ <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
294
+ </a>
@@ -41,7 +41,9 @@ android_notify/tests/test_notification_styles.py
41
41
  android_notify/tests/flet/adv/main.py
42
42
  android_notify/tests/flet/adv/tests/__init__.py
43
43
  android_notify/tests/flet/adv/tests/test_android_notify_full.py
44
+ android_notify/tests/flet/basic/src/core.py
44
45
  android_notify/tests/flet/basic/src/main.py
46
+ android_notify/tests/flet/flet-working/src/core.py
45
47
  android_notify/tests/flet/flet-working/src/main.py
46
48
  android_notify/tests/p4a/hook.py
47
49
  android_notify/tests/serivces/wallpaper.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "android-notify"
7
- version = "1.61.0"
7
+ version = "1.61.0.dev0"
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
  authors = [