diff options
| author | Po Lu | 2023-08-20 20:23:56 +0800 |
|---|---|---|
| committer | Po Lu | 2023-08-20 20:25:53 +0800 |
| commit | 4f714dc08137d36d0d1e886814008f2abe5712c0 (patch) | |
| tree | e400e9263e9c1b779b07e56ea88533e6bd4adfb0 /java | |
| parent | 321f6bd5722921175ac3dc8859daca74dbe3de6a (diff) | |
| download | emacs-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.in | 5 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsDesktopNotification.java | 152 | ||||
| -rw-r--r-- | java/res/layout/sdk8_notifications_view.xml | 31 | ||||
| -rw-r--r-- | java/res/values/strings.xml | 2 |
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 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | package org.gnu.emacs; | ||
| 21 | |||
| 22 | import android.app.Notification; | ||
| 23 | import android.app.NotificationManager; | ||
| 24 | import android.app.NotificationChannel; | ||
| 25 | |||
| 26 | import android.content.Context; | ||
| 27 | |||
| 28 | import android.os.Build; | ||
| 29 | |||
| 30 | import 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 | |||
| 43 | public 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 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along 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. | |||
| 17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
| 18 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. --> | 18 | along 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> |