android-notify 1.60.4__tar.gz → 1.60.4.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.
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/PKG-INFO +18 -88
- android_notify-1.60.4.dev0/README.md +110 -0
- android_notify-1.60.4.dev0/android_notify/an_types.py +251 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/an_utils.py +34 -14
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/config.py +18 -26
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/core.py +28 -33
- android_notify-1.60.4.dev0/android_notify/fallback-icons/flet-appicon.png +0 -0
- android_notify-1.60.4.dev0/android_notify/fallback-icons/pydroid3-appicon.png +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/sword.py +109 -47
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify.egg-info/PKG-INFO +18 -88
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify.egg-info/SOURCES.txt +2 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/pyproject.toml +4 -1
- android_notify-1.60.4/README.md +0 -180
- android_notify-1.60.4/android_notify/an_types.py +0 -226
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/__init__.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/__main__.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/base.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify/styles.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify.egg-info/dependency_links.txt +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify.egg-info/entry_points.txt +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify.egg-info/requires.txt +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/android_notify.egg-info/top_level.txt +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/examples/flet-working/src/core.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/examples/flet-working/src/main.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/tests/flet/adv/main.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/tests/flet/adv/tests/__init__.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/tests/flet/adv/tests/test_android_notify_full.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/tests/flet/basic/src/core.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/tests/flet/basic/src/main.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/docs/website/src/pages/data/laner_Sent.py +0 -0
- {android_notify-1.60.4 → android_notify-1.60.4.dev0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: android-notify
|
|
3
|
-
Version: 1.60.4
|
|
3
|
+
Version: 1.60.4.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
|
|
@@ -79,81 +79,32 @@ In your **`buildozer.spec`** file, ensure you include the following:
|
|
|
79
79
|
|
|
80
80
|
```ini
|
|
81
81
|
# Add pyjnius so ensure it's packaged with the build
|
|
82
|
-
requirements = python3, kivy, pyjnius, android-notify
|
|
82
|
+
requirements = python3, kivy, pyjnius, android-notify==1.60.4.dev0
|
|
83
83
|
# Add permission for notifications
|
|
84
84
|
android.permissions = POST_NOTIFICATIONS
|
|
85
|
-
|
|
86
|
-
# Required dependencies (write exactly as shown, no quotation marks)
|
|
87
|
-
android.gradle_dependencies = androidx.core:core:1.6.0, androidx.core:core-ktx:1.15.0
|
|
88
|
-
android.enable_androidx = True
|
|
89
|
-
android.api = 35
|
|
90
85
|
```
|
|
91
86
|
|
|
92
87
|
### Flet apps:
|
|
93
|
-
|
|
88
|
+
|
|
89
|
+
In your `pyproject.toml` file, ensure you include the following:
|
|
90
|
+
|
|
94
91
|
```toml
|
|
95
92
|
[tool.flet.android]
|
|
96
93
|
dependencies = [
|
|
97
|
-
"pyjnius","
|
|
94
|
+
"pyjnius","android-notify==1.60.4.dev0"
|
|
98
95
|
]
|
|
99
96
|
|
|
100
97
|
[tool.flet.android.permission]
|
|
101
98
|
"android.permission.POST_NOTIFICATIONS" = true
|
|
102
99
|
```
|
|
103
|
-
- example of [complete flet pyproject.toml](https://github.com/Fector101/flet-app/blob/main/pyproject.toml)
|
|
104
|
-
------
|
|
105
|
-
## Installing without Androidx
|
|
106
|
-
How to use without `gradle_dependencies`
|
|
107
|
-
Use `https://github.com/Fector101/android_notify/archive/without-androidx.zip` to install via `pip`
|
|
108
|
-
### In Kivy
|
|
109
|
-
```ini
|
|
110
|
-
# buildozer.spec
|
|
111
|
-
requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip
|
|
112
|
-
```
|
|
113
100
|
|
|
114
|
-
###
|
|
115
|
-
|
|
116
|
-
- In pip section where you're asked to insert `Libary name` paste `
|
|
117
|
-
|
|
118
|
-
```py
|
|
119
|
-
# Testing with `https://github.com/Fector101/android_notify/archive/without-androidx.zip` on pydroid
|
|
120
|
-
from kivy.app import App
|
|
121
|
-
from kivy.uix.boxlayout import BoxLayout
|
|
122
|
-
from kivy.uix.button import Button
|
|
123
|
-
from android_notify import Notification
|
|
124
|
-
from android_notify.core import asks_permission_if_needed
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
class AndroidNotifyDemoApp(App):
|
|
128
|
-
def build(self):
|
|
129
|
-
layout = BoxLayout(orientation='vertical', spacing=10, padding=20)
|
|
130
|
-
layout.add_widget(Button(
|
|
131
|
-
text="Ask Notification Permission",
|
|
132
|
-
on_release=self.request_permission
|
|
133
|
-
))
|
|
134
|
-
layout.add_widget(Button(
|
|
135
|
-
text="Send Notification",
|
|
136
|
-
on_release=self.send_notification
|
|
137
|
-
))
|
|
138
|
-
return layout
|
|
139
|
-
|
|
140
|
-
def request_permission(self, *args):
|
|
141
|
-
asks_permission_if_needed(no_androidx=True)
|
|
142
|
-
|
|
143
|
-
def send_notification(self, *args):
|
|
144
|
-
Notification(
|
|
145
|
-
title="Hello from Android Notify",
|
|
146
|
-
message="This is a basic notification.",
|
|
147
|
-
channel_id="android_notify_demo",
|
|
148
|
-
channel_name="Android Notify Demo"
|
|
149
|
-
).send()
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if __name__ == "__main__":
|
|
153
|
-
AndroidNotifyDemoApp().run()
|
|
154
|
-
```
|
|
101
|
+
### Pydroid 3
|
|
102
|
+
In 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.
|
|
103
|
+
- In pip section where you're asked to insert `Libary name` paste `android-notify==1.60.4.dev0`
|
|
104
|
+
|
|
155
105
|
|
|
156
|
-
|
|
106
|
+
### Testing
|
|
107
|
+
Can be installed via `pip` For testing purposes:
|
|
157
108
|
|
|
158
109
|
```bash
|
|
159
110
|
pip install android_notify
|
|
@@ -162,7 +113,7 @@ android-notify -v
|
|
|
162
113
|
|
|
163
114
|
## Documentation
|
|
164
115
|
For Dev Version use
|
|
165
|
-
```requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/
|
|
116
|
+
```requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip```
|
|
166
117
|
|
|
167
118
|
|
|
168
119
|
To use colored text in your notifications:
|
|
@@ -170,34 +121,13 @@ To use colored text in your notifications:
|
|
|
170
121
|
Lastly in your `buildozer.spec` file
|
|
171
122
|
- Add `source.include_exts = xml` and `android.add_resources = ./res`
|
|
172
123
|
|
|
173
|
-
To use Custom Sounds
|
|
174
|
-
- Put audio files in `res/raw` folder,
|
|
175
|
-
- Then from `buildozer.spec` point to res folder `android.add_resources = res`
|
|
176
|
-
- and includes it's format `source.include_exts = wav`.
|
|
177
|
-
|
|
178
|
-
Lastly From the code
|
|
179
|
-
```py
|
|
180
|
-
# Create a custom notification channel with a unique sound resource for android 8+
|
|
181
|
-
Notification.createChannel(
|
|
182
|
-
id="weird_sound_tester",
|
|
183
|
-
name="Weird Sound Tester",
|
|
184
|
-
description="A test channel used to verify custom notification sounds from the res/raw folder.",
|
|
185
|
-
res_sound_name="sneeze" # file name without .wav or .mp3
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
# Send a notification through the created channel
|
|
189
|
-
n=Notification(
|
|
190
|
-
title="Custom Sound Notification",
|
|
191
|
-
message="This tests playback of a custom sound (sneeze.wav) stored in res/raw.",
|
|
192
|
-
channel_id="weird_sound_tester" # important tells notification to use right channel
|
|
193
|
-
)
|
|
194
|
-
n.setSound("sneeze")# for android 7 below
|
|
195
|
-
n.send()
|
|
196
|
-
```
|
|
197
124
|
For full documentation, examples, and advanced usage, API reference visit the
|
|
198
125
|
[documentation](https://android-notify.vercel.app)
|
|
199
126
|
|
|
200
127
|
## ☕ Support the Project
|
|
201
128
|
|
|
202
|
-
If you find this project helpful,
|
|
203
|
-
|
|
129
|
+
If you find this project helpful, consider buying me a coffee! 😊 Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify/) Your support helps maintain and improve the project.
|
|
130
|
+
|
|
131
|
+
<a href="https://www.buymeacoffee.com/fector101" target="_blank">
|
|
132
|
+
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
|
|
133
|
+
</a>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<br>
|
|
3
|
+
<h1> Android-Notify </h1>
|
|
4
|
+
<p><a href='https://android-notify.vercel.app'>Android Notify</a> is a Python library for effortlessly creating and managing Android notifications in Kivy and Flet apps.</p>
|
|
5
|
+
<p>Supports various styles and ensures seamless integration, customization and Pythonic APIs.</p>
|
|
6
|
+
<!-- <br> -->
|
|
7
|
+
<!-- <img src="https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/democollage.jpg"> -->
|
|
8
|
+
</div>
|
|
9
|
+
<!-- Channel [CRUD]
|
|
10
|
+
The Android Notify package provides a simple yet comprehensive way to create and manage rich notifications on Android devices directly from your Python code. This library bridges the gap between Python and Android's notification system, giving you full control over notifications with a clean, Pythonic API. -->
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Multiple Notification Styles**: Support for various notification styles including:
|
|
15
|
+
- Simple text notifications
|
|
16
|
+
- [Progress bar notifications](https://android-notify.vercel.app/components#progress-bars) (determinate and indeterminate)
|
|
17
|
+
- Large icon notifications
|
|
18
|
+
- Big picture notifications
|
|
19
|
+
- Combined image styles
|
|
20
|
+
- Custom notification Icon - [images section](https://android-notify.vercel.app/components#images)
|
|
21
|
+
- Big text notifications
|
|
22
|
+
- Inbox-style notifications
|
|
23
|
+
- Colored texts and Icons
|
|
24
|
+
|
|
25
|
+
- **Rich Functionality**:
|
|
26
|
+
- Add action buttons with custom callbacks
|
|
27
|
+
- [Update notification](https://android-notify.vercel.app/advanced-methods#updating-notification) content dynamically
|
|
28
|
+
- Manage progress bars with fine-grained control
|
|
29
|
+
- [Custom notification channels](https://android-notify.vercel.app/advanced-methods#channel-management) for Android 8.0+ (Creating and Deleting)
|
|
30
|
+
- Silent notifications
|
|
31
|
+
- Persistent notifications
|
|
32
|
+
- Click handlers and callbacks
|
|
33
|
+
- Cancel Notifications
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from android_notify import Notification
|
|
39
|
+
|
|
40
|
+
# Simple notification
|
|
41
|
+
Notification(
|
|
42
|
+
title="Hello",
|
|
43
|
+
message="This is a basic notification."
|
|
44
|
+
).send()
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Sample Image:**
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
### Kivy apps:
|
|
54
|
+
|
|
55
|
+
In your **`buildozer.spec`** file, ensure you include the following:
|
|
56
|
+
|
|
57
|
+
```ini
|
|
58
|
+
# Add pyjnius so ensure it's packaged with the build
|
|
59
|
+
requirements = python3, kivy, pyjnius, android-notify==1.60.4.dev0
|
|
60
|
+
# Add permission for notifications
|
|
61
|
+
android.permissions = POST_NOTIFICATIONS
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Flet apps:
|
|
65
|
+
|
|
66
|
+
In your `pyproject.toml` file, ensure you include the following:
|
|
67
|
+
|
|
68
|
+
```toml
|
|
69
|
+
[tool.flet.android]
|
|
70
|
+
dependencies = [
|
|
71
|
+
"pyjnius","android-notify==1.60.4.dev0"
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
[tool.flet.android.permission]
|
|
75
|
+
"android.permission.POST_NOTIFICATIONS" = true
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Pydroid 3
|
|
79
|
+
In 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.
|
|
80
|
+
- In pip section where you're asked to insert `Libary name` paste `android-notify==1.60.4.dev0`
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
### Testing
|
|
84
|
+
Can be installed via `pip` For testing purposes:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install android_notify
|
|
88
|
+
android-notify -v
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Documentation
|
|
92
|
+
For Dev Version use
|
|
93
|
+
```requirements = python3, kivy, pyjnius, https://github.com/Fector101/android_notify/archive/without-androidx.zip```
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
To use colored text in your notifications:
|
|
97
|
+
- Copy the [res](https://github.com/Fector101/android_notify/tree/main/android_notify/res) folder to your app path.
|
|
98
|
+
Lastly in your `buildozer.spec` file
|
|
99
|
+
- Add `source.include_exts = xml` and `android.add_resources = ./res`
|
|
100
|
+
|
|
101
|
+
For full documentation, examples, and advanced usage, API reference visit the
|
|
102
|
+
[documentation](https://android-notify.vercel.app)
|
|
103
|
+
|
|
104
|
+
## ☕ Support the Project
|
|
105
|
+
|
|
106
|
+
If you find this project helpful, consider buying me a coffee! 😊 Or Giving it a star on 🌟 [GitHub](https://github.com/Fector101/android_notify/) Your support helps maintain and improve the project.
|
|
107
|
+
|
|
108
|
+
<a href="https://www.buymeacoffee.com/fector101" target="_blank">
|
|
109
|
+
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
|
|
110
|
+
</a>
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"""For autocomplete Storing Reference to Available Methods"""
|
|
2
|
+
from typing import Literal
|
|
3
|
+
Importance = Literal['urgent','high','medium','low','none']
|
|
4
|
+
"""
|
|
5
|
+
:argument urgent - Makes a sound and appears as a heads-up notification.
|
|
6
|
+
|
|
7
|
+
:argument high - Makes a sound.
|
|
8
|
+
|
|
9
|
+
:argument urgent - Makes no sound.
|
|
10
|
+
|
|
11
|
+
:argument urgent - Makes no sound and doesn't appear in the status bar.
|
|
12
|
+
|
|
13
|
+
:argument urgent - Makes no sound and doesn't in the status bar or shade.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# For Dev
|
|
17
|
+
# Idea for typing autocompletion and reference
|
|
18
|
+
class Bundle:
|
|
19
|
+
def putString(self,key,value):
|
|
20
|
+
print(f"[MOCK] Bundle.putString called with key={key}, value={value}")
|
|
21
|
+
|
|
22
|
+
def putInt(self,key,value):
|
|
23
|
+
print(f"[MOCK] Bundle.putInt called with key={key}, value={value}")
|
|
24
|
+
|
|
25
|
+
class String(str):
|
|
26
|
+
def __new__(cls, value):
|
|
27
|
+
print(f"[MOCK] String created with value={value}")
|
|
28
|
+
return str.__new__(cls, value)
|
|
29
|
+
|
|
30
|
+
class Intent:
|
|
31
|
+
def __init__(self,context,activity):
|
|
32
|
+
self.obj={}
|
|
33
|
+
print(f"[MOCK] Intent initialized with context={context}, activity={activity}")
|
|
34
|
+
|
|
35
|
+
def setAction(self,action):
|
|
36
|
+
print(f"[MOCK] Intent.setAction called with: {action}")
|
|
37
|
+
return self
|
|
38
|
+
|
|
39
|
+
def setFlags(self,intent_flag):
|
|
40
|
+
print(f"[MOCK] Intent.setFlags called with: {intent_flag}")
|
|
41
|
+
return self
|
|
42
|
+
|
|
43
|
+
def getAction(self):
|
|
44
|
+
print("[MOCK] Intent.getAction called")
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
def getStringExtra(self,key):
|
|
48
|
+
print(f"[MOCK] Intent.getStringExtra called with key={key}")
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
def putExtra(self,key,value):
|
|
52
|
+
self.obj[key] = value
|
|
53
|
+
print(f"[MOCK] Intent.putExtra called with key={key}, value={value}")
|
|
54
|
+
|
|
55
|
+
def putExtras(self,bundle:Bundle):
|
|
56
|
+
self.obj['bundle'] = bundle
|
|
57
|
+
print(f"[MOCK] Intent.putExtras called with bundle={bundle}")
|
|
58
|
+
|
|
59
|
+
class PendingIntent:
|
|
60
|
+
FLAG_IMMUTABLE=''
|
|
61
|
+
FLAG_UPDATE_CURRENT=''
|
|
62
|
+
|
|
63
|
+
def getActivity(self,context,value,action_intent,pending_intent_type):
|
|
64
|
+
print(f"[MOCK] PendingIntent.getActivity called with context={context}, value={value}, action_intent={action_intent}, type={pending_intent_type}")
|
|
65
|
+
|
|
66
|
+
class BitmapFactory:
|
|
67
|
+
def decodeStream(self,stream):
|
|
68
|
+
print(f"[MOCK] BitmapFactory.decodeStream called with stream={stream}")
|
|
69
|
+
|
|
70
|
+
class BuildVersion:
|
|
71
|
+
SDK_INT=0
|
|
72
|
+
|
|
73
|
+
class NotificationManager:
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
class NotificationChannel:
|
|
77
|
+
def __init__(self,channel_id,channel_name,importance):
|
|
78
|
+
self.description = None
|
|
79
|
+
self.channel_id = channel_id
|
|
80
|
+
self.channel = None
|
|
81
|
+
print(f"[MOCK] NotificationChannel initialized with id={channel_id}, name={channel_name}, importance={importance}")
|
|
82
|
+
|
|
83
|
+
def createNotificationChannel(self, channel):
|
|
84
|
+
self.channel=channel
|
|
85
|
+
print(f"[MOCK] NotificationChannel.createNotificationChannel called with channel={channel}")
|
|
86
|
+
|
|
87
|
+
def getNotificationChannel(self, channel_id):
|
|
88
|
+
self.channel_id=channel_id
|
|
89
|
+
print(f"[MOCK] NotificationChannel.getNotificationChannel called with id={channel_id}")
|
|
90
|
+
|
|
91
|
+
def setDescription(self, description):
|
|
92
|
+
self.description=description
|
|
93
|
+
print(f"[MOCK] NotificationChannel.setDescription called with description={description}")
|
|
94
|
+
|
|
95
|
+
def getId(self):
|
|
96
|
+
print(f"[MOCK] NotificationChannel.getId called, returning {self.channel_id}")
|
|
97
|
+
return self.channel_id
|
|
98
|
+
|
|
99
|
+
class IconCompat:
|
|
100
|
+
def createWithBitmap(self,bitmap):
|
|
101
|
+
print(f"[MOCK] IconCompat.createWithBitmap called with bitmap={bitmap}")
|
|
102
|
+
|
|
103
|
+
class Color:
|
|
104
|
+
def __init__(self):
|
|
105
|
+
print("[MOCK] Color initialized")
|
|
106
|
+
def parseColor(self,color:str):
|
|
107
|
+
print(f"[MOCK] Color.parseColor called with color={color}")
|
|
108
|
+
return self
|
|
109
|
+
|
|
110
|
+
class RemoteViews:
|
|
111
|
+
def __init__(self, package_name, small_layout_id):
|
|
112
|
+
print(f"[MOCK] RemoteViews initialized with package_name={package_name}, layout_id={small_layout_id}")
|
|
113
|
+
def createWithBitmap(self,bitmap):
|
|
114
|
+
print(f"[MOCK] RemoteViews.createWithBitmap called with bitmap={bitmap}")
|
|
115
|
+
def setTextViewText(self,id, text):
|
|
116
|
+
print(f"[MOCK] RemoteViews.setTextViewText called with id={id}, text={text}")
|
|
117
|
+
def setTextColor(self,id, color:Color):
|
|
118
|
+
print(f"[MOCK] RemoteViews.setTextColor called with id={id}, color={color}")
|
|
119
|
+
|
|
120
|
+
class NotificationManagerCompat:
|
|
121
|
+
IMPORTANCE_HIGH=4
|
|
122
|
+
IMPORTANCE_DEFAULT=3
|
|
123
|
+
IMPORTANCE_LOW=''
|
|
124
|
+
IMPORTANCE_MIN=''
|
|
125
|
+
IMPORTANCE_NONE=''
|
|
126
|
+
|
|
127
|
+
class NotificationCompat:
|
|
128
|
+
DEFAULT_ALL=3
|
|
129
|
+
PRIORITY_HIGH=4
|
|
130
|
+
PRIORITY_DEFAULT = ''
|
|
131
|
+
PRIORITY_LOW=''
|
|
132
|
+
PRIORITY_MIN=''
|
|
133
|
+
|
|
134
|
+
class MActions:
|
|
135
|
+
def clear(self):
|
|
136
|
+
"""This Removes all buttons"""
|
|
137
|
+
print('[MOCK] MActions.clear called')
|
|
138
|
+
|
|
139
|
+
class NotificationCompatBuilder:
|
|
140
|
+
def __init__(self,context,channel_id):
|
|
141
|
+
self.mActions = MActions()
|
|
142
|
+
print(f"[MOCK] NotificationCompatBuilder initialized with context={context}, channel_id={channel_id}")
|
|
143
|
+
def setProgress(self,max_value,current_value,endless):
|
|
144
|
+
print(f"[MOCK] setProgress called with max={max_value}, current={current_value}, endless={endless}")
|
|
145
|
+
def setStyle(self,style):
|
|
146
|
+
print(f"[MOCK] setStyle called with style={style}")
|
|
147
|
+
def setContentTitle(self,title):
|
|
148
|
+
print(f"[MOCK] setContentTitle called with title={title}")
|
|
149
|
+
def setContentText(self,text):
|
|
150
|
+
print(f"[MOCK] setContentText called with text={text}")
|
|
151
|
+
def setSmallIcon(self,icon):
|
|
152
|
+
print(f"[MOCK] setSmallIcon called with icon={icon}")
|
|
153
|
+
def setLargeIcon(self,icon):
|
|
154
|
+
print(f"[MOCK] setLargeIcon called with icon={icon}")
|
|
155
|
+
def setAutoCancel(self,auto_cancel:bool):
|
|
156
|
+
print(f"[MOCK] setAutoCancel called with auto_cancel={auto_cancel}")
|
|
157
|
+
def setPriority(self,priority):
|
|
158
|
+
print(f"[MOCK] setPriority called with priority={priority}")
|
|
159
|
+
def setDefaults(self,defaults):
|
|
160
|
+
print(f"[MOCK] setDefaults called with defaults={defaults}")
|
|
161
|
+
def setOngoing(self,persistent:bool):
|
|
162
|
+
print(f"[MOCK] setOngoing called with persistent={persistent}")
|
|
163
|
+
def setOnlyAlertOnce(self,state):
|
|
164
|
+
print(f"[MOCK] setOnlyAlertOnce called with state={state}")
|
|
165
|
+
def build(self):
|
|
166
|
+
print("[MOCK] build called")
|
|
167
|
+
def setContentIntent(self,pending_action_intent:PendingIntent):
|
|
168
|
+
print(f"[MOCK] setContentIntent called with {pending_action_intent}")
|
|
169
|
+
def addAction(self,icon_int,action_text,pending_action_intent):
|
|
170
|
+
print(f"[MOCK] addAction called with icon={icon_int}, text={action_text}, intent={pending_action_intent}")
|
|
171
|
+
def setShowWhen(self,state):
|
|
172
|
+
print(f"[MOCK] setShowWhen called with state={state}")
|
|
173
|
+
def setWhen(self,time_ms):
|
|
174
|
+
print(f"[MOCK] setWhen called with time_ms={time_ms}")
|
|
175
|
+
def setCustomContentView(self,layout):
|
|
176
|
+
print(f"[MOCK] setCustomContentView called with layout={layout}")
|
|
177
|
+
def setCustomBigContentView(self,layout):
|
|
178
|
+
print(f"[MOCK] setCustomBigContentView called with layout={layout}")
|
|
179
|
+
def setSubText(self,text):
|
|
180
|
+
print(f"[MOCK] setSubText called with text={text}")
|
|
181
|
+
def setColor(self, color:Color) -> None:
|
|
182
|
+
print(f"[MOCK] setColor called with color={color}")
|
|
183
|
+
|
|
184
|
+
class NotificationCompatBigTextStyle:
|
|
185
|
+
def bigText(self,body):
|
|
186
|
+
print(f"[MOCK] NotificationCompatBigTextStyle.bigText called with body={body}")
|
|
187
|
+
return self
|
|
188
|
+
|
|
189
|
+
class NotificationCompatBigPictureStyle:
|
|
190
|
+
def bigPicture(self,bitmap):
|
|
191
|
+
print(f"[MOCK] NotificationCompatBigPictureStyle.bigPicture called with bitmap={bitmap}")
|
|
192
|
+
return self
|
|
193
|
+
|
|
194
|
+
class NotificationCompatInboxStyle:
|
|
195
|
+
def addLine(self,line):
|
|
196
|
+
print(f"[MOCK] NotificationCompatInboxStyle.addLine called with line={line}")
|
|
197
|
+
return self
|
|
198
|
+
|
|
199
|
+
class NotificationCompatDecoratedCustomViewStyle:
|
|
200
|
+
def __init__(self):
|
|
201
|
+
print("[MOCK] NotificationCompatDecoratedCustomViewStyle initialized")
|
|
202
|
+
|
|
203
|
+
class Permission:
|
|
204
|
+
POST_NOTIFICATIONS=''
|
|
205
|
+
|
|
206
|
+
def check_permission(permission:Permission.POST_NOTIFICATIONS):
|
|
207
|
+
print(f"[MOCK] check_permission called with {permission}")
|
|
208
|
+
print(permission)
|
|
209
|
+
|
|
210
|
+
def request_permissions(_list: [], _callback):
|
|
211
|
+
print(f"[MOCK] request_permissions called with {_list}")
|
|
212
|
+
_callback()
|
|
213
|
+
|
|
214
|
+
class AndroidActivity:
|
|
215
|
+
def bind(self,on_new_intent):
|
|
216
|
+
print(f"[MOCK] AndroidActivity.bind called with {on_new_intent}")
|
|
217
|
+
def unbind(self,on_new_intent):
|
|
218
|
+
print(f"[MOCK] AndroidActivity.unbind called with {on_new_intent}")
|
|
219
|
+
|
|
220
|
+
class PythonActivity:
|
|
221
|
+
def __init__(self):
|
|
222
|
+
print("[MOCK] PythonActivity initialized")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class DummyIcon:
|
|
226
|
+
icon = 101
|
|
227
|
+
def __init__(self):
|
|
228
|
+
print("[MOCK] DummyIcon initialized")
|
|
229
|
+
|
|
230
|
+
class Context:
|
|
231
|
+
def __init__(self):
|
|
232
|
+
print("[MOCK] Context initialized")
|
|
233
|
+
pass
|
|
234
|
+
|
|
235
|
+
@staticmethod
|
|
236
|
+
def getApplicationInfo():
|
|
237
|
+
print("[MOCK] Context.getApplicationInfo called")
|
|
238
|
+
return DummyIcon
|
|
239
|
+
|
|
240
|
+
@staticmethod
|
|
241
|
+
def getResources():
|
|
242
|
+
print("[MOCK] Context.getResources called")
|
|
243
|
+
return None
|
|
244
|
+
|
|
245
|
+
@staticmethod
|
|
246
|
+
def getPackageName():
|
|
247
|
+
print("[MOCK] Context.getPackageName called")
|
|
248
|
+
return None # TODO get package name from buildozer.spec file
|
|
249
|
+
|
|
250
|
+
#Now writing Knowledge from errors
|
|
251
|
+
# notify.(int, Builder.build()) # must be int
|
|
@@ -6,7 +6,7 @@ from .an_types import Importance
|
|
|
6
6
|
from .config import (
|
|
7
7
|
get_python_activity_context, app_storage_path,ON_ANDROID,
|
|
8
8
|
BitmapFactory, BuildVersion, Bundle,
|
|
9
|
-
|
|
9
|
+
NotificationManagerClass,AndroidNotification
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
if ON_ANDROID:
|
|
@@ -37,15 +37,15 @@ def get_android_importance(importance: Importance):
|
|
|
37
37
|
return None
|
|
38
38
|
value = ''
|
|
39
39
|
if importance == 'urgent':
|
|
40
|
-
value =
|
|
40
|
+
value = AndroidNotification.PRIORITY_HIGH if BuildVersion.SDK_INT <= 25 else NotificationManagerClass.IMPORTANCE_HIGH
|
|
41
41
|
elif importance == 'high':
|
|
42
|
-
value =
|
|
42
|
+
value = AndroidNotification.PRIORITY_DEFAULT if BuildVersion.SDK_INT <= 25 else NotificationManagerClass.IMPORTANCE_DEFAULT
|
|
43
43
|
elif importance == 'medium':
|
|
44
|
-
value =
|
|
44
|
+
value = AndroidNotification.PRIORITY_LOW if BuildVersion.SDK_INT <= 25 else NotificationManagerClass.IMPORTANCE_LOW
|
|
45
45
|
elif importance == 'low':
|
|
46
|
-
value =
|
|
46
|
+
value = AndroidNotification.PRIORITY_MIN if BuildVersion.SDK_INT <= 25 else NotificationManagerClass.IMPORTANCE_MIN
|
|
47
47
|
elif importance == 'none':
|
|
48
|
-
value = '' if BuildVersion.SDK_INT <= 25 else
|
|
48
|
+
value = '' if BuildVersion.SDK_INT <= 25 else NotificationManagerClass.IMPORTANCE_NONE
|
|
49
49
|
|
|
50
50
|
return value
|
|
51
51
|
# side-note 'medium' = NotificationCompat.PRIORITY_LOW and 'low' = NotificationCompat.PRIORITY_MIN # weird but from docs
|
|
@@ -69,10 +69,11 @@ def generate_channel_id(channel_name: str) -> str:
|
|
|
69
69
|
return channel_id[:50]
|
|
70
70
|
|
|
71
71
|
def get_img_from_path(relative_path):
|
|
72
|
-
app_folder = os.path.join(app_storage_path(), 'app')
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
app_folder = os.path.join(app_storage_path(), 'app')
|
|
73
|
+
img_full_path = os.path.join(app_folder, relative_path)
|
|
74
|
+
img_name = os.path.basename(img_full_path)
|
|
75
|
+
if not os.path.exists(img_full_path):
|
|
76
|
+
print(f"\nImage - {img_name} not found at path: {app_folder}, (Local images gotten from App Path)")
|
|
76
77
|
try:
|
|
77
78
|
print("- These are the existing files in your app Folder:")
|
|
78
79
|
print('[' + ', '.join(os.listdir(app_folder)) + ']')
|
|
@@ -80,10 +81,8 @@ def get_img_from_path(relative_path):
|
|
|
80
81
|
print('Exception: ', could_not_get_files_in_path_error)
|
|
81
82
|
print("Couldn't get Files in App Folder")
|
|
82
83
|
return None
|
|
84
|
+
return get_bitmap_from_path(img_full_path)
|
|
83
85
|
# TODO test with a badly written Image and catch error
|
|
84
|
-
Uri = autoclass('android.net.Uri')
|
|
85
|
-
uri = Uri.parse(f"file://{output_path}")
|
|
86
|
-
return BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
|
|
87
86
|
|
|
88
87
|
def setLayoutText(layout, id, text, color):
|
|
89
88
|
# checked if self.title_color available before entering method
|
|
@@ -128,7 +127,6 @@ def add_data_to_intent(intent, title):
|
|
|
128
127
|
bundle.putInt("notify_id", 101)
|
|
129
128
|
intent.putExtras(bundle)
|
|
130
129
|
|
|
131
|
-
|
|
132
130
|
def get_sound_uri(res_sound_name):
|
|
133
131
|
if not res_sound_name:
|
|
134
132
|
return None
|
|
@@ -136,3 +134,25 @@ def get_sound_uri(res_sound_name):
|
|
|
136
134
|
package_name = context.getPackageName()
|
|
137
135
|
Uri = autoclass('android.net.Uri')
|
|
138
136
|
return Uri.parse(f"android.resource://{package_name}/raw/{res_sound_name}")
|
|
137
|
+
|
|
138
|
+
def get_package_path():
|
|
139
|
+
"""
|
|
140
|
+
Returns the directory path of this Python package.
|
|
141
|
+
Works on Android, Windows, Linux, macOS.
|
|
142
|
+
"""
|
|
143
|
+
return os.path.dirname(os.path.abspath(__file__))
|
|
144
|
+
|
|
145
|
+
def get_bitmap_from_path(img_full_path):
|
|
146
|
+
Uri = autoclass('android.net.Uri')
|
|
147
|
+
uri = Uri.parse(f"file://{img_full_path}")
|
|
148
|
+
return BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
|
|
149
|
+
|
|
150
|
+
def icon_finder(icon_name):
|
|
151
|
+
"""Get the full path to an icon file."""
|
|
152
|
+
try:
|
|
153
|
+
import pkg_resources
|
|
154
|
+
return pkg_resources.resource_filename(__name__, f"fallback-icons/{icon_name}")
|
|
155
|
+
except Exception:
|
|
156
|
+
# Fallback if pkg_resources not available
|
|
157
|
+
package_dir = get_package_path()
|
|
158
|
+
return os.path.join(package_dir, "fallback-icons", icon_name)
|