本地/推送通知

本指南讨论如何实现本地推送通知。

概述

Solar2D 支持两种类型的通知:本地推送。两种通知类型的目的都是为了在应用程序不在前台运行时通知用户某些事情——例如,消息或即将到来的约会。本地通知和推送通知之间的本质区别很简单:

通知仅在 iOS 和 Android 上受支持,macOS 桌面、Windows 桌面、Apple TV 或 Android TV 上不受支持

使用说明

要使用推送通知,请记住以下几点:

应用交互

应用程序如何响应通知取决于其状态:

项目设置

要使用 通知 插件,请在 `build.settings` 的 `plugins` 表中添加一个条目。添加后,构建服务器将在构建阶段集成该插件。

settings =
{
    plugins =
    {
        ["plugin.notifications.v2"] =
        {
            publisherId = "com.coronalabs"
        },
    },
}

在此 `build.settings` 文件中,还要包含 `minSdkVersion` 16 或更高版本。有关设置最低 SDK 版本的更多信息,请参阅此处

settings =
{
    android =
    {
        minSdkVersion = "16",
    },
}

然后,在使用通知函数的代码模块中,只需按如下方式 `require()` 该库:

local notifications = require( "plugin.notifications.v2" )
重要
  • 对于 Android,所有应用或首次使用推送通知更新的现有应用都必须使用 Firebase 云消息传递 (FCM),当前的 通知 插件(上方)支持该功能。如果您有一个已为 Google 云消息传递 (GCM) 配置的旧版应用,它将继续无限期地工作,但您应继续使用 旧版 插件,而不是当前的通知插件。

  • 对于 iOS,您可以使用 Apple 推送通知服务 (APNS) 或 Firebase 云消息传递 (FCM) 进行推送通知(请参阅下文)。

iOS 设置

推送通知的大部分 iOS 配置都在 Apple Developer 门户网站中完成。此外,您必须在 `config.lua` 的`notification` → `iphone` → `types`表中指定您的应用程序将使用哪些类型的通知。

application =
{
    notification =
    {
        iphone = 
        {
            types = 
            {
                "badge",
                "sound",
                "alert"
            },
        },
    },
}

Firebase

如果您想使用 Google Firebase 云消息传递 (FCM) 进行推送通知,请按照以下附加步骤操作:

  1. 将 Firebase 控制台中提供的 `GoogleService-Info.plist` 复制到与 `main.lua` 并列的项目根目录中。

  2. 将以下条目添加到 `build.settings` 的`iphone` → `plist`表中。

settings =
{
    iphone =
    {
        plist =
        {
            UIBackgroundModes = { "remote-notification" },
            FirebaseAppDelegateProxyEnabled = false,
        },
    },
}

Android 设置

Android 也需要对推送通知进行一些额外的配置:

  1. 将 Firebase 控制台中提供的 `google-services.json` 复制到与 `main.lua` 并列的项目根目录中。

  2. 在 `build.settings` 的 `android` 表中添加一个额外的 `useGoogleServicesJson` 条目。添加后,构建服务器将从 JSON 文件中读取设置,并在构建阶段将它们集成到您的应用程序中。

settings =
{
    android =
    {
        useGoogleServicesJson = true,
    },
}

Android 图标

您可以通过将以下文件添加到项目目录的根目录(就像自定义应用程序图标一样)来设置项目中的自定义通知图标。有关更多详细信息,请参阅 Google 的官方文档

文件 大小 (宽×高)
IconNotificationDefault-ldpi.png 18 × 18
IconNotificationDefault-mdpi.png 24 × 24
IconNotificationDefault-hdpi.png 36 × 36
IconNotificationDefault-xhdpi.png 48 × 48
IconNotificationDefault-xxhdpi.png 72 × 72
IconNotificationDefault-xxxhdpi.png 96 × 96

安排本地通知

要安排本地通知,请使用 notifications.scheduleNotification() 函数,并使用以下两种格式之一指定未来事件的时间

  1. 从调用时间算起应传送通知的秒数。

  2. 以协调世界时 (UTC) 指定的时间。这应该是 `os.date("!*t")` 返回的时间表。请注意,一个常见的错误是忘记感叹号并传递 `"*t"` 而不是 `"!*t"`——这将以本地时间(您的时区)而不是 UTC 返回时间结构。

