android-notify 1.60.8.dev0__tar.gz → 1.60.9__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.60.8.dev0 → android_notify-1.60.9}/PKG-INFO +45 -28
  2. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/README.md +44 -27
  3. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/config.py +1 -2
  4. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/core.py +4 -3
  5. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/facade.py +68 -28
  6. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/java_classes.py +17 -10
  7. android_notify-1.60.9/android_notify/internal/logger.py +94 -0
  8. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/permissions.py +39 -11
  9. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/sword.py +9 -2
  10. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_permission.py +0 -2
  11. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/widgets/images.py +1 -2
  12. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/widgets/texts.py +10 -8
  13. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify.egg-info/PKG-INFO +45 -28
  14. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify.egg-info/SOURCES.txt +0 -2
  15. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/pyproject.toml +1 -1
  16. android_notify-1.60.8.dev0/android_notify/internal/logger.py +0 -61
  17. android_notify-1.60.8.dev0/android_notify/tests/flet/basic/src/core.py +0 -221
  18. android_notify-1.60.8.dev0/android_notify/tests/flet/flet-working/src/core.py +0 -221
  19. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/__init__.py +0 -0
  20. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/__main__.py +0 -0
  21. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/base.py +0 -0
  22. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/fallback-icons/flet-appicon.png +0 -0
  23. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/fallback-icons/pydroid3-appicon.png +0 -0
  24. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/an_types.py +0 -0
  25. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/android.py +0 -0
  26. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/channels.py +0 -0
  27. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/helper.py +0 -0
  28. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/internal/intents.py +0 -0
  29. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/styles.py +0 -0
  30. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/__init__.py +0 -0
  31. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/android_notify_test.py +0 -0
  32. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/base_test.py +0 -0
  33. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/flet/adv/main.py +0 -0
  34. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/flet/adv/tests/__init__.py +0 -0
  35. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/flet/adv/tests/test_android_notify_full.py +0 -0
  36. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/flet/basic/src/main.py +0 -0
  37. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/flet/flet-working/src/main.py +0 -0
  38. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/main.py +0 -0
  39. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/p4a/hook.py +0 -0
  40. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/serivces/wallpaper.py +0 -0
  41. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_basic_notifications.py +0 -0
  42. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_actions.py +0 -0
  43. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_appearance.py +0 -0
  44. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_behavior.py +0 -0
  45. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_channels.py +0 -0
  46. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_clear.py +0 -0
  47. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_progress.py +0 -0
  48. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_sound.py +0 -0
  49. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify/tests/test_notification_styles.py +0 -0
  50. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify.egg-info/dependency_links.txt +0 -0
  51. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify.egg-info/entry_points.txt +0 -0
  52. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify.egg-info/requires.txt +0 -0
  53. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/android_notify.egg-info/top_level.txt +0 -0
  54. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/docs/website/src/pages/data/laner_Sent.py +0 -0
  55. {android_notify-1.60.8.dev0 → android_notify-1.60.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: android-notify
3
- Version: 1.60.8.dev0
3
+ Version: 1.60.9
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,9 +81,14 @@ 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==1.60.8.dev0
84
+ requirements = python3, kivy, pyjnius, android-notify
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
87
92
  ```
88
93
 
89
94
  </details>
@@ -93,13 +98,13 @@ android.permissions = POST_NOTIFICATIONS
93
98
  <summary><b>Flet apps:</b></summary>
94
99
  <br/>
95
100
 
96
- In your `pyproject.toml` file, ensure you include the following:
101
+ In your `pyproject.toml` file, ensure you include the following:
97
102
 
98
103
 
99
104
  ```toml
100
105
  [tool.flet.android]
101
106
  dependencies = [
102
- "pyjnius","android-notify==1.60.8.dev0"
107
+ "pyjnius","android-notify==1.60.9.dev0"
103
108
  ]
104
109
 
105
110
  [tool.flet.android.permission]
@@ -109,7 +114,35 @@ dependencies = [
109
114
 
110
115
  </details>
111
116
 
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.60.9.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.60.9.dev0
143
+ ```
112
144
 
145
+ </details>
113
146
 
114
147
  <details>
115
148
 
@@ -117,10 +150,10 @@ dependencies = [
117
150
  <br/>
118
151
 
119
152
  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.
120
- - In pip section where you're asked to insert `Libary name` paste `android-notify==1.60.8.dev0`
153
+ - In pip section where you're asked to insert `Libary name` paste `android-notify==1.60.9.dev0`
121
154
  - Minimal working example
122
155
  ```py
123
- # Testing with `android-notify==1.60.8.dev0` on pydroid
156
+ # Testing with `android-notify==1.60.9.dev0` on pydroid
124
157
  from kivy.app import App
125
158
  from kivy.uix.boxlayout import BoxLayout
126
159
  from kivy.uix.button import Button
@@ -160,23 +193,11 @@ if __name__ == "__main__":
160
193
  </details>
161
194
 
162
195
 
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>
175
196
 
176
197
  ## Documentation
177
- For Dev Version use
198
+ For Dev Version usage
178
199
  ```ini
179
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
200
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
180
201
  ```
181
202
 
182
203
  <details>
@@ -185,7 +206,7 @@ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_noti
185
206
  - Make things happen without being in your app
186
207
  ```python
187
208
  from android_notify import Notification
188
- notification = Notification(title="Receiver Notification")
209
+ notification = Notification(title="Reciver Notification")
189
210
  notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
190
211
  notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
191
212
  ```
@@ -248,7 +269,7 @@ Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
248
269
 
249
270
  n=Notification(title='Vibrate',channel_id='shake')
250
271
  n.setVibrate() # for less than android 8
251
- n.fVibrate() # To Force Vibrate (when user turned off in settings)
272
+ n.fVibrate() # To Force Vibrate
252
273
  n.send()
253
274
  ```
254
275
 
@@ -286,9 +307,5 @@ from android_notify import Notification, NotificationHandler
286
307
 
287
308
  ## ☕ Support the Project
288
309
 
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>
310
+ If you find this project helpful, your support would help me continue working on open-source projects
311
+ [donate](https://www.buymeacoffee.com/fector101)
@@ -58,9 +58,14 @@ 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==1.60.8.dev0
61
+ requirements = python3, kivy, pyjnius, android-notify
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
64
69
  ```
65
70
 
66
71
  </details>
@@ -70,13 +75,13 @@ android.permissions = POST_NOTIFICATIONS
70
75
  <summary><b>Flet apps:</b></summary>
71
76
  <br/>
72
77
 
73
- In your `pyproject.toml` file, ensure you include the following:
78
+ In your `pyproject.toml` file, ensure you include the following:
74
79
 
75
80
 
76
81
  ```toml
77
82
  [tool.flet.android]
78
83
  dependencies = [
79
- "pyjnius","android-notify==1.60.8.dev0"
84
+ "pyjnius","android-notify==1.60.9.dev0"
80
85
  ]
81
86
 
82
87
  [tool.flet.android.permission]
@@ -86,7 +91,35 @@ dependencies = [
86
91
 
87
92
  </details>
88
93
 
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.60.9.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.60.9.dev0
120
+ ```
89
121
 
122
+ </details>
90
123
 
91
124
  <details>
92
125
 
@@ -94,10 +127,10 @@ dependencies = [
94
127
  <br/>
95
128
 
96
129
  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.60.8.dev0`
130
+ - In pip section where you're asked to insert `Libary name` paste `android-notify==1.60.9.dev0`
98
131
  - Minimal working example
99
132
  ```py
100
- # Testing with `android-notify==1.60.8.dev0` on pydroid
133
+ # Testing with `android-notify==1.60.9.dev0` on pydroid
101
134
  from kivy.app import App
102
135
  from kivy.uix.boxlayout import BoxLayout
103
136
  from kivy.uix.button import Button
@@ -137,23 +170,11 @@ if __name__ == "__main__":
137
170
  </details>
138
171
 
139
172
 
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>
152
173
 
153
174
  ## Documentation
154
- For Dev Version use
175
+ For Dev Version usage
155
176
  ```ini
156
- requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
177
+ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/main.zip
157
178
  ```
158
179
 
159
180
  <details>
@@ -162,7 +183,7 @@ requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_noti
162
183
  - Make things happen without being in your app
163
184
  ```python
164
185
  from android_notify import Notification
165
- notification = Notification(title="Receiver Notification")
186
+ notification = Notification(title="Reciver Notification")
166
187
  notification.addButton(text="Stop", receiver_name="CarouselReceiver", action="ACTION_STOP")
167
188
  notification.addButton(text="Skip", receiver_name="CarouselReceiver", action="ACTION_SKIP")
168
189
  ```
@@ -225,7 +246,7 @@ Notification.createChannel(id='shake', name="Shake Passage", vibrate=True)
225
246
 
226
247
  n=Notification(title='Vibrate',channel_id='shake')
227
248
  n.setVibrate() # for less than android 8
228
- n.fVibrate() # To Force Vibrate (when user turned off in settings)
249
+ n.fVibrate() # To Force Vibrate
229
250
  n.send()
230
251
  ```
231
252
 
@@ -263,9 +284,5 @@ from android_notify import Notification, NotificationHandler
263
284
 
264
285
  ## ☕ Support the Project
265
286
 
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>
287
+ If you find this project helpful, your support would help me continue working on open-source projects
288
+ [donate](https://www.buymeacoffee.com/fector101)
@@ -1,7 +1,6 @@
1
1
  import os
2
2
 
3
- __version__ = "1.60.8.dev0"
4
-
3
+ __version__ = "1.60.9"
5
4
 
6
5
  from .internal.java_classes import autoclass, cast, NotificationManager
7
6
  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
9
+ NotificationCompatBigTextStyle, NotificationCompatBigPictureStyle, NotificationCompatInboxStyle, IconCompat
10
10
 
11
11
 
12
12
 
@@ -60,7 +60,6 @@ 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')
64
63
  bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
65
64
  return IconCompat.createWithBitmap(bitmap)
66
65
 
@@ -115,7 +114,9 @@ def send_notification(
115
114
  return None
116
115
  context = get_python_activity_context()
117
116
 
118
- asks_permission_if_needed(legacy=True)
117
+
118
+ asks_permission_if_needed()
119
+
119
120
  channel_id = channel_name.replace(' ', '_').lower().lower() if not channel_id else channel_id
120
121
  # Get notification manager
121
122
  notification_manager = context.getSystemService(context.NOTIFICATION_SERVICE)
@@ -3,8 +3,10 @@ For autocomplete Storing and Safely Running on PC
3
3
  Also For Reference of Available Methods
4
4
  """
5
5
 
6
+ from enum import IntFlag, auto
6
7
  from android_notify.internal.logger import logger
7
8
 
9
+
8
10
  class Bundle:
9
11
  def putString(self, key, value):
10
12
  logger.debug(f"[MOCK] Bundle.putString called with key={key}, value={value}")
@@ -19,11 +21,16 @@ class String(str):
19
21
  return str.__new__(cls, value)
20
22
 
21
23
 
22
- class Intent:
23
- FLAG_ACTIVITY_NEW_TASK = 'FACADE_FLAG_ACTIVITY_NEW_TASK'
24
- CATEGORY_DEFAULT = 'FACADE_FLAG_CATEGORY_DEFAULT'
24
+
25
+
26
+ class Intent(IntFlag):
27
+ NONE = 0
28
+ FLAG_ACTIVITY_CLEAR_TOP = auto()
29
+ FLAG_ACTIVITY_NEW_TASK = auto()
30
+ FLAG_ACTIVITY_SINGLE_TOP = auto()
25
31
 
26
32
  def __init__(self, context='', activity=''):
33
+ self.IS = "FACADE"
27
34
  self.obj = {}
28
35
  logger.debug(f"[MOCK] Intent initialized with context={context}, activity={activity}")
29
36
 
@@ -132,12 +139,13 @@ class NotificationChannel:
132
139
  def setSound(self, sound_uri, _):
133
140
  logger.debug(f"[MOCK] NotificationChannel.setSound called, sound_uri={sound_uri}")
134
141
 
135
- def enableVibration(self,state):
142
+ def enableVibration(self, state):
136
143
  logger.debug(f"[MOCK] NotificationChannel.enableVibration called, state={state}")
137
144
 
138
- def setVibrationPattern(self,list_of_numbers):
145
+ def setVibrationPattern(self, list_of_numbers):
139
146
  logger.debug(f"[MOCK] NotificationChannel.setVibrationPattern called, list_of_numbers={list_of_numbers}")
140
147
 
148
+
141
149
  class IconCompat:
142
150
  @classmethod
143
151
  def createWithBitmap(cls, bitmap):
@@ -175,6 +183,7 @@ class NotificationManagerCompat:
175
183
  IMPORTANCE_MIN = ''
176
184
  IMPORTANCE_NONE = ''
177
185
 
186
+
178
187
  class AndroidNotification:
179
188
  DEFAULT_ALL = 3
180
189
  PRIORITY_HIGH = 4
@@ -182,6 +191,7 @@ class AndroidNotification:
182
191
  PRIORITY_LOW = ''
183
192
  PRIORITY_MIN = ''
184
193
 
194
+
185
195
  class NotificationCompat:
186
196
  DEFAULT_ALL = 3
187
197
  PRIORITY_HIGH = 4
@@ -201,76 +211,97 @@ class NotificationCompatBuilder:
201
211
  self.mActions = MActions()
202
212
  logger.debug(f"[MOCK] NotificationCompatBuilder initialized with context={context}, channel_id={channel_id}")
203
213
 
204
- def setProgress(self, max_value, current_value, endless):
214
+ @classmethod
215
+ def setProgress(cls, max_value, current_value, endless):
205
216
  logger.debug(f"[MOCK] setProgress called with max={max_value}, current={current_value}, endless={endless}")
206
217
 
207
- def setStyle(self, style):
218
+ @classmethod
219
+ def setStyle(cls, style):
208
220
  logger.debug(f"[MOCK] setStyle called with style={style}")
209
221
 
210
- def setContentTitle(self, title):
222
+ @classmethod
223
+ def setContentTitle(cls, title):
211
224
  logger.debug(f"[MOCK] setContentTitle called with title={title}")
212
225
 
213
- def setContentText(self, text):
226
+ @classmethod
227
+ def setContentText(cls, text):
214
228
  logger.debug(f"[MOCK] setContentText called with text={text}")
215
229
 
216
- def setSmallIcon(self, icon):
230
+ @classmethod
231
+ def setSmallIcon(cls, icon):
217
232
  logger.debug(f"[MOCK] setSmallIcon called with icon={icon}")
218
233
 
219
- def setLargeIcon(self, icon):
234
+ @classmethod
235
+ def setLargeIcon(cls, icon):
220
236
  logger.debug(f"[MOCK] setLargeIcon called with icon={icon}")
221
237
 
222
- def setAutoCancel(self, auto_cancel: bool):
238
+ @classmethod
239
+ def setAutoCancel(cls, auto_cancel: bool):
223
240
  logger.debug(f"[MOCK] setAutoCancel called with auto_cancel={auto_cancel}")
224
241
 
225
- def setPriority(self, priority):
242
+ @classmethod
243
+ def setPriority(cls, priority):
226
244
  logger.debug(f"[MOCK] setPriority called with priority={priority}")
227
245
 
228
- def setDefaults(self, defaults):
246
+ @classmethod
247
+ def setDefaults(cls, defaults):
229
248
  logger.debug(f"[MOCK] setDefaults called with defaults={defaults}")
230
249
 
231
- def setOngoing(self, persistent: bool):
250
+ @classmethod
251
+ def setOngoing(cls, persistent: bool):
232
252
  logger.debug(f"[MOCK] setOngoing called with persistent={persistent}")
233
253
 
234
- def setOnlyAlertOnce(self, state):
254
+ @classmethod
255
+ def setOnlyAlertOnce(cls, state):
235
256
  logger.debug(f"[MOCK] setOnlyAlertOnce called with state={state}")
236
257
 
237
- def build(self):
258
+ @classmethod
259
+ def build(cls):
238
260
  logger.debug("[MOCK] build called")
239
261
 
240
- def setContentIntent(self, pending_action_intent: PendingIntent):
262
+ @classmethod
263
+ def setContentIntent(cls, pending_action_intent: PendingIntent):
241
264
  logger.debug(f"[MOCK] setContentIntent called with {pending_action_intent}")
242
265
 
243
- def addAction(self, icon_int, action_text, pending_action_intent):
266
+ @classmethod
267
+ def addAction(cls, icon_int, action_text, pending_action_intent):
244
268
  logger.debug(
245
269
  f"[MOCK] addAction called with icon={icon_int}, text={action_text}, intent={pending_action_intent}"
246
270
  )
247
271
 
248
- def setShowWhen(self, state):
272
+ @classmethod
273
+ def setShowWhen(cls, state):
249
274
  logger.debug(f"[MOCK] setShowWhen called with state={state}")
250
275
 
251
- def setWhen(self, time_ms):
276
+ @classmethod
277
+ def setWhen(cls, time_ms):
252
278
  logger.debug(f"[MOCK] setWhen called with time_ms={time_ms}")
253
279
 
254
- def setCustomContentView(self, layout):
280
+ @classmethod
281
+ def setCustomContentView(cls, layout):
255
282
  logger.debug(f"[MOCK] setCustomContentView called with layout={layout}")
256
283
 
257
- def setCustomBigContentView(self, layout):
284
+ @classmethod
285
+ def setCustomBigContentView(cls, layout):
258
286
  logger.debug(f"[MOCK] setCustomBigContentView called with layout={layout}")
259
287
 
260
- def setSubText(self, text):
288
+ @classmethod
289
+ def setSubText(cls, text):
261
290
  logger.debug(f"[MOCK] setSubText called with text={text}")
262
291
 
263
- def setColor(self, color: Color) -> None:
292
+ @classmethod
293
+ def setColor(cls, color: Color) -> None:
264
294
  logger.debug(f"[MOCK] setColor called with color={color}")
265
295
 
266
- def setVibrate(self, state) -> None:
296
+ @classmethod
297
+ def setVibrate(cls, state) -> None:
267
298
  logger.debug(f"[MOCK] setVibrate called with state={state}")
268
299
 
269
300
 
270
301
  class NotificationCompatBigTextStyle:
271
- def bigText(self, body):
302
+ def bigText(cls, body):
272
303
  logger.debug(f"[MOCK] NotificationCompatBigTextStyle.bigText called with body={body}")
273
- return self
304
+ return cls
274
305
 
275
306
  def setBigContentTitle(self, title):
276
307
  logger.debug(f"[MOCK] NotificationCompatBigTextStyle.setBigContentTitle called with title={title}")
@@ -334,6 +365,15 @@ class PythonActivity:
334
365
  logger.debug("[MOCK] mActivity used")
335
366
  return MActivity()
336
367
 
368
+ @staticmethod
369
+ def startForeground(notification_id, builder_build, foreground_type):
370
+ logger.debug(
371
+ f"[MOCK] startForeground called with notification_id={notification_id}, builder.build()={builder_build}, foreground_type={foreground_type}")
372
+
373
+ def setAutoRestartService(self):
374
+ logger.debug("[MOCK] setAutoRestartService called")
375
+ return self
376
+
337
377
 
338
378
  class DummyIcon:
339
379
  icon = 101
@@ -39,24 +39,31 @@ 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")
43
42
  except Exception as e:
44
43
  from .facade import *
45
44
  logger.exception("Didn't get Basic Java Classes")
46
45
 
47
46
  # noinspection PyBroadException
48
47
  try:
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')
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')
55
52
 
56
- except Exception as styles_import_error:
57
- logger.exception(styles_import_error)
58
- from .facade import *
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
+ """)
59
65
 
66
+ from .facade import *
60
67
  else:
61
68
  cast = lambda x, y: x
62
69
  autoclass = lambda x: None
@@ -0,0 +1,94 @@
1
+ import logging
2
+ import sys
3
+ import os
4
+
5
+ try:
6
+ from jnius import autoclass
7
+ except ModuleNotFoundError:
8
+ autoclass = lambda x: None
9
+
10
+
11
+ def on_kivy_android():
12
+ kivy_build = os.environ.get('KIVY_BUILD', '')
13
+ if kivy_build in {'android'}:
14
+ return True
15
+ elif 'P4A_BOOTSTRAP' in os.environ:
16
+ return True
17
+ elif 'ANDROID_ARGUMENT' in os.environ:
18
+ return True
19
+
20
+ return False
21
+
22
+
23
+ def on_flet_app():
24
+ return os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME")
25
+
26
+
27
+ def on_android_platform():
28
+ return on_kivy_android() or on_flet_app()
29
+
30
+
31
+ def android_print(msg):
32
+ msg = str(msg)
33
+ if on_android_platform():
34
+ Log = autoclass("android.util.Log")
35
+ Log.i("python", msg)
36
+ return None
37
+ print(msg)
38
+ return None
39
+
40
+
41
+ def kivy_logger_patch():
42
+ if not on_kivy_android():
43
+ return
44
+
45
+ handler = logging.StreamHandler(sys.stdout)
46
+ formatter = KivyColorFormatter()
47
+ handler.setFormatter(formatter)
48
+
49
+ # Avoid duplicate logs if root logger is configured
50
+ logger.propagate = False
51
+ logger.addHandler(handler)
52
+ logger._configured = True
53
+
54
+
55
+ class KivyColorFormatter(logging.Formatter):
56
+ COLORS = {
57
+ 'DEBUG': '\x1b[1;36m', # bold cyan
58
+ 'INFO': '\x1b[1;92m', # bold lime green
59
+ 'WARNING': '\x1b[1;93m', # bold yellow
60
+ 'ERROR': '\x1b[1;91m', # bold red
61
+ 'CRITICAL': '\x1b[1;95m', # bold magenta
62
+ }
63
+ RESET = '\x1b[0m'
64
+
65
+ def format(self, record):
66
+ level = record.levelname.ljust(7)
67
+ name = record.name.ljust(14)
68
+ msg = record.getMessage()
69
+
70
+ if getattr(sys.stdout, "isatty", lambda: False)():
71
+ color = self.COLORS.get(record.levelname, '')
72
+ level = f"{color}{level}{self.RESET}"
73
+
74
+ return f"[{level}] [{name}] {msg}"
75
+
76
+
77
+ logger = logging.getLogger("android_notify")
78
+ kivy_logger_patch()
79
+
80
+ env_level = os.getenv("ANDROID_NOTIFY_LOGLEVEL")
81
+ if env_level:
82
+ try:
83
+ logging.getLogger("android_notify").setLevel(getattr(logging, env_level.upper()))
84
+ except Exception as android_notify_loglevel_error:
85
+ android_print(f"android_notify_loglevel_error: {android_notify_loglevel_error}")
86
+
87
+ if __name__ == "__main__":
88
+ # from kivymd.app import MDApp
89
+
90
+ logger.debug("Debug message - should not appear with INFO level")
91
+ logger.info("Info message")
92
+ logger.warning("Warning message")
93
+ logger.error("Error message")
94
+ logger.critical("Critical message")