emacs/java/org/gnu/emacs/EmacsDesktopNotification.java
Po Lu df5a9a78b5 Update Android port
* doc/lispref/os.texi (Desktop Notifications): Revise
documentation for android-notifications-notify to reflect
changes.

* java/org/gnu/emacs/EmacsDesktopNotification.java (display1):
Convert notification importance to a legacy priority between
Android 7.1 and 4.1.

* java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap): Remove
immutable bitmap constructor, as the underlying Android API
functions are erroneously implemented.

* src/android.c (android_init_emacs_pixmap): Cease searching for
deleted constructor.
(android_create_pixmap_from_bitmap_data): Create a pixmap, then
fill it with the contents of the bitmap, in lieu of employing
the aforementioned constructor.

* src/androidselect.c (Fandroid_notifications_notify): Revise
doc string.
2023-09-25 13:01:44 +08:00

202 lines
5.7 KiB
Java
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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 <https://www.gnu.org/licenses/>. */
package org.gnu.emacs;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
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 identifier of this notification's icon. */
public final int icon;
/* The importance of this notification's group. */
public final int importance;
public
EmacsDesktopNotification (String title, String content,
String group, String tag, int icon,
int importance)
{
this.content = content;
this.title = title;
this.group = group;
this.tag = tag;
this.icon = icon;
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;
Intent intent;
PendingIntent pending;
int priority;
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 (icon)
.build ());
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
/* Android 7.1 and earlier don't segregate notifications into
distinct categories, but permit an importance to be
assigned to each individual notification. */
switch (importance)
{
case 2: /* IMPORTANCE_LOW */
default:
priority = Notification.PRIORITY_LOW;
break;
case 3: /* IMPORTANCE_DEFAULT */
priority = Notification.PRIORITY_DEFAULT;
break;
case 4: /* IMPORTANCE_HIGH */
priority = Notification.PRIORITY_HIGH;
break;
}
notification = (new Notification.Builder (context)
.setContentTitle (title)
.setContentText (content)
.setSmallIcon (icon)
.setPriority (priority)
.build ());
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN)
notification.priority = priority;
}
else
{
notification = new Notification ();
notification.icon = icon;
/* 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);
}
/* Provide a content intent which starts Emacs when the
notification is clicked. */
intent = new Intent (context, EmacsActivity.class);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
pending = PendingIntent.getActivity (context, 0, intent,
PendingIntent.FLAG_IMMUTABLE);
else
pending = PendingIntent.getActivity (context, 0, intent, 0);
notification.contentIntent = pending;
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);
}
});
}
};