您还应传递一个包含以下任何参数的 `options` 表:

要在本地通知触发之前取消它,请使用 notifications.cancelNotification() 函数并传递 notifications.scheduleNotification() 返回的 ID。

处理通知事件

根据 Solar2D 事件/侦听器模型,如果您的应用程序在前台或后台运行并且收到通知,您将收到一个 notification 事件。您有责任初始化系统并设置侦听器函数来处理这些事件。请查看以下框架,然后阅读下面的详细小节。

local function notificationListener( event )

    if ( event.type == "remote" ) then
        -- Handle the push notification

    elseif ( event.type == "local" ) then
        -- Handle the local notification

    end
end

Runtime:addEventListener( "notification", notificationListener )

通知数据

notification 事件返回一个信息表,您可以使用它来管理特定通知。此表包括以下内容:

启动参数

当操作系统由于传入通知而从非活动(未运行)状态启动您的应用程序时,应用程序会将数据作为 `launchArgs` 的一部分接收,而不是触发通知事件。您可以使用 `notificationListener` 函数来处理启动参数。

local launchArgs = ...

if ( launchArgs and launchArgs.notification ) then
    notificationListener( launchArgs.notification )
end
重要

此 `launchArgs` 处理必须在 `main.lua` 中,因为它是接收数据的代码。

通知徽章 (iOS)

iOS 上的通知徽章很容易通过覆盖在应用程序图标上的小圆圈/数字来识别。如果通知传递了 `badge` 值,则等于该值的徽章将出现在应用程序图标上。

您有责任读取并根据其先前值设置徽章编号。这可以通过 native.getProperty()native.setProperty() 函数来完成。几乎在所有情况下,当用户打开/处理通知时,您应该将徽章编号减 1,如下所示

-- Decrement the badge number by 1
local function notificationListener( event )

    if ( event.type == "local" ) then
        -- Handle the local notification
        local badgeNum = native.getProperty( "applicationIconBadgeNumber" )
        if ( badgeNum > 0 ) then
            badgeNum = badgeNum - 1
            native.setProperty( "applicationIconBadgeNumber", badgeNum )
        end

    elseif ( event.type == "remote" ) then
        -- Handle the push notification
        if ( event.badge and event.badge > 0 ) then
            native.setProperty( "applicationIconBadgeNumber", event.badge - 1 )
        end
    end
end

或者,您可以完全清除徽章

native.setProperty( "applicationIconBadgeNumber", 0 )

通知声音

默认情况下,设备会在收到通知时播放声音。您可以在项目中指定自定义声音文件来代替默认声音。例如,如果您的应用程序包中包含文件 notification.wav,您可以将字符串 "notification.wav" 指定为推送包的一部分(如果发送服务支持的话),操作系统将播放该自定义声音而不是默认声音。在这种情况下,事件侦听器中的 event.sound 条目将等于此字符串。

远程注册 (iOS)

在 iOS 上,当您准备好请求用户允许推送通知的权限时,您应该调用 notifications.registerForPushNotifications()。这将显示一个弹出窗口,询问用户是否要启用推送通知。建议您仅在需要时才请求此权限,而不是在应用程序启动时。

重要

如果您正在使用 Google Firebase 云消息传递 (FCM) 进行推送通知,则应向 notifications.registerForPushNotifications() 传递一个附加参数。此参数应该是一个包含 useFCM 键且值为 true

notifications.registerForPushNotifications( { useFCM=true } )

调用 notifications.registerForPushNotifications() 将触发向您的通知侦听器函数发送远程注册事件。为了适应这种情况,添加一个附加条件

local function notificationListener( event )

    if ( event.type == "remote" ) then
        -- Handle the push notification

    elseif ( event.type == "remoteRegistration" ) then
        -- Code to register your device with the service

    elseif ( event.type == "local" ) then
        -- Handle the local notification

    end
end

注册设备所需的代码因服务而异。请查阅您首选提供商的文档,或在 论坛Discord 中寻求帮助。