android-notify 1.1__py3-none-any.whl → 1.2__py3-none-any.whl

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.

Potentially problematic release.


This version of android-notify might be problematic. Click here for more details.

android_notify/core.py CHANGED
@@ -3,22 +3,48 @@ from jnius import autoclass,cast
3
3
  import random
4
4
  import os
5
5
 
6
+ ON_ANDROID = False
7
+ try:
8
+ # Get the required Java classes
9
+ PythonActivity = autoclass('org.kivy.android.PythonActivity')
10
+ NotificationChannel = autoclass('android.app.NotificationChannel')
11
+ String = autoclass('java.lang.String')
12
+ Intent = autoclass('android.content.Intent')
13
+ PendingIntent = autoclass('android.app.PendingIntent')
14
+ context = PythonActivity.mActivity # Get the app's context
15
+ BitmapFactory = autoclass('android.graphics.BitmapFactory')
16
+ BuildVersion = autoclass('android.os.Build$VERSION')
17
+ ON_ANDROID=True
18
+ except Exception as e:
19
+ print('This Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" to see design patterns and more info.')
20
+
21
+ if ON_ANDROID:
22
+ try:
23
+ # NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
24
+ NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
25
+
26
+ # Notification Design
27
+ NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
28
+ NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
29
+ # NotificationCompatBigTextStyle = autoclass('android.app.Notification$BigTextStyle')
30
+ NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
31
+ NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
32
+ except Exception as e:
33
+ print("""
34
+ Dependency Error: Add the following in buildozer.spec:
35
+ * android.gradle_dependencies = androidx.core:core-ktx:1.15.0, androidx.core:core:1.6.0
36
+ * android.enable_androidx = True
37
+ * android.permissions = POST_NOTIFICATIONS
38
+ """)
6
39
 
7
40
  def asks_permission_if_needed():
8
41
  """
9
42
  Ask for permission to send notifications if needed.
10
43
  """
11
- # Get the required Java classes
12
44
  from android.permissions import request_permissions, Permission,check_permission # type: ignore
13
-
14
- def check_permissions(permissions):
15
- for permission in permissions:
16
- if check_permission(permission) != True:
17
- return False
18
- return True
19
45
 
20
46
  permissions=[Permission.POST_NOTIFICATIONS]
21
- if check_permissions(permissions):
47
+ if not all(check_permission(p) for p in permissions):
22
48
  request_permissions(permissions)
23
49
 
24
50
  def get_image_uri(relative_path):
@@ -28,62 +54,40 @@ def get_image_uri(relative_path):
28
54
  :return: Absolute URI java Object (e.g., 'file:///path/to/file.png').
29
55
  """
30
56
  from android.storage import app_storage_path # type: ignore
31
- # print("app_storage_path()",app_storage_path())
32
57
 
33
58
  output_path = os.path.join(app_storage_path(),'app', relative_path)
34
59
  # print(output_path,'output_path') # /data/user/0/org.laner.lan_ft/files/app/assets/imgs/icon.png
35
-
60
+
61
+ if not os.path.exists(output_path):
62
+ raise FileNotFoundError(f"Image not found at path: {output_path}")
63
+
36
64
  Uri = autoclass('android.net.Uri')
37
65
  return Uri.parse(f"file://{output_path}")
38
66
 
39
- def send_notification(title, message, style=None, img_path=None, channel_id="default_channel"):
67
+
68
+ def send_notification(title:str, message:str, style=None, img_path=None, channel_id:str="default_channel"):
40
69
  """
41
70
  Send a notification on Android.
42
71
 
43
72
  :param title: Title of the notification.
44
73
  :param message: Message body.
45
- :param style: Style of the notification ('big_text', 'big_picture', 'inbox').
46
- :param image: Image URL or drawable for 'big_picture' style.
74
+ :param style: Style of the notification ('big_text', 'big_picture', 'inbox', 'large_icon').
75
+ :param img_path: Path to the image resource.
47
76
  :param channel_id: Notification channel ID.
