plugin android: attach an action dict to notification:
instead of calling plyer's generic notify, AndroidNotification is now inherited to add a SàT specific behaviour: a "sat_action" dictionary is now attached, to indicate to the frontend what to do when the notification is opened.
This commit is contained in:
parent
1a2078739e
commit
120289f08f
1 changed files with 90 additions and 9 deletions
|
|
@ -1,6 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
# SAT plugin for file tansfer
|
||||
# Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
|
||||
|
||||
|
|
@ -20,6 +19,7 @@
|
|||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import json
|
||||
from pathlib import Path
|
||||
from sat.core.i18n import _, D_
|
||||
from sat.core.constants import Const as C
|
||||
|
|
@ -49,10 +49,23 @@ if sys.platform != "android":
|
|||
raise exceptions.CancelError("this module is not needed on this platform")
|
||||
|
||||
|
||||
from plyer import notification, vibrator
|
||||
from plyer import vibrator
|
||||
from plyer.platforms.android import activity
|
||||
from plyer.platforms.android.notification import AndroidNotification
|
||||
from jnius import autoclass
|
||||
from android.broadcast import BroadcastReceiver
|
||||
from android import python_act
|
||||
|
||||
|
||||
Context = autoclass('android.content.Context')
|
||||
ConnectivityManager = autoclass('android.net.ConnectivityManager')
|
||||
MediaPlayer = autoclass('android.media.MediaPlayer')
|
||||
AudioManager = autoclass('android.media.AudioManager')
|
||||
|
||||
# notifications
|
||||
AndroidString = autoclass('java.lang.String')
|
||||
PendingIntent = autoclass('android.app.PendingIntent')
|
||||
Intent = autoclass('android.content.Intent')
|
||||
|
||||
#: delay between a pause event and sending the inactive indication to server, in seconds
|
||||
#: we don't send the indication immediately because user can be just checking something
|
||||
|
|
@ -84,12 +97,70 @@ NET_TYPE_NONE = "no network"
|
|||
NET_TYPE_WIFI = "wifi"
|
||||
NET_TYPE_MOBILE = "mobile"
|
||||
NET_TYPE_OTHER = "other"
|
||||
INTENT_EXTRA_ACTION = AndroidString("org.salut-a-toi.IntentAction")
|
||||
|
||||
|
||||
Context = autoclass('android.content.Context')
|
||||
ConnectivityManager = autoclass('android.net.ConnectivityManager')
|
||||
MediaPlayer = autoclass('android.media.MediaPlayer')
|
||||
AudioManager = autoclass('android.media.AudioManager')
|
||||
class Notification(AndroidNotification):
|
||||
# We extend plyer's AndroidNotification instead of creating directly with jnius
|
||||
# because it already handles issues like backward compatibility, and we just want to
|
||||
# slightly modify the behaviour.
|
||||
|
||||
@staticmethod
|
||||
def _set_open_behavior(notification, sat_action):
|
||||
# we reproduce plyer's AndroidNotification._set_open_behavior
|
||||
# bu we add SàT specific extra action data
|
||||
|
||||
app_context = activity.getApplication().getApplicationContext()
|
||||
notification_intent = Intent(app_context, python_act)
|
||||
|
||||
notification_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
notification_intent.setAction(Intent.ACTION_MAIN)
|
||||
notification_intent.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
if sat_action is not None:
|
||||
action_data = AndroidString(json.dumps(sat_action).encode())
|
||||
log.debug(f"adding extra {INTENT_EXTRA_ACTION} ==> {action_data}")
|
||||
notification_intent = notification_intent.putExtra(
|
||||
INTENT_EXTRA_ACTION, action_data)
|
||||
|
||||
# we use PendingIntent.FLAG_UPDATE_CURRENT here, otherwise extra won't be set
|
||||
# in the new intent (the old ACTION_MAIN intent will be reused). This differs
|
||||
# from plyers original behaviour which set no flag here
|
||||
pending_intent = PendingIntent.getActivity(
|
||||
app_context, 0, notification_intent, PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
|
||||
notification.setContentIntent(pending_intent)
|
||||
notification.setAutoCancel(True)
|
||||
|
||||
def _notify(self, **kwargs):
|
||||
# we reproduce plyer's AndroidNotification._notify behaviour here
|
||||
# and we add handling of "sat_action" attribute (SàT specific).
|
||||
# we also set, where suitable, default values to empty string instead of
|
||||
# original None, as a string is expected (in plyer the empty string is used
|
||||
# in the generic "notify" method).
|
||||
sat_action = kwargs.pop("sat_action", None)
|
||||
noti = None
|
||||
message = kwargs.get('message', '').encode('utf-8')
|
||||
ticker = kwargs.get('ticker', '').encode('utf-8')
|
||||
title = AndroidString(
|
||||
kwargs.get('title', '').encode('utf-8')
|
||||
)
|
||||
icon = kwargs.get('app_icon', '')
|
||||
|
||||
if kwargs.get('toast', False):
|
||||
self._toast(message)
|
||||
return
|
||||
else:
|
||||
noti = self._build_notification(title)
|
||||
|
||||
noti.setContentTitle(title)
|
||||
noti.setContentText(AndroidString(message))
|
||||
noti.setTicker(AndroidString(ticker))
|
||||
|
||||
self._set_icons(noti, icon=icon)
|
||||
self._set_open_behavior(noti, sat_action)
|
||||
|
||||
self._open_notification(noti)
|
||||
|
||||
|
||||
class FrontendStateProtocol(protocol.Protocol):
|
||||
|
|
@ -252,9 +323,19 @@ class AndroidPlugin(object):
|
|||
try:
|
||||
subject = next(iter(mess_data["subject"].values()))
|
||||
except StopIteration:
|
||||
subject = "Cagou new message"
|
||||
subject = D_("new message from {contact}").format(
|
||||
contact = mess_data['from'])
|
||||
|
||||
notification.notify(title=subject, message=message)
|
||||
notification = Notification()
|
||||
notification._notify(
|
||||
title=subject,
|
||||
message=message,
|
||||
sat_action={
|
||||
"type": "open",
|
||||
"widget": "chat",
|
||||
"target": mess_data["from"].userhost(),
|
||||
},
|
||||
)
|
||||
|
||||
ringer_mode = self.am.getRingerMode()
|
||||
vibrate_mode = ringer_mode == AudioManager.RINGER_MODE_VIBRATE
|
||||
|
|
|
|||
Loading…
Reference in a new issue