android-notify 1.3__py3-none-any.whl → 1.5__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.

@@ -1,3 +1,4 @@
1
+ """"For Easier Imports For Public Classes"""
1
2
  from .core import send_notification
2
3
  from .styles import NotificationStyles
3
- from .sword import Notification
4
+ from .sword import Notification,NotificationHandler
android_notify/core.py CHANGED
@@ -1,10 +1,10 @@
1
1
  """ Non-Advanced Stuff """
2
2
  import random
3
3
  import os
4
- from jnius import autoclass,cast
5
4
 
6
5
  ON_ANDROID = False
7
6
  try:
7
+ from jnius import autoclass,cast # Needs Java to be installed
8
8
  # Get the required Java classes
9
9
  PythonActivity = autoclass('org.kivy.android.PythonActivity')
10
10
  NotificationChannel = autoclass('android.app.NotificationChannel')
android_notify/sword.py CHANGED
@@ -1,15 +1,19 @@
1
1
  """This Module Contain Class for creating Notification With Java"""
2
2
  import difflib
3
- import random
3
+ import traceback
4
4
  import os
5
5
  import re
6
- from jnius import autoclass,cast # pylint: disable=W0611, C0114
7
6
 
8
7
  DEV=0
9
8
  ON_ANDROID = False
10
9
 
11
10
  try:
11
+ from jnius import autoclass,cast # Needs Java to be installed pylint: disable=W0611, C0114
12
+ from android import activity # pylint: disable=import-error
13
+ from android.config import ACTIVITY_CLASS_NAME # pylint: disable=import-error
14
+
12
15
  # Get the required Java classes
16
+ Bundle = autoclass('android.os.Bundle')
13
17
  PythonActivity = autoclass('org.kivy.android.PythonActivity')
14
18
  String = autoclass('java.lang.String')
15
19
  Intent = autoclass('android.content.Intent')
@@ -56,17 +60,21 @@ class Notification:
56
60
  :param style: Style of the notification
57
61
  ('simple', 'progress', 'big_text', 'inbox', 'big_picture', 'large_icon', 'both_imgs').
58
62
  both_imgs == using lager icon and big picture
59
- :param big_picture_path: Path to the image resource.
60
- :param large_icon_path: Path to the image resource.
63
+ :param big_picture_path: Relative Path to the image resource.
64
+ :param large_icon_path: Relative Path to the image resource.
65
+ :param callback: Function for notification Click.
61
66
  ---
62
67
  (Advance Options)
63
- :param channel_name: Defaults to "Default Channel"
64
- :param channel_id: Defaults to "default_channel"
68
+ :param channel_name: - str Defaults to "Default Channel"
69
+ :param channel_id: - str Defaults to "default_channel"
65
70
  ---
66
71
  (Options during Dev On PC)
67
- :param logs: Defaults to True
72
+ :param logs: - Bool Defaults to True
68
73
  """
69
- notification_ids=[]
74
+ notification_ids=[0]
75
+ button_ids=[0]
76
+ btns_box={}
77
+ main_functions={}
70
78
  style_values=[
71
79
  '','simple',
72
80
  'progress','big_text',
@@ -80,11 +88,13 @@ class Notification:
80
88
  'style':'simple',
81
89
  'big_picture_path':'',
82
90
  'large_icon_path':'',
83
- 'progress_max_value': 100,
91
+ 'progress_max_value': 0,
84
92
  'progress_current_value': 0,
85
93
  'channel_name':'Default Channel',
86
94
  'channel_id':'default_channel',
87
95
  'logs':True,
96
+ "identifer": '',
97
+ 'callback': None
88
98
  }
89
99
  # During Development (When running on PC)
90
100
  logs=not ON_ANDROID
@@ -97,22 +107,30 @@ class Notification:
97
107
  self.large_icon_path=''
98
108
  self.big_picture_path=''
99
109
  self.progress_current_value=0
100
- self.progress_max_value=100
110
+ self.progress_max_value=0
111
+
112
+ # For Nofitication Functions
113
+ self.identifer=''
114
+ self.callback = None
115
+
101
116
  # Advance Options
102
- self.channel_name=''
103
- self.channel_id=''
117
+ self.channel_name='Default Channel'
118
+ self.channel_id='default_channel'
104
119
  self.silent=False
120
+
105
121
  # During Dev on PC
106
122
  self.logs=self.logs
123
+
107
124
  # Private (Don't Touch)
108
125
  self.__id = self.__getUniqueID()
109
126
  self.__setArgs(kwargs)
110
- self.__builder=None
127
+
111
128
  if not ON_ANDROID:
112
129
  return
113
130
  # TODO make send method wait for __asks_permission_if_needed method
114
131
  self.__asks_permission_if_needed()
115
132
  self.notification_manager = context.getSystemService(context.NOTIFICATION_SERVICE)
133
+ self.__builder=NotificationCompatBuilder(context, self.channel_id)# pylint: disable=E0606
116
134
 
117
135
  def updateTitle(self,new_title):
118
136
  """Changes Old Title