48
77
  """
49
- # TODO check if running on android short circuit and return message if not
50
-
51
- # Get the required Java classes
52
- # Notification Base
53
- PythonActivity = autoclass('org.kivy.android.PythonActivity')
54
- NotificationChannel = autoclass('android.app.NotificationChannel')
55
- String = autoclass('java.lang.String')
56
-
57
-
58
- NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
59
- NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
60
-
61
- # Notification Design
62
- NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
63
- NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
64
- # NotificationCompatBigTextStyle = autoclass('android.app.Notification$BigTextStyle')
65
-
66
- NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
67
- NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
68
- BitmapFactory = autoclass('android.graphics.BitmapFactory')
69
- BuildVersion = autoclass('android.os.Build$VERSION')
70
- PendingIntent = autoclass('android.app.PendingIntent')
71
- Intent = autoclass('android.content.Intent')
78
+ if not ON_ANDROID:
79
+ print('This Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" for Documentation.')
80
+ return
72
81
 
73
- # Get the app's context and notification manager
74
- context = PythonActivity.mActivity
82
+ # Get notification manager
75
83
  notification_manager = context.getSystemService(context.NOTIFICATION_SERVICE)
76
84
 
77
- importance= NotificationManagerCompat.IMPORTANCE_HIGH #autoclass('android.app.NotificationManager').IMPORTANCE_HIGH also works #NotificationManager.IMPORTANCE_DEFAULT
85
+ importance= autoclass('android.app.NotificationManager').IMPORTANCE_HIGH # also works #NotificationManager.IMPORTANCE_DEFAULT
86
+ # importance= NotificationManagerCompat.IMPORTANCE_HIGH #autoclass('android.app.NotificationManager').IMPORTANCE_HIGH also works #NotificationManager.IMPORTANCE_DEFAULT
78
87
 
79
88
  # Notification Channel (Required for Android 8.0+)
80
89
  if BuildVersion.SDK_INT >= 26:
81
- print('entered....')
82
- channel = NotificationChannel(
83
- channel_id,
84
- "Default Channel",
85
- importance
86
- )
90
+ channel = NotificationChannel(channel_id, "Default Channel",importance)
87
91
  notification_manager.createNotificationChannel(channel)
88
92
 
89
93
  # Build the notification
@@ -95,74 +99,37 @@ def send_notification(title, message, style=None, img_path=None, channel_id="def
95
99
  builder.setPriority(NotificationCompat.PRIORITY_HIGH)
96
100
 
97
101
  # Get Image
98
- img=img_path
102
+ img=None
99
103
  if img_path:
100
104
  try:
101
105
  img = get_image_uri(img_path)
102
- except Exception as e:
103
- print('Failed getting Image path',e)
106
+ except FileNotFoundError as e:
107
+ print('Failed Adding Bitmap: ',e)
104
108
 
105
- # Add Actions (Buttons)
106
-
107
- # add Action 1 Button
108
- # try:
109
- # # Create Action 1
110
- # action_intent = Intent(context, PythonActivity)
111
- # action_intent.setAction("ACTION_ONE")
112
- # pending_action_intent = PendingIntent.getActivity(
113
- # context,
114
- # 0,
115
- # action_intent,
116
- # PendingIntent.FLAG_IMMUTABLE
117
- # )
118
-
119
- # # Convert text to CharSequence
120
- # action_text = cast('java.lang.CharSequence', String("Action 1"))
121
-
122
- # # Add action with proper types
123
- # builder.addAction(
124
- # int(context.getApplicationInfo().icon), # Cast icon to int
125
- # action_text, # CharSequence text
126
- # pending_action_intent # PendingIntent
127
- # )
128
-
129
-
130
- # # Set content intent for notification tap
131
- # builder.setContentIntent(pending_action_intent)
132
- # except Exception as e:
133
- # print('Failed adding Action 1',e)
134
-
135
-
136
- # Apply styles
137
- if style == "big_text":
138
- big_text_style = NotificationCompatBigTextStyle()
139
- big_text_style.bigText(message)
140
- builder.setStyle(big_text_style)
141
-
142
-
143
- elif style == "big_picture" and img_path:
144
- try:
109
+ # Apply notification styles
110
+ try:
111
+ if style == "big_text":
112
+ big_text_style = NotificationCompatBigTextStyle()
113
+ big_text_style.bigText(message)
114
+ builder.setStyle(big_text_style)
115
+
116
+
117
+ elif style == "big_picture" and img_path:
145
118
  bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(img))
146
- # bitmap = BitmapFactory.decodeFile(img_path)
147
119
  builder.setLargeIcon(bitmap)
148
120
  big_picture_style = NotificationCompatBigPictureStyle().bigPicture(bitmap)
149
- # big_picture_style.bigPicture(bitmap).bigLargeIcon(None)
150
- # big_picture_style.bigLargeIcon(bitmap) # This just changes dropdown app icon
151
-
152
121
  builder.setStyle(big_picture_style)
153
- except Exception as e:
154
- print('Failed Adding Bitmap...', e)
155
- elif style == "inbox":
156
- inbox_style = NotificationCompatInboxStyle()
157
- for line in message.split("\n"):
158
- inbox_style.addLine(line)
159
- builder.setStyle(inbox_style)
160
- elif style == "large_icon" and img_path:
161
- try:
122
+ elif style == "inbox":
123
+ inbox_style = NotificationCompatInboxStyle()
124
+ for line in message.split("\n"):
125
+ inbox_style.addLine(line)
126
+ builder.setStyle(inbox_style)
127
+ elif style == "large_icon" and img_path:
162
128
  bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(img))
163
129
  builder.setLargeIcon(bitmap)
164
- except Exception as e:
165
- print('Failed Large Icon...', e)
166
-
167
- # Show the notification
168
- notification_manager.notify(random.randint(0, 100), builder.build())
130
+ except Exception as e:
131
+ print('Failed Adding Style: ',e)
132
+ # Display the notification
133
+ notification_id = random.randint(0, 100)
134
+ notification_manager.notify(notification_id, builder.build())
135
+ return notification_id
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
- Name: android-notify
3
- Version: 1.1
2
+ Name: android_notify
3
+ Version: 1.2
4
4
  Summary: A Python package for sending Android notifications.
5
5
  Home-page: https://github.com/Fector101/android_notify/
6
6
  Author: Fabian
@@ -21,21 +21,21 @@ Requires-Dist: pyjnius
21
21
  - Support for multiple notification styles:
22
22
  - Big Text
23
23
  - Big Picture
24
+ - Large Icon
24
25
  - Inbox
25
- - Ability to include images in notifications.
26
+ - Supports including images in notifications.
26
27
  - Compatible with Android 8.0+ (Notification Channels).
27
28
  - Customizable notification channels.
28
- - Support for large icons in notifications.
29
29
 
30
30
  ## Installation
31
31
 
32
- Make sure you have the required dependencies installed:
32
+ This package is available on PyPI and can be installed via pip:
33
33
 
34
34
  ```bash
35
35
  pip install android-notify
36
36
  ```
37
37
 
38
- ## Usage
38
+ ## **Dependencies**
39
39
 
40
40
  **Prerequisites:**
41
41
 
@@ -52,10 +52,12 @@ requirements = python3,kivy,pyjnius
52
52
  android.permissions = POST_NOTIFICATIONS
53
53
 
54
54
  # Required dependencies (write exactly as shown, no quotation marks)
55
- android.gradle_dependencies = androidx.core:core:1.6.0
55
+ android.gradle_dependencies = androidx.core:core:1.6.0, androidx.core:core-ktx:1.15.0
56
56
  android.enable_androidx = True
57
57
  ```
58
58
 
59
+ ---
60
+
59
61
  ### Example Notification
60
62
 
61
63
  ```python
@@ -87,20 +89,75 @@ send_notification(
87
89
  )
88
90
  ```
89
91
 
90
- ### Function Reference
92
+ ---
93
+
94
+ ### **Assist** -- How to Copy image to app folder
95
+
96
+ ```python
97
+ import shutil # This module comes packaged with python
98
+ from android.storage import app_storage_path # type: ignore -- This works only on android
99
+
100
+ app_path = os.path.join(app_storage_path(),'app')
101
+ image_path= "/storage/emulated/0/Download/profile.png"
102
+
103
+ shutil.copy(image_path, os.path.join(app_path, "profile.png"))
104
+ ```
105
+
106
+ ---
107
+
108
+ ### **Functions Reference**
91
109
 
92
- #### `send_notification`
110
+ ### 1. `asks_permission_if_needed()`
93
111
 
94
- - **title** (*str*): Notification title.
95
- - **message** (*str*): Notification message body.
96
- - **style** (*str*): Notification style (`big_text`, `big_picture`, `inbox`, `large_icon`).
97
- - **img_path** (*str*): Path to the image (for `big_picture` or `large_icon` styles).
98
- - **channel_id** (*str*): Notification channel ID.
112
+ **Description:**
99
113
 
100
- #### `get_image_uri`
114
+ - Checks if notification permissions are granted and requests them if missing.
101
115
 
102
- - Resolves the absolute URI of an image resource.
103
- - **relative_path** (*str*): The relative path to the image.
116
+ **Usage:**
117
+
118
+ ```python
119
+ asks_permission_if_needed()
120
+ ```
121
+
122
+ ---
123
+
124
+ ### 2. `get_image_uri(relative_path)`
125
+
126
+ **Description:**
127
+
128
+ - Resolves the absolute URI for an image in the app's storage.
129
+
130
+ **Parameters:**
131
+
132
+ - `relative_path` *(str)*: Path to the image (e.g., `assets/imgs/icon.png`).
133
+
134
+ **Returns:**
135
+
136
+ - `Uri`: Android URI object for the image.
137
+
138
+ **Usage:**
139
+
140
+ ```python
141
+ uri = get_image_uri('assets/imgs/icon.png')
142
+ ```
143
+
144
+ ---
145
+
146
+ ### 3. `send_notification(title, message, style=None, img_path=None, channel_id='default_channel')`
147
+
148
+ **Description:**
149
+
150
+ - Sends an Android notification with optional styles and images.
151
+
152
+ **Parameters:**
153
+
154
+ - `title` *(str)*: Notification title.
155
+ - `message` *(str)*: Notification message.
156
+ - `style` *(str, optional)*: Notification style (`big_text`, `big_picture`, `inbox`, `large_icon`).
157
+ - `img_path` *(str, optional)*: Path to the image resource.(for `big_picture` or `large_icon` styles).
158
+ - `channel_id` *(str, optional)*: Notification channel ID.
159
+
160
+ Returns - notification id
104
161
 
105
162
  ### Advanced Usage
106
163
 
@@ -122,6 +179,15 @@ Feel free to open issues or submit pull requests for improvements!
122
179
 
123
180
  Found a bug? Please open an issue on our [GitHub Issues](https://github.com/Fector101/android_notify/issues) page.
124
181
 
182
+ ## Author
183
+
184
+ - Fabian - <fector101@yahoo.com>
185
+ - GitHub: <https://github.com/Fector101/android_notify>
186
+
187
+ For feedback or contributions, feel free to reach out!
188
+
189
+ ---
190
+
125
191
  ## ☕ Support the Project
126
192
 
127
193
  If you find this project helpful, consider buying me a coffee! Your support helps maintain and improve the project.
@@ -130,11 +196,15 @@ If you find this project helpful, consider buying me a coffee! Your support help
130
196
  <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60">
131
197
  </a>
132
198
 
133
- ## Author
134
-
135
- - Fabian - <fector101@yahoo.com>
136
- - GitHub: <https://github.com/Fector101/android_notify>
199
+ ---
137
200
 
138
201
  ## Acknowledgments
139
202
 
140
203
  - Thanks to the Kivy and Pyjnius communities for their support.
204
+
205
+ ---
206
+
207
+ ## 🌐 **Links**
208
+
209
+ - **PyPI:** [android-notify on PyPI](https://pypi.org/project/android-notify/)
210
+ - **GitHub:** [Source Code Repository](hhttps://github.com/Fector101/android_notify/)
@@ -0,0 +1,8 @@
1
+ android_notify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ android_notify/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ android_notify/core.py,sha256=P80jtB4Dim9c10ibgVPioEDJOKgjcoetl7rHAHEZEAI,5960
4
+ android_notify/styles.py,sha256=P_8sAqb3Hbf_vbhqSoCVjKeqJ05Fr_CksO-HX5pj8pU,134
5
+ android_notify-1.2.dist-info/METADATA,sha256=pkhzt6TaEZ1gTTEShVpXrATujLqcsVA-GQn3g7X65Qg,5125
6
+ android_notify-1.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
7
+ android_notify-1.2.dist-info/top_level.txt,sha256=IR1ONMrRSRINZpWn2X0dL5gbWwWINsK7PW8Jy2p4fU8,15
8
+ android_notify-1.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,8 +0,0 @@
1
- android_notify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- android_notify/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- android_notify/core.py,sha256=0edRXIF6ltTboJtkGjnOhLJDrYCYa2fzrB7cy61Y1PM,6598
4
- android_notify/styles.py,sha256=P_8sAqb3Hbf_vbhqSoCVjKeqJ05Fr_CksO-HX5pj8pU,134
5
- android_notify-1.1.dist-info/METADATA,sha256=q2w4ak4jAcfJ9103bpKU-kPXdFdVgtpc4cbI7z5nd9I,3808
6
- android_notify-1.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
7
- android_notify-1.1.dist-info/top_level.txt,sha256=IR1ONMrRSRINZpWn2X0dL5gbWwWINsK7PW8Jy2p4fU8,15
8
- android_notify-1.1.dist-info/RECORD,,