From 4f714dc08137d36d0d1e886814008f2abe5712c0 Mon Sep 17 00:00:00 2001
From: Po Lu
Date: Sun, 20 Aug 2023 20:23:56 +0800
Subject: Support desktop notifications on Android
* doc/emacs/android.texi (Android Environment): Correct list of
permissions granted by default.
* doc/lispref/os.texi (Desktop Notifications): Document the new
function `android-notifications-notify' and its limitations.
* java/AndroidManifest.xml.in: Request notification permissions.
* java/org/gnu/emacs/EmacsDesktopNotification.java: New file.
* java/res/layout/sdk8_notifications_view.xml: New file holding
substitute notification widget definitions for Android versions
prior to 3.0.
* java/res/values/strings.xml: Remove inadvertently introduced
tag attribute.
* lisp/org/org-clock.el (haiku-notifications-notify): Correct
file name in function declaration.
(android-notifications-notify): New declaration.
(org-show-notification): Use `android-notifications-notify'.
* src/androidselect.c (android_init_emacs_desktop_notification)
(android_notifications_notify_1, Fandroid_notifications_notify):
New functions.
(init_androidselect, syms_of_androidselect): Initialize new
class and define new subr.
---
java/AndroidManifest.xml.in | 5 +
java/org/gnu/emacs/EmacsDesktopNotification.java | 152 +++++++++++++++++++++++
java/res/layout/sdk8_notifications_view.xml | 31 +++++
java/res/values/strings.xml | 2 +-
4 files changed, 189 insertions(+), 1 deletion(-)
create mode 100644 java/org/gnu/emacs/EmacsDesktopNotification.java
create mode 100644 java/res/layout/sdk8_notifications_view.xml
(limited to 'java')
diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in
index 895e7f88c57..b9cda401c9d 100644
--- a/java/AndroidManifest.xml.in
+++ b/java/AndroidManifest.xml.in
@@ -66,6 +66,11 @@ along with GNU Emacs. If not, see . -->
+
+
+
+
diff --git a/java/org/gnu/emacs/EmacsDesktopNotification.java b/java/org/gnu/emacs/EmacsDesktopNotification.java
new file mode 100644
index 00000000000..8f55ffe8145
--- /dev/null
+++ b/java/org/gnu/emacs/EmacsDesktopNotification.java
@@ -0,0 +1,152 @@
+/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
+
+Copyright (C) 2023 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see . */
+
+package org.gnu.emacs;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.NotificationChannel;
+
+import android.content.Context;
+
+import android.os.Build;
+
+import android.widget.RemoteViews;
+
+
+
+/* Structure designating a single desktop notification.
+
+ New versions of Android also organize notifications into individual
+ ``channels'', which are used to implement groups. Unlike on other
+ systems, notification importance is set for each group, not for
+ each individual notification. */
+
+
+
+public final class EmacsDesktopNotification
+{
+ /* The content of this desktop notification. */
+ public final String content;
+
+ /* The title of this desktop notification. */
+ public final String title;
+
+ /* The notification group. */
+ public final String group;
+
+ /* String identifying this notification for future replacement.
+ Typically a string resembling ``XXXX.NNNN.YYYY'', where XXXX is
+ the system boot time, NNNN is the PID of this Emacs instance, and
+ YYYY is the counter value returned by the notifications display
+ function. */
+ public final String tag;
+
+ /* The importance of this notification's group. */
+ public final int importance;
+
+ public
+ EmacsDesktopNotification (String title, String content,
+ String group, String tag, int importance)
+ {
+ this.content = content;
+ this.title = title;
+ this.group = group;
+ this.tag = tag;
+ this.importance = importance;
+ }
+
+
+
+ /* Functions for displaying desktop notifications. */
+
+ /* Internal helper for `display' executed on the main thread. */
+
+ @SuppressWarnings ("deprecation") /* Notification.Builder (Context). */
+ private void
+ display1 (Context context)
+ {
+ NotificationManager manager;
+ NotificationChannel channel;
+ Notification notification;
+ Object tem;
+ RemoteViews contentView;
+
+ tem = context.getSystemService (Context.NOTIFICATION_SERVICE);
+ manager = (NotificationManager) tem;
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+ {
+ /* Create the notification channel for this group. If a group
+ already exists with the same name, its linked attributes
+ (such as its importance) will be overridden. */
+ channel = new NotificationChannel (group, group, importance);
+ manager.createNotificationChannel (channel);
+
+ /* Create a notification object and display it. */
+ notification = (new Notification.Builder (context, group)
+ .setContentTitle (title)
+ .setContentText (content)
+ .setSmallIcon (R.drawable.emacs)
+ .build ());
+ }
+ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ notification = (new Notification.Builder (context)
+ .setContentTitle (title)
+ .setContentText (content)
+ .setSmallIcon (R.drawable.emacs)
+ .build ());
+ else
+ {
+ notification = new Notification ();
+ notification.icon = R.drawable.emacs;
+
+ /* This remote widget tree is defined in
+ java/res/layout/sdk8_notifications_view.xml. */
+ notification.contentView
+ = contentView
+ = new RemoteViews ("org.gnu.emacs",
+ R.layout.sdk8_notifications_view);
+ contentView.setTextViewText (R.id.sdk8_notifications_title,
+ title);
+ contentView.setTextViewText (R.id.sdk8_notifications_content,
+ content);
+ }
+
+ manager.notify (tag, 2, notification);
+ }
+
+ /* Display this desktop notification.
+
+ Create a notification channel named GROUP or update its
+ importance if such a channel is already defined. */
+
+ public void
+ display ()
+ {
+ EmacsService.SERVICE.runOnUiThread (new Runnable () {
+ @Override
+ public void
+ run ()
+ {
+ display1 (EmacsService.SERVICE);
+ }
+ });
+ }
+};
diff --git a/java/res/layout/sdk8_notifications_view.xml b/java/res/layout/sdk8_notifications_view.xml
new file mode 100644
index 00000000000..2daa5beea86
--- /dev/null
+++ b/java/res/layout/sdk8_notifications_view.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 8a11cb007ee..0bf1ef0ac9b 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -17,7 +17,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see . -->
-
+
Restart Emacs with -Q
--
cgit v1.2.1