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.
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/PKG-INFO +23 -62
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/README.md +22 -61
- android_notify-1.61.4/android_notify/__main__.py +75 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/config.py +33 -4
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/core.py +6 -9
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/channels.py +1 -1
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/facade.py +2 -4
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/helper.py +0 -4
- android_notify-1.61.4/android_notify/internal/java_classes.py +85 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/permissions.py +46 -15
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/basic/src/core.py +2 -2
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/flet-working/src/core.py +2 -2
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/main.py +1 -1
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/widgets/images.py +4 -5
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/widgets/texts.py +1 -5
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/PKG-INFO +23 -62
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/pyproject.toml +1 -2
- android_notify-1.61.3.dev0/android_notify/__main__.py +0 -24
- android_notify-1.61.3.dev0/android_notify/internal/java_classes.py +0 -69
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/__init__.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/base.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/fallback-icons/flet-appicon.png +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/fallback-icons/pydroid3-appicon.png +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/an_types.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/android.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/intents.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/internal/logger.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/styles.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/sword.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/__init__.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/android_notify_test.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/base_test.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/adv/main.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/adv/tests/__init__.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/adv/tests/test_android_notify_full.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/basic/src/main.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/flet-working/src/main.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/p4a/hook.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/serivces/wallpaper.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_basic_notifications.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_actions.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_appearance.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_behavior.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_channels.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_clear.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_permission.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_progress.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_sound.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_styles.py +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/SOURCES.txt +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/dependency_links.txt +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/entry_points.txt +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/requires.txt +0 -0
- {android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/top_level.txt +0 -0
- {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
|
+
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
|
|
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
|
|
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
|
|
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
|
|
171
|
+
For Dev Version usage
|
|
177
172
|
```ini
|
|
178
|
-
requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
149
|
+
For Dev Version usage
|
|
155
150
|
```ini
|
|
156
|
-
requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/
|
|
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
|
+
__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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
190
|
+
class IconClass:
|
|
193
191
|
@classmethod
|
|
194
192
|
def createWithBitmap(cls, bitmap):
|
|
195
|
-
logger.debug(f"[MOCK]
|
|
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
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
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"
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/basic/src/core.py
RENAMED
|
@@ -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
|
-
|
|
108
|
+
IconClass = autoclass('android.graphics.drawable.Icon')
|
|
109
109
|
|
|
110
110
|
bitmap= BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
|
|
111
|
-
return
|
|
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
|
-
|
|
108
|
+
IconClass = autoclass('android.graphics.drawable.Icon')
|
|
109
109
|
|
|
110
110
|
bitmap= BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
|
|
111
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
+
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
|
|
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
|
|
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
|
|
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
|
|
171
|
+
For Dev Version usage
|
|
177
172
|
```ini
|
|
178
|
-
requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/
|
|
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.
|
|
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
|
-
|
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/fallback-icons/flet-appicon.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/android_notify_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/adv/tests/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/flet/basic/src/main.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/serivces/wallpaper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_clear.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify/tests/test_notification_sound.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{android_notify-1.61.3.dev0 → android_notify-1.61.4}/android_notify.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|