使用 Mixpanel 为 Android 自定义通知图标

Customising Notification icon for Android, using Mixpanel

使用 Mixpanel 我可以直接从他们的控制面板发送通知,但是目前它使用一个奇怪的裁剪版本的启动器图标作为通知图标。

我看到了一些使用自定义 BroadcastReceiver 自定义图标的答案,但我似乎无法在这种情况下使用它。直接从 Mixpanel 发送时,有人成功地更改了通知图标吗?

谢谢。

实际上,有一种方法可以为 android 推送通知设置自定义图标,而无需编写您自己的自定义广播接收器。 Mixpanel android 库的最新版本理解一个 "mp_icnm" 参数,该参数可以引用应用程序中资源的名称。该库本身还打包了一组您可以使用的预定义图标。快速的方法是将以下代码片段放入 "custom data" 字段

{"mp_icnm":"com_mixpanel_android_ic_megaphone"}

我附上了 Mixpanel 应用程序的屏幕截图和文本字段的图片。当您输入数据时,您需要确保此数据是在 "Android" 预览模式下输入的,如图所示。

您可以在您的应用程序中使用任何可绘制资源作为图标 - 可以在 Mixpanel 库中找到预打包通知图标的完整列表,它们的资源名称列在下面。

  • com_mixpanel_android_ic_bell
  • com_mixpanel_android_ic_clipboard_checkmark
  • com_mixpanel_android_ic_coin
  • com_mixpanel_android_ic_flag
  • com_mixpanel_android_ic_gear
  • com_mixpanel_android_ic_inbox
  • com_mixpanel_android_ic_megaphone
  • com_mixpanel_android_ic_phone
  • com_mixpanel_android_ic_rocket
  • com_mixpanel_android_ic_sale_tag
  • com_mixpanel_android_ic_sync
  • com_mixpanel_android_ic_trophy
  • com_mixpanel_android_ic_vip
  • com_mixpanel_android_ic_warning

请注意,Mixpanel 资源可能会被混淆器配置删除,因此如果您想使用它们,请确保您没有剥离它们。

另外可以添加小图标会显示在状态栏中

"mp_icnm_w": "your_small_icon_id"

应该是白色透明背景。

要回答@user1544797 问题的一个方面,除了@user128536 的回答之外,您可能希望让您的应用负责配置您的通知图标,而不是依赖于 Mixpanel 预览模式。为此,您必须通过创建自己的 BroadcastReceiver 来拦截 Mixpanel 广播,该 BroadcastReceiver 扩展了 Mixpanel 的 GCMReceiver :

public class MixpanelGCMReceiver extends GCMReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        intent.putExtra("mp_icnm", "<your_icon_name>");
        super.onReceive(context, intent);
    }

}

然后在 AndroidManifest.xml 文件中声明 BroadcastReceiver :

<receiver
  android:name="<your_package_name>.MixpanelGCMReceiver"
  android:permission="com.google.android.c2dm.permission.SEND">
  <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

    <category android:name="${applicationId}" />
  </intent-filter>
</receiver>

最后,@user128536 警告你如果管理不当,Proguard 会弄乱你的通知图标,这是正确的(不幸的是,Mixpanel 没有记录你的应用程序应该如何处理这种情况)。但是,除了 Proguard 之外,当您使用与您的 packageName 不同的 applicationId(通常同时使用产品口味)。在 Mixpanel SDK 的 ResourceReader class 中,你可以看到这个评论:

MPLog.w(LOGTAG, "Can't load names for Android view ids from '" + localClassName + "', ids by name will not be available in the events editor.");
MPLog.i(LOGTAG, "You may be missing a Resources class for your package due to your proguard configuration, " +
                "or you may be using an applicationId in your build that isn't the same as the package declared in your AndroidManifest.xml file.\n" +
                "If you're using proguard, you can fix this issue by adding the following to your proguard configuration:\n\n" +
                "-keep class **.R$* {\n" +
                "    <fields>;\n" +
                "}\n\n" +
                "If you're not using proguard, or if your proguard configuration already contains the directive above, " +
                "you can add the following to your AndroidManifest.xml file to explicitly point the Mixpanel library to " +
                "the appropriate library for your resources class:\n\n" +
                "<meta-data android:name=\"com.mixpanel.android.MPConfig.ResourcePackageName\" android:value=\"YOUR_PACKAGE_NAME\" />\n\n" +
                "where YOUR_PACKAGE_NAME is the same string you use for the \"package\" attribute in your <manifest> tag."
);

