Skip to content

Commit 5842928

Browse files
authored
Merge pull request #5 from Fector101/flet-adv-support
Flet adv support
2 parents a45fa76 + 9e9d6bb commit 5842928

2 files changed

Lines changed: 94 additions & 48 deletions

File tree

android_notify/config.py

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
import os, traceback
2-
try:
3-
from jnius import cast, autoclass
4-
except ImportError as e:
5-
# So commandline still works if java isn't installed and get pyjinus import error
6-
print('Exception occured in __init__.py: ',e)
7-
cast = lambda x: x
8-
autoclass = lambda x: None
92

103
ON_ANDROID = False
114
__version__ = "1.60.2(dev)"
125

13-
try:
14-
from android import config
15-
ACTIVITY_CLASS_NAME = config.JAVA_NAMESPACE
16-
except (ImportError, AttributeError):
17-
ACTIVITY_CLASS_NAME = 'org.kivy.android'
6+
def on_flet_app():
7+
return os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME")
188

9+
def get_activity_class_name():
10+
ACTIVITY_CLASS_NAME = os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME") # flet python
11+
if not ACTIVITY_CLASS_NAME:
12+
try:
13+
from android import config
14+
ACTIVITY_CLASS_NAME = config.JAVA_NAMESPACE
15+
except (ImportError, AttributeError):
16+
ACTIVITY_CLASS_NAME = 'org.kivy.android'
17+
return ACTIVITY_CLASS_NAME
1918

19+
20+
if os.getenv("MAIN_ACTIVITY_HOST_CLASS_NAME"):
21+
from jnius import cast, autoclass
22+
else:
23+
# print('Not on Flet android env...\n')
24+
try:
25+
import kivy #TODO find var for kivy
26+
from jnius import cast, autoclass
27+
except Exception as e:
28+
print('android-notify: No pjnius, not on android')
29+
# So commandline still works if java isn't installed and get pyjinus import error
30+
# print('Exception occured in __init__.py: ',e)
31+
cast = lambda x: x
32+
autoclass = lambda x: None
2033
try:
2134
# Android Imports
22-
from android import activity as android_activity
23-
from jnius import autoclass,cast
2435

2536
# Get the required Java classes needs to on android to import
2637
Bundle = autoclass('android.os.Bundle')
@@ -33,29 +44,27 @@
3344
NotificationChannel = autoclass('android.app.NotificationChannel')
3445
RemoteViews = autoclass('android.widget.RemoteViews')
3546

36-
ON_ANDROID = True
47+
ON_ANDROID = RemoteViews
3748
except Exception as e:
3849
from .an_types import *
3950
if hasattr(e,'name') and e.name != 'android' :
4051
print('Exception: ',e)
4152
print(traceback.format_exc())
4253

54+
4355
if ON_ANDROID:
4456
try:
45-
from android.permissions import request_permissions, Permission, check_permission
46-
from android.storage import app_storage_path
47-
4857
NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
4958
NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
5059
IconCompat = autoclass('androidx.core.graphics.drawable.IconCompat')
60+
Color = autoclass('android.graphics.Color')
5161

5262
# Notification Design
5363
NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
5464
NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
5565
NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
5666
NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
5767
NotificationCompatDecoratedCustomViewStyle = autoclass('androidx.core.app.NotificationCompat$DecoratedCustomViewStyle')
58-
Color = autoclass('android.graphics.Color')
5968