@@ -136,6 +154,11 @@ class Notification:
136
154
 
137
155
  def updateProgressBar(self,current_value,message:str=''):
138
156
  """message defaults to last message"""
157
+ if not ON_ANDROID:
158
+ return
159
+
160
+ if self.logs:
161
+ print(f'Progress Bar Update value: {current_value}')
139
162
  self.__builder.setProgress(self.progress_max_value, current_value, False)
140
163
  if message:
141
164
  self.__builder.setContentText(String(message))
@@ -159,16 +182,12 @@ class Notification:
159
182
  self.__startNotificationBuild()
160
183
  self.notification_manager.notify(self.__id, self.__builder.build())
161
184
  elif self.logs:
162
- print(f"""
163
- Dev Notification Properties:
164
- title: '{self.title}'
165
- message: '{self.message}'
166
- large_icon_path: '{self.large_icon_path}'
167
- big_picture_path: '{self.big_picture_path}'
168
- style: '{self.style}'
169
- Silent: '{self.silent}'
170
- (Won't Print Logs When Complied,except if selected `Notification.logs=True`
171
- """)
185
+ string_to_display=''
186
+ for name,value in vars(self).items():
187
+ if value and name not in ['logs','_Notification__id']:
188
+ string_to_display += f'\n {name}: {value}'
189
+ string_to_display +="\n (Won't Print Logs When Complied,except if selected `Notification.logs=True`)"
190
+ print(string_to_display)
172
191
  if DEV:
173
192
  print(f'channel_name: {self.channel_name}, Channel ID: {self.channel_id}, id: {self.__id}')
174
193
  print('Can\'t Send Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" for Documentation.\n' if DEV else '\n') # pylint: disable=C0301
@@ -202,14 +221,14 @@ class Notification:
202
221
 
203
222
  def __setArgs(self,options_dict:dict):
204
223
  for key,value in options_dict.items():
205
- if key == 'channel_name':
206
- setattr(self,key, value[:40] if value else self.defaults[key])
207
- elif key == 'channel_id' and value:
208
- setattr(self,key, self.__generate_channel_id(value) if value else self.defaults[key])
209
-
210
- setattr(self,key, value if value else self.defaults[key])
211
-
212
- if "channel_id" not in options_dict and 'channel_name' in options_dict:
224
+ if key == 'channel_name' and value.strip():
225
+ setattr(self,key, value[:40])
226
+ elif key == 'channel_id' and value.strip(): # If user input's a channel id (i format properly)
227
+ setattr(self,key, self.__generate_channel_id(value))
228
+ else:
229
+ setattr(self,key, value if value else self.defaults[key])
230
+
231
+ if "channel_id" not in options_dict and 'channel_name' in options_dict: # if User doesn't input channel id but inputs channel_name
213
232
  setattr(self,'channel_id', self.__generate_channel_id(options_dict['channel_name']))
214
233
 
215
234
  def __startNotificationBuild(self):
@@ -219,8 +238,10 @@ class Notification:
219
238
 
220
239
  def __createBasicNotification(self):
221
240
  # Notification Channel (Required for Android 8.0+)