如以上评论所述,如果您发现自己处于这种情况,只需在 AndroidManifest.xml 文件中添加以下块:

<meta-data
  android:name="com.mixpanel.android.MPConfig.ResourcePackageName"
  android:value="<your_package_name>" />

就是这样,你现在应该完成了 ;)

我将这个答案提供给所有即使阅读了所有以前的答案也无法找到完美解决方案的人。当您收到 Mixpanel 推送时,我将总结显示应用程序图标所需的所有关键点。

  1. 如果您正在使用 ProGuard(在我的情况下),您需要在 Proguard 规则 中进行以下设置文件。

keepclassmembers class **.R$* {
    public static <fields>;
}

  1. 在您的 Manifest.xml 文件中添加以下代码。

<meta-data
    android:name="com.mixpanel.android.MPConfig.ResourcePackageName"
    android:value="YOUR_PACKAGE_NAME" /> 

这是在您的应用程序的清单文件中声明的包名称 (package="YOUR_PACKAGE_NAME")(例如 YOUR_PACKAGE_NAME。将其替换为您的实际包名称值)。不要将它与应用程序 ID 混淆。如果您将 Application Id 放在这里,它将不起作用。

第 1 点和第 2 点也在 ResourceReader class 中提到,如上述答案之一所述。

MPLog.w(LOGTAG, "Can't load names for Android view ids from '" + localClassName + "', ids by name will not be available in the events editor.");
MPLog.i(LOGTAG, "You may be missing a Resources class for your package due to your proguard configuration, " +
                "or you may be using an applicationId in your build that isn't the same as the package declared in your AndroidManifest.xml file.\n" +
                "If you're using proguard, you can fix this issue by adding the following to your proguard configuration:\n\n" +
                "-keep class **.R$* {\n" +
                "    <fields>;\n" +
                "}\n\n" +
                "If you're not using proguard, or if your proguard configuration already contains the directive above, " +
                "you can add the following to your AndroidManifest.xml file to explicitly point the Mixpanel library to " +
                "the appropriate library for your resources class:\n\n" +
                "<meta-data android:name=\"com.mixpanel.android.MPConfig.ResourcePackageName\" android:value=\"YOUR_PACKAGE_NAME\" />\n\n" +
                "where YOUR_PACKAGE_NAME is the same string you use for the \"package\" attribute in your <manifest> tag."
);

  1. 如果您已经在使用 FCMPushReceiver 并且想要集成 Mixpanel 通知支持,请遵循提到的指南 here

无论您使用的是 MixpanelFCMMessagingService 还是 FirebaseMessagingService,您都需要将以下代码放入 onMessageReceived() 部分。

/* drawable_name is just the Drawable Name like if you app logo is app_icon, 
   use "app_icon" instead of "R.drawable.app_icon" */
if (TextUtils.isEmpty(intent.getStringExtra("mp_icnm"))) {
    intent.putExtra("mp_icnm", "drawable_name"); // mp_icnm is used for the app icon
}
if (TextUtils.isEmpty(intent.getStringExtra("mp_icnm_l"))) {
    intent.putExtra("mp_icnm_l", "drawable_name"); // mp_icnm_l is used for the large icon
}
if (TextUtils.isEmpty(intent.getStringExtra("mp_icnm_w"))) {
    intent.putExtra("mp_icnm_w", "drawable_name"); // mp_icnm_w is used for the White icon
} 

有关Mixpanel使用的参数的更多信息,您可以查看MixpanelPushNotificationclass的parseIntent方法。

MixpanelFCMMessagingService的情况下,您可以在方法参数中获取意图。对于 FirebaseMessagingService,您可以通过如下方式获得意图 -

final Intent intent = remoteMessage.toIntent();