6069
except Exception as dependencies_import_error:
6170
print('dependencies_import_error: ',dependencies_import_error)
@@ -65,23 +74,16 @@
6574
* android.enable_androidx = True
6675
* android.permissions = POST_NOTIFICATIONS
6776
""")
68-
def app_storage_path():
69-
return './'
77+
7078
from .an_types import *
71-
from .an_types import AndroidActivity as android_activity
7279
else:
73-
def app_storage_path():
74-
return './'
7580
from .an_types import *
76-
from .an_types import AndroidActivity as android_activity
77-
78-
7981

8082
def from_service_file():
8183
return 'PYTHON_SERVICE_ARGUMENT' in os.environ
8284

8385
run_on_ui_thread = None
84-
if from_service_file() or not ON_ANDROID:
86+
if on_flet_app() or from_service_file() or not ON_ANDROID:
8587
def run_on_ui_thread(func):
8688
"""Fallback for Developing on PC"""
8789

@@ -90,21 +92,22 @@ def wrapper(*args, **kwargs):
9092
return func(*args, **kwargs)
9193

9294
return wrapper
93-
else:
95+
else:# TODO find var for kivy
9496
from android.runnable import run_on_ui_thread
9597

9698
def get_python_activity():
9799
if not ON_ANDROID:
98100
from .an_types import PythonActivity
99101
return PythonActivity
102+
ACTIVITY_CLASS_NAME = get_activity_class_name()
100103
if from_service_file():
101-
# PythonService = autoclass(ACTIVITY_CLASS_NAME + '.PythonService')
102104
PythonActivity = autoclass(ACTIVITY_CLASS_NAME + '.PythonService')
105+
elif on_flet_app():
106+
PythonActivity = autoclass(ACTIVITY_CLASS_NAME)
103107
else:
104108
PythonActivity = autoclass(ACTIVITY_CLASS_NAME + '.PythonActivity')
105109
return PythonActivity
106110

107-
108111
def get_python_activity_context():
109112
if not ON_ANDROID:
110113
from .an_types import Context
@@ -130,3 +133,13 @@ def get_notification_manager():
130133
return None
131134
notification_service = context.getSystemService(context.NOTIFICATION_SERVICE)
132135
return cast(NotificationManager, notification_service)
136+
137+
def app_storage_path():
138+
if on_flet_app():
139+
return os.path.join(context.getFilesDir().getAbsolutePath(), 'flet')
140+
else:
141+
try:
142+
from android.storage import app_storage_path as kivy_app_storage_path # type: ignore
143+
return kivy_app_storage_path()
144+
except Exception as e:
145+
return './' # TODO return file main.py path (not android)

android_notify/sword.py

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,17 @@
88
get_android_importance, generate_channel_id, get_img_from_path, setLayoutText, \
99
get_bitmap_from_url, add_data_to_intent
1010

11-
from .config import from_service_file, get_python_activity,get_notification_manager,ON_ANDROID
11+
from .config import from_service_file, get_python_activity,get_notification_manager,ON_ANDROID,on_flet_app
1212
from .config import (Bundle, String, BuildVersion,
1313
Intent,PendingIntent,
1414
IconCompat,app_storage_path,
1515
NotificationChannel,RemoteViews,
16-
run_on_ui_thread,android_activity,
17-
request_permissions, Permission,check_permission
16+
run_on_ui_thread,
1817
)
1918
from .config import (NotificationCompat, NotificationCompatBuilder,
2019
NotificationCompatBigTextStyle,NotificationCompatBigPictureStyle,
2120
NotificationCompatInboxStyle, NotificationCompatDecoratedCustomViewStyle,
22-
Color
21+
Color
2322
)
2423
from .styles import NotificationStyles
2524
from .base import BaseNotification
@@ -622,7 +621,7 @@ def __dispatch_notification(self):
622621
self.notification_manager.notify(self.__id, self.__builder.build())
623622
except Exception as sending_notification_from_service_error:
624623
print('error sending notification from service:',sending_notification_from_service_error)
625-
elif self.passed_check or NotificationHandler.has_permission():
624+
elif on_flet_app() or self.passed_check or NotificationHandler.has_permission():
626625
try:
627626
self.notification_manager.notify(self.__id, self.__builder.build())
628627
except Exception as notify_error:
@@ -852,6 +851,10 @@ class NotificationHandler:
852851
__name = None
853852
__bound = False
854853
__requesting_permission=False
854+
android_activity=None
855+
if ON_ANDROID and not on_flet_app():
856+
from android import activity
857+
android_activity = activity
855858
@classmethod
856859
def get_name(cls):
857860
"""Returns name or id str for Clicked Notification."""
@@ -881,7 +884,7 @@ def get_name(cls):
881884
def __notification_handler(cls, intent):
882885
"""Calls Function Attached to notification on click.
883886
Don't Call this function manual, it's Already Attach to Notification.
884-
887+
885888
Sets self.__name #action of Notification that was clicked from Notification.name or Notification.id
886889
"""
887890
if not cls.is_on_android():
@@ -915,14 +918,17 @@ def __notification_handler(cls, intent):
915918
@classmethod
916919
def bindNotifyListener(cls):
917920
"""This Creates a Listener for All Notification Clicks and Functions"""
921+
if on_flet_app():
922+
return False
923+
918924
if not cls.is_on_android():
919925
return "Not on Android"
920926
#TODO keep trying BroadcastReceiver
921927
if cls.__bound:
922928
print("binding done already ")
923929
return True
924930
try:
925-
android_activity.bind(on_new_intent=cls.__notification_handler)
931+
cls.android_activity.bind(on_new_intent=cls.__notification_handler)
926932
cls.__bound = True
927933
return True
928934
except Exception as binding_listener_error:
@@ -936,10 +942,10 @@ def unbindNotifyListener(cls):
936942
return "Not on Android"
937943

938944
#Beta TODO use BroadcastReceiver
939-
if from_service_file():
945+
if on_flet_app() or from_service_file():
940946
return False # error 'NoneType' object has no attribute 'registerNewIntentListener'
941947
try:
942-
android_activity.unbind(on_new_intent=cls.__notification_handler)
948+
cls.android_activity.unbind(on_new_intent=cls.__notification_handler)
943949
return True
944950
except Exception as unbinding_listener_error:
945951
print("Failed to unbind notifications listener: ",unbinding_listener_error)
@@ -958,7 +964,22 @@ def has_permission():
958964
"""
959965
if not ON_ANDROID:
960966
return True
961-
return check_permission(Permission.POST_NOTIFICATIONS)
967+
968+
if on_flet_app():
969+
from .config import autoclass
970+
ContextCompat = autoclass('androidx.core.content.ContextCompat')
971+
Manifest = autoclass('android.Manifest$permission')
972+
VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')
973+
974+
if BuildVersion.SDK_INT >= VERSION_CODES.TIRAMISU:
975+
permission = Manifest.POST_NOTIFICATIONS
976+
return ContextCompat.checkSelfPermission(context, permission)
977+
else:
978+
print("android_notify- On Low android version don't need permission")
979+
return True #doesn't need permission
980+
else:
981+
from android.permissions import Permission, check_permission
982+
return check_permission(Permission.POST_NOTIFICATIONS)
962983

