diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
--- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
+++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java
@@ -16,7 +16,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
-*/
+ */
package org.kde.kdeconnect.Plugins.NotificationsPlugin;
@@ -40,6 +40,7 @@
import android.text.SpannableString;
import android.util.Log;
+import org.json.JSONArray;
import org.kde.kdeconnect.Helpers.AppsHelper;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
@@ -55,24 +56,31 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
+
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
@PluginFactory.LoadablePlugin
public class NotificationsPlugin extends Plugin implements NotificationReceiver.NotificationListener {
private final static String PACKET_TYPE_NOTIFICATION = "kdeconnect.notification";
private final static String PACKET_TYPE_NOTIFICATION_REQUEST = "kdeconnect.notification.request";
private final static String PACKET_TYPE_NOTIFICATION_REPLY = "kdeconnect.notification.reply";
+ private final static String PACKET_TYPE_NOTIFICATION_ACTION = "kdeconnect.notification.action";
+
+ private final static String TAG = "NotificationsPlugin";
private AppDatabase appDatabase;
private Set currentNotifications;
private Map pendingIntents;
+ private Map> actions;
private boolean serviceReady;
@Override
@@ -117,6 +125,7 @@
pendingIntents = new HashMap<>();
currentNotifications = new HashSet<>();
+ actions = new HashMap<>();
appDatabase = new AppDatabase(context, true);
@@ -153,6 +162,9 @@
return;
}
String id = getNotificationKeyCompat(statusBarNotification);
+
+ actions.remove(id);
+
NetworkPacket np = new NetworkPacket(PACKET_TYPE_NOTIFICATION);
np.set("id", id);
np.set("isCancel", true);
@@ -252,6 +264,22 @@
currentNotifications.add(key);
}
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (notification.actions != null && notification.actions.length > 0) {
+ actions.put(key, new LinkedList());
+ JSONArray jsonArray = new JSONArray();
+ for (Notification.Action action : notification.actions) {
+ if (null == action.title)
+ break;
+ Log.d(TAG, action.title.toString());
+ jsonArray.put(action.title.toString());
+ actions.get(key).add(action);
+ }
+ np.set("actions", jsonArray);
+ Log.d(TAG, np.getString("actions"));
+ }
+ }
+
np.set("id", key);
np.set("isClearable", statusBarNotification.isClearable());
np.set("appName", appName == null ? packageName : appName);
@@ -474,7 +502,30 @@
@Override
public boolean onPacketReceived(final NetworkPacket np) {
- if (np.getBoolean("request")) {
+ if (np.getType().equals(PACKET_TYPE_NOTIFICATION_ACTION) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+
+ String key = np.getString("key");
+ String title = np.getString("action");
+ PendingIntent intent = null;
+
+ Log.d(TAG, "Received action " + title);
+
+ for (Notification.Action a : actions.get(key)) {
+ if (a.title.equals(title)) {
+ intent = a.actionIntent;
+ }
+ }
+
+ if (intent != null) {
+ try {
+ Log.d(TAG, "Fire action " + title);
+ intent.send();
+ } catch (PendingIntent.CanceledException e) {
+ e.printStackTrace();
+ }
+ }
+
+ } else if (np.getBoolean("request")) {
if (serviceReady) {
NotificationReceiver.RunCommand(context, this::sendCurrentNotifications);
@@ -510,7 +561,7 @@
@Override
public String[] getSupportedPacketTypes() {
- return new String[]{PACKET_TYPE_NOTIFICATION_REQUEST, PACKET_TYPE_NOTIFICATION_REPLY};
+ return new String[]{PACKET_TYPE_NOTIFICATION_REQUEST, PACKET_TYPE_NOTIFICATION_REPLY, PACKET_TYPE_NOTIFICATION_ACTION};
}
@Override