📜  如何提高 Android 中的推送通知传递率?

📅  最后修改于: 2022-05-13 01:58:44.425000             🧑  作者: Mango

如何提高 Android 中的推送通知传递率?

通知是任何应用程序的重要组成部分。几乎您移动设备上的每个应用程序都会发送某种通知。 WhatsApp 通知就是最好的例子之一。每当您收到消息时,它都会以通知的形式显示在您的手机上。但是,许多开发人员发现很难向所有用户发送通知,导致只有少数用户收到通知。因此,我收到的最常见问题之一是“为什么有些用户没有收到推送通知?”简而言之,答案是:我们没有完全的控制权,但我们可以显着提高交付率。在本文中,我们将介绍一些提高通知传递率的方法。

究竟是什么问题?

在本文的这一部分,我们将讨论阻碍通知传递率的问题。首先,所有开发人员最常犯的错误是使用有关其应用用户的不正确数据。例如,如果您的应用有 500 名用户,那么这 500 名用户中有 20% 的用户可能已经卸载了您的应用。因此,您可能正在收集 500 个用户的数据,但您只向其中 100 个用户发送了通知(500 的 20% = 100)。因此,您必须做的第一件事就是确定确切的用户数量。只有 30% 的用户收到我们发送的通知,即 100 个中的 30 个。因此,我们无法向 70% 的客户发送通知。我们来看看原因:

30% 的情况下,它被归类为免打扰:因为有这么多应用程序以及来自这些应用程序的大量通知,30% 的用户将该特定应用程序置于免打扰模式,即免打扰模式。因此,在这种情况下,不会向用户显示该特定应用程序的通知。

  • 20% 的 OEM 限制:为了提高移动设备的性能,移动制造商创建了一个称为白名单应用程序的应用程序列表,例如 WhatsApp、Twitter、Gmail 等,并且允许来自这些应用程序的所有通知,因为很少或没有这些应用程序的服务被终止。但是,为了电池优化,那些不在白名单应用列表中的应用的服务经常被终止,导致您的用户没有收到通知。
  • FCM GooglePlayServices 不存在或断开连接:20% 所有通知都是在 FCM 的帮助下发送的。因此,在 20% 的情况下,此服务要么不存在,要么与您的用户设备断开连接。

通知系统的操作是什么?

一般来说,我们有两种选择来向我们的用户发送推送通知。直接从 Firebase 控制台的网站:在这种情况下,我们在 Firebase 控制台上注册我们的应用程序,然后接收唯一标识设备的注册令牌。现在,通知消息已使用 Firebase 控制台创建并发送到 FCM 后端。 FCM 后端接收消息并生成消息 ID 以及其他一些数据,然后使用注册令牌将消息发送给所需的用户,并在用户连接时接收消息。下图描述了整个过程

如何解决这些问题?

到目前为止,我们已经讨论了这些问题以及通知系统是如何工作的。让我们看看如何解决我们在本博客前面讨论的问题:

免打扰问题

对于 API 级别 19+,您可以编写代码来确定您的用户是否为您的应用禁用了通知。您可以使用以下代码:

NotificationManagerCompat.areNotificationsEnabled()

如果启用通知,上述方法将返回 true;否则,它将返回 false。如果 API 级别小于 19,它将始终返回 true。因此,如果用户阻止通知,您可以显示一条消息,说明来自您的应用程序的通知非常重要,因此请让它们保持更新。另一种选择是根据通知类型创建频道。现在,用户将只禁用他们不想要的应用中的通知类型,并且用户很有可能不会禁用来自所有渠道的所有通知。

OEM问题

您可以通过编程方式检查您的应用程序是否在设备的白名单中。如果不是,您可以请求用户将您的应用程序添加到白名单中。这可以通过包含以下权限来完成:

然后以这种方式编码以检查:

Java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    Intent intent = new Intent();
    String packageName = getPackageName();
    PowerManager pm
        = (PowerManager)getSystemService(POWER_SERVICE);
    if (!pm.isIgnoringBatteryOptimizations(packageName)) {
        intent.setAction(
            Settings
                .ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + packageName));
        startActivity(intent);
    }
}


OEM 还可以禁用这些服务以提高电池性能。在这种情况下,您可以直接从服务器检索通知。但是,这种方法不适用于即时通知;但是,对于其他通知,我们可以使用 WorkManager 从服务器检索通知并创建本地通知。如果上述方法不适用于您的用例,您可以在应用程序中创建一个单独的通知中心页面,并将所有通知仅保留在该位置。结果,用户可能会养成打开该页面以查看他们收到的所有通知的习惯。根据您的使用案例,您始终可以在用户打开应用程序、通知中心页面或 WorkManager 时从服务器获取最新的通知数据。现在,让我们谈谈从服务器检索通知数据时应该如何处理事情,尽管这也取决于您的用例。

  • 因此,基本上,您可以在服务器上创建一个表,该表将存储服务器发送到 Google 服务器以接收通知的所有信息,例如 FCM id 和通知数据。在这些数据旁边创建一个“状态”列来存储通知的状态,即是否显示(该字段将由客户端更新)。将采取以下步骤
  • 服务器将通过发送 FCM Id 和通知数据向 Google 服务器请求通知。同时,这些数据将保存在服务器创建的表中。
  • Google 服务器会将通知发送到所需的设备,但由于 OEM 限制,可能无法发送通知。因此,我们将聘请工作经理。
  • 我们将使用工作管理器从服务器批量检索通知。例如,如果我们有 20 个 id 从 1 到 20 的通知,我们可以将最近收到的通知 id 发送到服务器,服务器将返回接下来的 10 个通知。
  • 假设 Google Server 发送了 id 为 7 的通知。因此,我们不应再次显示此通知。
  • 每当我们从服务器拉通知或从 Google 服务器接收通知时,我们都会在客户端检查它是否显示在设备上。如果显示,我们将忽略该通知并且不会显示它。
  • 此外,某些通知仅在有限的时间内有效,例如来自送餐应用程序的餐厅优惠通知。在这种情况下,您可以将另一个字段添加到数据库表中,例如到期日期或时间。现在,每当 WorkManger 检索到该通知时,我们将检查它是否已过期。如果它已过期,我们将不会向用户显示它。
  • 可能存在您只想在特定时间显示通知的情况,例如在 Quiz App 中,您需要显示测验即将在晚上 8 点左右开始的通知。您必须仅在该时间显示通知,而不是之前或之后。要处理这些类型的情况,请在数据库表中添加一个新字段并将其命名为“显示时间”。
  • 在某些情况下,工作管理器也可能无法工作。因此,无论何时启动应用程序,您都可以从服务器检索通知。为了改进这种方法,您可以编写一些逻辑以仅在经过一定时间后才获取通知,而不是每次启动应用程序时。

FCM 问题

如果您的应用属于消息传递类别,您可以使用 WebSocket 在客户端(Android 应用)和服务器之间建立轻量级的持久连接,服务器将能够向客户端发送数据并根据该数据显示通知。如果您的应用程序不是消息应用程序,那么使用 WebSocket 不是一个好主意。因此,您可以使用前面讨论的方法,即工作管理器。