963984
@classmethod
964985
@run_on_ui_thread
@@ -984,23 +1005,35 @@ def on_permissions_result(permissions, grants):
9841005
cls.__requesting_permission = False
9851006

9861007
if not cls.has_permission():
987-
cls.__requesting_permission = True
988-
request_permissions([Permission.POST_NOTIFICATIONS],on_permissions_result)
1008+
if on_flet_app():
1009+
from .config import autoclass
1010+
ActivityCompat = autoclass('androidx.core.app.ActivityCompat')
1011+
Manifest = autoclass('android.Manifest$permission')
1012+
permission = Manifest.POST_NOTIFICATIONS
1013+
ActivityCompat.requestPermissions(context, [permission], 101)
1014+
return None
1015+
# TODO Callback when user answers request question
1016+
else:
1017+
from android.permissions import request_permissions, Permission
1018+
cls.__requesting_permission = True
1019+
request_permissions([Permission.POST_NOTIFICATIONS],on_permissions_result)
1020+
return None
9891021
else:
9901022
cls.__requesting_permission = False
9911023
if callback:
9921024
if can_accept_arguments(callback,True):
9931025
callback(True)
9941026
else:
9951027
callback()
1028+
return None
9961029

9971030

998-
if not from_service_file():
1031+
if not on_flet_app() and from_service_file():
1032+
print("didn't bind listener, In service file")
1033+
elif ON_ANDROID:
9991034
try:
10001035
NotificationHandler.bindNotifyListener()
10011036
except Exception as bind_error:
1037+
# error 'NoneType' object has no attribute 'registerNewIntentListener'
10021038
print("notification listener bind error:",bind_error)
1003-
traceback.print_exc()
1004-
else:
1005-
# error 'NoneType' object has no attribute 'registerNewIntentListener'
1006-
print("didn't bind listener, In service file:")
1039+
traceback.print_exc()

0 commit comments

Comments
 (0)