aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2023-08-20 20:23:56 +0800
committerPo Lu2023-08-20 20:25:53 +0800
commit4f714dc08137d36d0d1e886814008f2abe5712c0 (patch)
treee400e9263e9c1b779b07e56ea88533e6bd4adfb0 /java
parent321f6bd5722921175ac3dc8859daca74dbe3de6a (diff)
downloademacs-4f714dc08137d36d0d1e886814008f2abe5712c0.tar.gz
emacs-4f714dc08137d36d0d1e886814008f2abe5712c0.zip
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.
Diffstat (limited to 'java')
-rw-r--r--java/AndroidManifest.xml.in5
-rw-r--r--java/org/gnu/emacs/EmacsDesktopNotification.java152
-rw-r--r--java/res/layout/sdk8_notifications_view.xml31
-rw-r--r--java/res/values/strings.xml2
4 files changed, 189 insertions, 1 deletions
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 <https://www.gnu.org/licenses/>. -->
66 66
67 <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> 67 <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
68 68
69 <!-- And under Android 13 or later to post desktop
70 notifications. -->
71
72 <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
73
69 <uses-sdk android:minSdkVersion="@ANDROID_MIN_SDK@" 74 <uses-sdk android:minSdkVersion="@ANDROID_MIN_SDK@"
70 android:targetSdkVersion="33"/> 75 android:targetSdkVersion="33"/>
71 76
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 @@
1/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
2
3Copyright (C) 2023 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20package org.gnu.emacs;
21
22import android.app.Notification;
23import android.app.NotificationManager;
24import android.app.NotificationChannel;
25
26import android.content.Context;
27
28import android.os.Build;
29
30import android.widget.RemoteViews;
31
32
33
34/* Structure designating a single desktop notification.
35
36 New versions of Android also organize notifications into individual
37 ``channels'', which are used to implement groups. Unlike on other
38 systems, notification importance is set for each group, not for
39 each individual notification. */
40
41
42
43public final class EmacsDesktopNotification
44{
45 /* The content of this desktop notification. */
46 public final String content;
47
48 /* The title of this desktop notification. */
49 public final String title;
50
51 /* The notification group. */
52 public final String group;
53
54 /* String identifying this notification for future replacement.
55 Typically a string resembling ``XXXX.NNNN.YYYY'', where XXXX is
56 the system boot time, NNNN is the PID of this Emacs instance, and
57 YYYY is the counter value returned by the notifications display
58 function. */
59 public final String tag;
60
61 /* The importance of this notification's group. */
62 public final int importance;
63
64 public
65 EmacsDesktopNotification (String title, String content,
66 String group, String tag, int importance)
67 {
68 this.content = content;
69 this.title = title;
70 this.group = group;
71 this.tag = tag;
72 this.importance = importance;
73 }
74
75
76
77 /* Functions for displaying desktop notifications. */
78
79 /* Internal helper for `display' executed on the main thread. */
80
81 @SuppressWarnings ("deprecation") /* Notification.Builder (Context). */
82 private void
83 display1 (Context context)
84 {
85 NotificationManager manager;
86 NotificationChannel channel;
87 Notification notification;
88 Object tem;
89 RemoteViews contentView;
90
91 tem = context.getSystemService (Context.NOTIFICATION_SERVICE);
92 manager = (NotificationManager) tem;
93
94 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
95 {
96 /* Create the notification channel for this group. If a group
97 already exists with the same name, its linked attributes
98 (such as its importance) will be overridden. */
99 channel = new NotificationChannel (group, group, importance);
100 manager.createNotificationChannel (channel);
101
102 /* Create a notification object and display it. */
103 notification = (new Notification.Builder (context, group)
104 .setContentTitle (title)
105 .setContentText (content)
106 .setSmallIcon (R.drawable.emacs)
107 .build ());
108 }
109 else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
110 notification = (new Notification.Builder (context)
111 .setContentTitle (title)
112 .setContentText (content)
113 .setSmallIcon (R.drawable.emacs)
114 .build ());
115 else
116 {
117 notification = new Notification ();
118 notification.icon = R.drawable.emacs;
119
120 /* This remote widget tree is defined in
121 java/res/layout/sdk8_notifications_view.xml. */
122 notification.contentView
123 = contentView
124 = new RemoteViews ("org.gnu.emacs",
125 R.layout.sdk8_notifications_view);
126 contentView.setTextViewText (R.id.sdk8_notifications_title,
127 title);
128 contentView.setTextViewText (R.id.sdk8_notifications_content,
129 content);
130 }
131
132 manager.notify (tag, 2, notification);
133 }
134
135 /* Display this desktop notification.
136
137 Create a notification channel named GROUP or update its
138 importance if such a channel is already defined. */
139
140 public void
141 display ()
142 {
143 EmacsService.SERVICE.runOnUiThread (new Runnable () {
144 @Override
145 public void
146 run ()
147 {
148 display1 (EmacsService.SERVICE);
149 }
150 });
151 }
152};
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 @@
1<!-- Notification content widget tree for GNU Emacs on Android 2.3.
2
3Copyright (C) 2023 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. -->
19
20<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
21 android:orientation="vertical"
22 android:layout_width="match_parent"
23 android:layout_height="wrap_content"
24 android:padding="8dp">
25 <TextView android:id="@+id/sdk8_notifications_title"
26 android:layout_width="wrap_content"
27 android:layout_height="wrap_content"/>
28 <TextView android:id="@+id/sdk8_notifications_content"
29 android:layout_width="wrap_content"
30 android:layout_height="wrap_content"/>
31</LinearLayout>
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.
17You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. --> 18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. -->
19 19
20<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> 20<resources>
21 <string name="start_quick_title"> 21 <string name="start_quick_title">
22 Restart Emacs with -Q 22 Restart Emacs with -Q
23 </string> 23 </string>