且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Ionic/Cordova 应用程序不会在后台收到推送通知

更新时间:2022-12-27 15:06:42

在 *** 中搜索所有涉及 Cordova/Phonegap Push Plugin 的问题后,我找到了问题的根源.插件的源代码里写的,应该不是.

After searching all questions in *** involving Cordova/Phonegap Push Plugin I found de source of the problem. Is written in the source code of the plugin, and it shouldn't.

问题是插件源代码要求推送通知具有消息"字段,以便在后台触发通知.它在 GCMIntentService.java 文件中指定.

The problem was that the plugin source code requires the push notification to have "message" field in order to trigger a notification while being on the background. It is especified in the GCMIntentService.java file.

if (extras.getString("message") != null && extras.getString("message").length() != 0) {
    createNotification(context, extras);
}

最有用的帖子是这个 answer 和这个 issue 在插件库中.因此,由于我无法控制推送服务器操作,因此无法在推送通知中指定消息"字段,因此我别无选择,只能重写源代码.

The most helpful posts are this answer and this issue in the plugin repository. So, because I have no power over the push server action I can't have specified a "message" field in the push notifications, I had no alternative but to rewrite the source code.

所以我重写了这样的代码:

So I rewrote te code like this:

@Override
protected void onMessage(Context context, Intent intent) {
    Log.d(TAG, "onMessage - context: " + context);

    // Extract the payload from the message
    Bundle extras = intent.getExtras();
    if (extras != null)
    {
        // if we are in the foreground, just surface the payload, else post it to the statusbar
        if (PushPlugin.isInForeground()) {
            extras.putBoolean("foreground", true);
            PushPlugin.sendExtras(extras);
        }
        else {
            extras.putBoolean("foreground", false);

            // Send a notification if there is a message
            //if (extras.getString("message") != null && extras.getString("message").length() != 0) {
            if (extras.getString("alert") != null && extras.getString("alert").length() != 0) {
                createNotification(context, extras);
            }
        }
    }
}

这样,如果插件收到带有警报"字段而不是消息"字段的推送通知,则会触发本地通知.

That way the plugin triggers a local notification if it receives a push notifications with the field "alert" instead of "message".

然后,我更改了本地通知本身的代码:

Then, I changed the code for the local notification itself:

public void createNotification(Context context, Bundle extras)
{
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        String appName = getAppName(this);

        Intent notificationIntent = new Intent(this, PushHandlerActivity.class);
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        notificationIntent.putExtra("pushBundle", extras);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        int defaults = Notification.DEFAULT_ALL;

        if (extras.getString("defaults") != null) {
            try {
                defaults = Integer.parseInt(extras.getString("defaults"));
            } catch (NumberFormatException e) {}
        }

        NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(context)
                .setDefaults(defaults)
                .setSmallIcon(context.getApplicationInfo().icon)
                .setWhen(System.currentTimeMillis())
                //.setContentTitle(extras.getString("title"))
                .setContentTitle(extras.getString("alert"))
                //.setTicker(extras.getString("title"))
                .setTicker(extras.getString("alert"))
                .setContentIntent(contentIntent)
                .setAutoCancel(true);
    /*
        String message = extras.getString("message");
        if (message != null) {
            mBuilder.setContentText(message);
        } else {
            mBuilder.setContentText("<missing message content>");
        }
    */
    // Agregado mensaje predefinido
    mBuilder.setContentText("Haz clic para más información");

        String msgcnt = extras.getString("msgcnt");
        if (msgcnt != null) {
            mBuilder.setNumber(Integer.parseInt(msgcnt));
        }

        int notId = 0;

        try {
            notId = Integer.parseInt(extras.getString("notId"));
        }
        catch(NumberFormatException e) {
            Log.e(TAG, "Number format exception - Error parsing Notification ID: " + e.getMessage());
        }
        catch(Exception e) {
            Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage());
        }

        mNotificationManager.notify((String) appName, notId, mBuilder.build());
    }

现在通知栏中的通知将首先显示警报"字段而不是标题",然后显示预定义的消息而不是我的推送通知中不存在的字段消息".

Now the notification in the notification bar will show first the field "alert" instead of "title" and second a predefined message instead of the field "message" that doesn't exist in my push notifications.

然后我只是重新编译代码:

Then I just recompile the code with:

ionic platform rm android

ionic platform add android

ionic run android

所以孩子们,这就是当你为每个人编写插件但不考虑通用情况并且没有很好地记录时会发生的情况.该插件仅对推送通知中包含消息"和标题"字段的人有用.

So kids, this is what happens when you write a plugin for everyone but you don't consider generic cases and you don't document well. That plugin is only useful for people with the field "message" and "title" in their push notifications.

我因此失去了两天的实习机会,我花时间写了这篇文章,这样其他人就不必了.

I lost two days of my internship because of this, I took my time to write this so others won't have to.