241
+ # print("THis is cchannel is ",self.channel_id) #"BLAH"
222
242
  if BuildVersion.SDK_INT >= 26 and self.notification_manager.getNotificationChannel(self.channel_id) is None:
223
243
  importance=NotificationManagerCompat.IMPORTANCE_DEFAULT if self.silent else NotificationManagerCompat.IMPORTANCE_HIGH # pylint: disable=possibly-used-before-assignment
244
+ # importance = 3 or 4
224
245
  channel = NotificationChannel(
225
246
  self.channel_id,
226
247
  self.channel_name,
@@ -229,14 +250,13 @@ class Notification:
229
250
  self.notification_manager.createNotificationChannel(channel)
230
251
 
231
252
  # Build the notification
232
- self.__builder = NotificationCompatBuilder(context, self.channel_id)# pylint: disable=E0606
233
- self.__builder.setContentTitle(self.title)
234
- self.__builder.setContentText(self.message)
253
+ # self.__builder = NotificationCompatBuilder(context, self.channel_id)# pylint: disable=E0606
254
+ self.__builder.setContentTitle(str(self.title))
255
+ self.__builder.setContentText(str(self.message))
235
256
  self.__builder.setSmallIcon(context.getApplicationInfo().icon)
236
257
  self.__builder.setDefaults(NotificationCompat.DEFAULT_ALL) # pylint: disable=E0606
237
- if not self.silent:
238
- self.__builder.setPriority(NotificationCompat.PRIORITY_DEFAULT if self.silent else NotificationCompat.PRIORITY_HIGH)
239
-
258
+ self.__builder.setPriority(NotificationCompat.PRIORITY_DEFAULT if self.silent else NotificationCompat.PRIORITY_HIGH)
259
+ self.__addIntentToOpenApp()
240
260
  def __addNotificationStyle(self):
241
261
  # pylint: disable=trailing-whitespace
242
262
 
@@ -280,7 +300,7 @@ class Notification:
280
300
  big_pic_bitmap = self.__getBitmap(big_pic_javapath)
281
301
  big_picture_style = NotificationCompatBigPictureStyle().bigPicture(big_pic_bitmap)
282
302
  self.__builder.setStyle(big_picture_style)
283
- elif large_icon_javapath:
303
+ if large_icon_javapath:
284
304
  large_icon_bitmap = self.__getBitmap(large_icon_javapath)
285
305
  self.__builder.setLargeIcon(large_icon_bitmap)
286
306
  elif self.style == 'progress':
@@ -295,10 +315,7 @@ class Notification:
295
315
  # return self.__builder
296
316
 
297
317
  def __getUniqueID(self):
298
- reasonable_amount_of_notifications=101
299
- notification_id = random.randint(1, reasonable_amount_of_notifications)
300
- while notification_id in self.notification_ids:
301
- notification_id = random.randint(1, 100)
318
+ notification_id = self.notification_ids[-1] + 1
302
319
  self.notification_ids.append(notification_id)
303
320
  return notification_id
304
321
 
@@ -350,26 +367,181 @@ class Notification:
350
367
  channel_id = channel_id.strip('_')
351
368
  return channel_id[:50]
352
369
 
353
- # try:
354
- # notify=Notification(titl='My Title',channel_name='Go')#,logs=False)
355
- # # notify.channel_name='Downloads'
356
- # notify.message="Blah"
357
- # notify.send()
358
- # notify.updateTitle('New Title')
359
- # notify.updateMessage('New Message')
360
- # notify.send(True)
361
- # except Exception as e:
362
- # print(e)
363
-
364
- # notify=Notification(title='My Title1')
365
- # # notify.updateTitle('New Title1')
366
- # notify.send()
367
-
368
-
369
- # Notification.logs=False # Add in Readme
370
- # notify=Notification(style='large_icon',title='My Title',channel_name='Some thing about a thing ')#,logs=False)
371
- # # notify.channel_name='Downloads'
372
- # notify.message="Blah"
373
- # notify.send()
374
- # notify.updateTitle('New Title')
375
- # notify.updateMessage('New Message')
370
+ def __addIntentToOpenApp(self):
371
+ intent = Intent(context, PythonActivity)
372
+ action = str(self.identifer) or f"ACTION_{self.__id}"
373
+ intent.setAction(action)
374
+ self.__addDataToIntent(intent)
375
+ self.main_functions[action]=self.callback
376
+ intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
377
+
378
+ pending_intent = PendingIntent.getActivity(
379
+ context, 0,
380
+ intent, PendingIntent.FLAG_IMMUTABLE if BuildVersion.SDK_INT >= 31 else PendingIntent.FLAG_UPDATE_CURRENT
381
+ )
382
+ self.__builder.setContentIntent(pending_intent)
383
+ self.__builder.setAutoCancel(True)
384
+
385
+ def __addDataToIntent(self,intent):
386
+ """Persit Some data to notification object for later use"""
387
+ bundle = Bundle()
388
+ bundle.putString("title", self.title or 'Title Placeholder')
389
+ bundle.putInt("notify_id", self.__id)
390
+ intent.putExtras(bundle)
391
+
392
+ def __getIDForButton(self):
393
+ btn_id = self.button_ids[-1] + 1
394
+ self.button_ids.append(btn_id)
395
+ return btn_id
396
+
397
+ def addButton(self, text:str,on_release):
398
+ """For adding action buttons
399
+
400
+ Args:
401
+ text (str): Text For Button
402
+ """
403
+ if self.logs:
404
+ print('Added Button: ', text)
405
+
406
+ if not ON_ANDROID:
407
+ return
408
+
409
+ btn_id= self.__getIDForButton()
410
+ action = f"BTN_ACTION_{btn_id}"
411
+
412
+ action_intent = Intent(context, PythonActivity)
413
+ action_intent.setAction(action)
414
+ action_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
415
+ bundle = Bundle()
416
+ bundle.putString("title", self.title or 'Title Placeholder')
417
+ bundle.putInt("key_int", 123)
418
+ action_intent.putExtras(bundle)
419
+ action_intent.putExtra("button_id", btn_id)
420
+
421
+ self.btns_box[action] = on_release
422
+ # action_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP)
423
+
424
+ if self.logs:
425
+ print('Button id: ',btn_id)
426
+ pending_action_intent = PendingIntent.getActivity(
427
+ context,
428
+ 0,
429
+ action_intent,
430
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
431
+ )
432
+ # Convert text to CharSequence
433
+ action_text = cast('java.lang.CharSequence', String(text))
434
+
435
+
436
+
437
+ # Add action with proper types
438
+ self.__builder.addAction(
439
+ int(context.getApplicationInfo().icon), # Cast icon to int
440
+ action_text, # CharSequence text
441
+ pending_action_intent # PendingIntent
442
+ )
443
+ # Set content intent for notification tap
444
+ self.__builder.setContentIntent(pending_action_intent)
445
+
446
+
447
+ class NotificationHandler:
448
+ """For Notification Operations """
449
+ __identifer = None
450
+
451
+ @classmethod
452
+ def getIdentifer(cls):
453
+ """Returns identifer for Clicked Notification."""
454
+ if not cls.is_on_android():
455
+ return "Not on Android"
456
+
457
+ saved_intent = cls.__identifer
458
+ if not saved_intent or (isinstance(saved_intent, str) and saved_intent.startswith("android.intent")):
459
+ # All other notifications are not None after First notification opens app
460
+ # NOTE these notifications are also from Last time app was opened and they Still Give Value after first one opens App
461
+ # TODO Find a way to get intent when App if Swiped From recents
462
+ __PythonActivity = autoclass(ACTIVITY_CLASS_NAME)
463
+ __mactivity = __PythonActivity.mActivity
464
+ __context = cast('android.content.Context', __mactivity)
465
+ __Intent = autoclass('android.content.Intent')
466
+ __intent = __Intent(__context, __PythonActivity)
467
+ action = __intent.getAction()
468
+ print('Start up Intent ----', action)
469
+ print('start Up Title --->',__intent.getStringExtra("title"))
470
+
471
+ return saved_intent
472
+
473
+ @classmethod
474
+ def __notificationHandler(cls,intent):
475
+ """Calls Function Attached to notification on click.
476
+ Don't Call this function manual, it's Already Attach to Notification.
477
+
478
+ Returns:
479
+ str: The Identiter of Nofication that was clicked.
480
+ """
481
+ if not cls.is_on_android():
482
+ return "Not on Android"
483
+ buttons_object=Notification.btns_box
484
+ notifty_functions=Notification.main_functions
485
+ if DEV:
486
+ print("notifty_functions ",notifty_functions)
487
+ print("buttons_object", buttons_object)
488
+ action = None
489
+ try:
490
+ action = intent.getAction()
491
+ cls.__identifer = action
492
+
493
+ print("The Action --> ",action)
494
+ if action == "android.intent.action.MAIN": # Not Open From Notification
495
+ return 'Not notification'
496
+
497
+ print(intent.getStringExtra("title"))
498
+ try:
499
+ if action in notifty_functions and notifty_functions[action]:
500
+ notifty_functions[action]()
501
+ elif action in buttons_object:
502
+ buttons_object[action]()
503
+ except Exception as e: # pylint: disable=broad-exception-caught
504
+ print('Failed to run function: ', traceback.format_exc())
505
+ print("Error Type ",e)
506
+ except Exception as e: # pylint: disable=broad-exception-caught
507
+ print('Notify Hanlder Failed ',e)
508
+ return action
509
+
510
+ @classmethod
511
+ def bindNotifyListener(cls):
512
+ """Binds the notification listener.\n\n
513
+ ```
514
+ from kivy.app import App
515
+ from android_notify import bindNotifyListener
516
+ class Myapp(App):
517
+ def on_start(self):
518
+ bindNotifyListener() # if successfull returns True
519
+ ```
520
+ """
521
+ if not cls.is_on_android():
522
+ return "Not on Android"
523
+ #Beta TODO Automatic bind when Notification object is called the first time use keep trying BroadcastReceiver
524
+ try:
525
+ activity.bind(on_new_intent=cls.__notificationHandler)
526
+ return True
527
+ except Exception as e: # pylint: disable=broad-exception-caught
528
+ print('Failed to bin notitfications listener',e)
529
+ return False
530
+ @classmethod
531
+ def unbindNotifyListener(cls):
532
+ """Removes Listener for Notifications Click"""
533
+ if not cls.is_on_android():
534
+ return "Not on Android"
535
+
536
+ #Beta TODO use BroadcastReceiver
537
+ try:
538
+ activity.unbind(on_new_intent=cls.__notificationHandler)
539
+ return True
540
+ except Exception as e: # pylint: disable=broad-exception-caught
541
+ print("Failed to unbind notifications listener: ",e)
542
+ return False
543
+
544
+ @staticmethod
545
+ def is_on_android():
546
+ """Utility to check if the app is running on Android."""
547
+ return ON_ANDROID
@@ -1,7 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: android-notify
3
- Version: 1.3
4
- Summary: A Python package that simpilfies creating Android Post notifications using PyJNIus in Kivy apps.
3
+ Version: 1.5
4
+ Summary: A Python package that simpilfies creating Android notifications in Kivy apps.
5
5
  Home-page: https://github.com/fector101/android-notify
6
6
  Author: Fabian
7
7
  Author-email: fector101@yahoo.com
@@ -21,22 +21,41 @@ Requires-Python: >=3.6
21
21
  Description-Content-Type: text/markdown
22
22
  Requires-Dist: kivy>=2.0.0
23
23
  Requires-Dist: pyjnius>=1.4.2
24
-
25
- # Android-Notifiy
26
-
27
- A Python library for effortlessly creating and managing Android notifications in Kivy android apps.
28
- Supports various styles and ensures seamless integration and customization.
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: classifier
27
+ Dynamic: description
28
+ Dynamic: description-content-type
29
+ Dynamic: home-page
30
+ Dynamic: keywords
31
+ Dynamic: license
32
+ Dynamic: project-url
33
+ Dynamic: requires-dist
34
+ Dynamic: requires-python
35
+ Dynamic: summary
36
+
37
+ <div align="center">
38
+ <br>
39
+ <h1> Android-Notifiy </h1>
40
+ <p> A Python library for effortlessly creating and managing Android notifications in Kivy android apps.</p>
41
+ <p>Supports various styles and ensures seamless integration and customization.</p>
42
+ <!-- <br> -->
43
+ <!-- <img src="https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/democollage.jpg"> -->
44
+ </div>
29
45
 
30
46
  ## Features
31
47
 
32
- - Compatible with Android 8.0+.
48
+ - Also Compatible with Android 8.0+.
33
49
  - Supports including images in notifications.
50
+ - All Notifications can take Functions (version 1.5+) [functions docs](#functions).
34
51
  - Support for multiple notification styles:
35
- - Progress
36
- - Big Picture
37
- - Inbox
38
- - Big Text
39
- - Large Icon
52
+ - [Simple](#basic-usage)
53
+ - [Progress](#progress-bar-notification)
54
+ - [Big Picture](#notification-with-an-image-big-picture-style)
55
+ - [Inbox](#inbox-notification-style)
56
+ - [Large Icon](#notification-with-an-image-large-icon-style)
57
+ - [Buttons](#notification-with-buttons)
58
+ - [Big Text](#big-text-notification-will-display-as-simple-text-if-device-dosent-support)
40
59
 
41
60
  This module automatically handles:
42
61
 
@@ -60,7 +79,7 @@ pip install android-notify
60
79
  In your **`buildozer.spec`** file, ensure you include the following:
61
80
 
62
81
  ```ini
63
- # Add pyjnius so it's packaged with the build
82
+ # Add pyjnius so ensure it's packaged with the build
64
83
  requirements = python3, kivy, pyjnius, android-notify
65
84
 
66
85
  # Add permission for notifications
@@ -81,7 +100,7 @@ from android_notify import Notification
81
100
  # Create a simple notification
82
101
  notification = Notification(
83
102
  title="Hello",
84
- message="This is a basic notification"
103
+ message="This is a basic notification."
85
104
  )
86
105
  notification.send()
87
106
  ```
@@ -104,6 +123,25 @@ The library supports multiple notification styles:
104
123
 
105
124
  ### Style Examples
106
125
 
126
+ #### Progress Bar notification
127
+
128
+ ```python
129
+ from kivy.clock import Clock
130
+
131
+ notification = Notification(
132
+ title="Downloading...",
133
+ message="0% downloaded",
134
+ style="progress",
135
+ progress_max_value=100,
136
+ progress_current_value=0
137
+ )
138
+ notification.send()
139
+ Clock.schedule_once(lambda dt: notification.updateProgressBar(30, "30% downloaded"), 350)
140
+ ```
141
+
142
+ **Sample Image:**
143
+ ![progress img sample](https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/progress.jpg)
144
+
107
145
  #### Notification with an Image (Big Picture Style)
108
146
 
109
147
  ```python
@@ -114,6 +152,8 @@ notification = Notification(
114
152
  style="big_picture",
115
153
  big_picture_path="assets/imgs/photo.png"
116
154
  )
155
+ notification.send()
156
+
117
157
  ```
118
158
 
119
159
  **Sample Image:**
@@ -128,52 +168,60 @@ notification = Notification(
128
168
  message='Line 1\nLine 2\nLine 3',
129
169
  style='inbox'
130
170
  )
171
+ notification.send()
172
+
131
173
  ```
132
174
 
133
175
  **Sample Image:**
134
176
  ![Inbox Notification sample](https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/inboxnoti.jpg)
135
177
 
136
- #### Big text notification (Will Display as simple text if Device dosen't support)
178
+ #### Notification with an Image (Large Icon Style)
137
179
 
138
180
  ```python
139
181
  notification = Notification(
140
- title="Article",
141
- message="Long article content...",
142
- style="big_text"
182
+ title="FabianDev_",
183
+ message="A twitter about some programming stuff",
184
+ style="large_icon",
185
+ large_icon_path="assets/imgs/profile.png"
143
186
  )
187
+
144
188
  ```
145
189
 
146
- #### Progress bar notification
190
+ **Sample Image:**
191
+ ![large_icon img sample](https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/large_icon.jpg)
192
+
193
+ #### Notification with Buttons
147
194
 
148
195
  ```python
149
- notification = Notification(
150
- title="Download",
151
- message="Downloading file...",
152
- style="progress",
153
- progress_max_value=100,
154
- progress_current_value=0
155
- )
196
+ notification = Notification(title="Jane Dough", message="How to use android-notify #coding #purepython")
197
+ def playVideo():
198
+ print('Playing Video')
199
+
200
+ def turnOffNoti():
201
+ print('Please Turn OFf Noti')
202
+
203
+ def watchLater():
204
+ print('Add to Watch Later')
156
205
 
206
+ notification.addButton(text="Play",on_release=playVideo)
207
+ notification.addButton(text="Turn Off",on_release=turnOffNoti)
208
+ notification.addButton(text="Watch Later",on_release=watchLater)
209
+ notification.send()
157
210
  ```
158
211
 
159
- **Sample Image:**
160
- ![progress img sample](https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/progress.jpg)
212
+ **Sample Image:**
213
+ ![btns img sample](https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/btns.jpg)
161
214
 
162
- #### Notification with an Image (Large Icon Style)
215
+ #### Big text notification (Will Display as normal text if Device dosen't support)
163
216
 
164
217
  ```python
165
218
  notification = Notification(
166
- title="Completed download",
167
- message="profile.jpg",
168
- style="large_icon",
169
- large_icon_path="assets/imgs/profile.png"
219
+ title="Article",
220
+ message="Long article content...",
221
+ style="big_text"
170
222
  )
171
-
172
223
  ```
173
224
 
174
- **Sample Image:**
175
- ![large_icon img sample](https://raw.githubusercontent.com/Fector101/android_notify/main/docs/imgs/large_icon.jpg)
176
-
177
225
  ## Advanced Features
178
226
 
179
227
  ### Updating Notifications
@@ -193,12 +241,12 @@ notification.updateMessage("New Message")
193
241
 
194
242
  ```python
195
243
  notification = Notification(
196
- title="Download Progress",
244
+ title="Download..",
197
245
  style="progress"
198
246
  )
199
247
 
200
248
  # Update progress
201
- notification.updateProgressBar(50, "50% Complete")
249
+ notification.updateProgressBar(30, "30% downloaded")
202
250
 
203
251
  # Remove progress bar
204
252
  notification.removeProgressBar("Download Complete")
@@ -214,8 +262,8 @@ Notifications are organized into channels. You can customize the channel name an
214
262
  notification = Notification(
215
263
  title="Download finished",
216
264
  message="How to Catch a Fish.mp4",
217
- channel_name="Download Notifications", # Will create User-visible name "downloads"
218
- channel_id="custom_downloads" # Optional: specify custom channel ID
265
+ channel_name="Download Notifications", # Will create User-visible name "Download Notifications"
266
+ channel_id="downloads_notifications" # Optional: specify custom channel ID
219
267
  )
220
268
  ```
221
269
 
@@ -231,6 +279,60 @@ notification = Notification(title="Silent Update")
231
279
  notification.send(silent=True)
232
280
  ```
233
281
 
282
+ ## Functions
283
+
284
+ ### NotificationHandler - To Attach Listener
285
+
286
+ Add this to your main.py App Class so it runs Once, In later Versions It'll be Attached Automatical
287
+
288
+ ```python
289
+ from kivymd.app import MDApp
290
+ from android_notify import Notification, NotificationHandler
291
+
292
+ class Myapp(MDApp):
293
+
294
+ def on_start(self):
295
+ # Is called Once when app is Starts up
296
+ NotificationHandler.bindNotifyListener() # if successfull returns True
297
+ Notification(title="Hello", message="This is a basic notification.",callback=self.doSomething).send()
298
+
299
+ def doSomething(self):
300
+ print("print in Debug Console")
301
+ ```
302
+
303
+ ### Get Which Notification was used to Open App - identifer (str)
304
+
305
+ If you just want to get the Exact Notification Clicked to Open App, you can use NotificationHandler to get unique identifer
306
+
307
+ ```python
308
+ from kivymd.app import MDApp
309
+ from android_notify import Notification, NotificationHandler
310
+
311
+ class Myapp(MDApp):
312
+
313
+ def on_start(self):
314
+
315
+ notify = Notification(title="Change Page", message="Click to change App page.", identifer='change_app_page')
316
+ notify.send()
317
+
318
+ notify1 = Notification(title="Change Colour", message="Click to change App Colour", identifer='change_app_color')
319
+ notify1.send()
320
+
321
+ NotificationHandler.bindNotifyListener()
322
+
323
+ def on_resume(self):
324
+ # Is called everytime app is reopened
325
+ notify_identifer = NotificationHandler.getIdentifer()
326
+ if notify_identifer == 'change_app_page':
327
+ # Code to change Screen
328
+ pass
329
+ elif notify_identifer == 'change_app_color':
330
+ # Code to change Screen Color
331
+ pass
332
+ ```
333
+
334
+
335
+
234
336
  ### Assist
235
337
 
236
338
  - How to Copy image to app folder
@@ -249,7 +351,7 @@ shutil.copy(image_path, os.path.join(app_path, "profile.png"))
249
351
 
250
352
  ```python
251
353
  from android_notify import Notification, NotificationStyles
252
- notification = Notification(
354
+ Notification(
253
355
  title="New Photo",
254
356
  message="Check out this image",
255
357
  style=NotificationStyles.BIG_PICTURE,
@@ -273,7 +375,7 @@ notification.send()
273
375
 
274
376
  ## Image Requirements
275
377
 
276
- - Images must be located within your app's asset folder
378
+ - Images must be located within your app's folder
277
379
  - Supported paths are relative to your app's storage path
278
380
  - Example: `assets/imgs/icon.png`
279
381
 
@@ -0,0 +1,9 @@
1
+ android_notify/__init__.py,sha256=lcLjyfegXgU7cyGhfSphAOBipXwemrVkdYy3mcF6X5Y,172
2
+ android_notify/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ android_notify/core.py,sha256=B3gOgbLGGI6tz-Q_T2wmk74oggOSDX0Qz4lqj00vaFo,6114
4
+ android_notify/styles.py,sha256=I2p31qStg9DaML9U4nXRvdpGzpppK6RS-qlDKuOv_Tk,328
5
+ android_notify/sword.py,sha256=6dmlTQRYtuhHUyO8E4fh3YlnLJC1FCvkLtgBKGvJnmI,23252
6
+ android_notify-1.5.dist-info/METADATA,sha256=D-xTAAdOyVgeK_kqcZL1cU_HAbwcFvJkwi6smOIE41Y,13161
7
+ android_notify-1.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
+ android_notify-1.5.dist-info/top_level.txt,sha256=IR1ONMrRSRINZpWn2X0dL5gbWwWINsK7PW8Jy2p4fU8,15
9
+ android_notify-1.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- android_notify/__init__.py,sha256=dAcsj7M_KHBOira9AVk4LtFFXRHTYsn6tza4Oz7T1MM,107
2
- android_notify/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- android_notify/core.py,sha256=hHzBnVw25x_WpMHp_HPKCuHEL2mQ7IHC_I3EqQZylas,6081
4
- android_notify/styles.py,sha256=I2p31qStg9DaML9U4nXRvdpGzpppK6RS-qlDKuOv_Tk,328
5
- android_notify/sword.py,sha256=8v28Q9x3CRRa3xDbHUd8629S5KvLy7xnjSygbqT-coQ,16271
6
- android_notify-1.3.dist-info/METADATA,sha256=fA2YdjiuZKnEWirQdnzci1l4di-EXmphkdlp41I0FzU,9831
7
- android_notify-1.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
8
- android_notify-1.3.dist-info/top_level.txt,sha256=IR1ONMrRSRINZpWn2X0dL5gbWwWINsK7PW8Jy2p4fU8,15
9
- android_notify-1.3.dist-info/RECORD,,