Skip to content

Electron - 通知

现代应用程序经常使用系统通知(System Notifications)来提醒用户重要事件,即使应用程序窗口没有焦点。Electron 提供内置的 Notification API,它可以在 Windows、macOS 和 Linux 上工作,利用每个操作系统的原生通知功能。

以前,像 node-notifier 这样的库很常见,但现在 Electron 的原生 Notification API 已成为大多数用例推荐的方法。

Notification 类是 electron 模块的一部分。通知通常在主进程(main process)中创建和管理。如果你需要在渲染进程(renderer process,例如,响应用户操作)中触发通知,你应该使用 IPC(Inter-Process Communication,进程间通信)来请求主进程显示它。

关键步骤:

  1. 在主进程中,监听来自渲染进程的 IPC 消息。
  2. 收到消息时,创建一个新的 Notification 实例,并设置所需的选项(标题、正文、图标等)。
  3. 在通知实例上调用 show() 方法。

我们来创建一个带按钮的应用程序,它将触发一个系统通知。

首先,你的 main.js 文件:

const { app, BrowserWindow, ipcMain, Notification } = require('electron');
const path = require('path');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
});
mainWindow.loadFile('index.html');
}
app.whenReady().then(createWindow);
ipcMain.on('show-notification', (event, { title, body, icon }) => {
if (Notification.isSupported()) { // Check if notifications are supported
const notification = new Notification({
title: title,
body: body,
// icon: icon ? path.join(__dirname, icon) : undefined // Optional: path to an icon file
// Note: Icon paths can be tricky. For local files, ensure they are accessible.
// For macOS, only .icns files are supported for notifications if packaged.
});
notification.on('click', () => {
console.log('Notification clicked');
// Optionally, bring window to front or perform an action
if (mainWindow) {
mainWindow.show();
}
});
notification.on('close', () => {
console.log('Notification closed');
});
notification.show();
} else {
console.log('Notifications are not supported on this system.');
}
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});

接下来,创建一个 preload.js 文件,以安全地向渲染进程暴露 IPC 功能:

const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
sendNotification: (options) => ipcRenderer.send('show-notification', options)
});

最后,你的 index.html 文件,其中包含一个按钮:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Electron Notifications</title>
</head>
<body>
<h1>Notifications Demo</h1>
<button id="notifyButton">Show Notification</button>
<script>
document.getElementById('notifyButton').addEventListener('click', () => {
window.electronAPI.sendNotification({
title: 'My Awesome App',
body: 'Hello from Electron! This is a notification.',
// icon: 'assets/icon.png' // Optional: relative path to an icon in your project
});
});
</script>
</body>
</html>

确保创建一个 assets 文件夹,并在其中放入 icon.png(如果你想使用图标的话),并相应调整路径。图标处理可能因平台而异。

运行你的应用程序(electron .)。当你点击“Show Notification”按钮时,应该会出现一个原生的系统通知。外观因操作系统而异:

  • 在 Windows 上,它通常是角落里的浮动通知(toast notification)。
  • 在 macOS 上,它出现在通知中心(Notification Center)。
  • 在 Linux 上,它取决于桌面环境的通知守护程序(notification daemon,例如 libnotify)。

Notification API 还支持操作(macOS 上的通知内部按钮)和回复。点击通知或关闭通知可以通过主进程中 Notification 对象的事件监听器('click'、'close'、'reply'、'action')来处理,从而实现交互式通知。