Android 科尔多瓦本地通知不';应用程序处于后台时无法工作

Android 科尔多瓦本地通知不';应用程序处于后台时无法工作,android,cordova,notifications,push-notification,cordova-plugins,Android,Cordova,Notifications,Push Notification,Cordova Plugins,我正在使用Cordova开发一个android应用程序,它使用PushPlugin从我的服务器接收推送通知 特别是,我正在使用 我也在使用,因为我希望应用程序在收到推送通知后立即显示本地通知 @Override protected void onMessage(Context context, Intent intent) { Log.d(TAG, "onMessage - context: " + context); // Extract the payload fr

我正在使用Cordova开发一个android应用程序,它使用PushPlugin从我的服务器接收推送通知

特别是,我正在使用

我也在使用,因为我希望应用程序在收到推送通知后立即显示本地通知

    @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) {
                createNotification(context, extras);
            }
        }
    }
}
下面的代码可以工作,并且只有当应用程序位于前台时才会显示本地通知

我希望本地通知即使在应用程序处于后台时也会出现。 可能吗?我怎样才能让它工作

提前谢谢

<!DOCTYPE HTML>
<html>
    <head>
        <title>com.PhoneGap.c2dm</title>
    </head>
    <body>

    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
    <script type="text/javascript" charset="utf-8" src="jquery_1.5.2.min.js"></script>
    <script type="text/javascript" src="PushNotification.js"></script>

    <script type="text/javascript">
        var pushNotification;

        function onDeviceReady() {
            $("#app-status-ul").append('<li>deviceready event received</li>');

                    document.addEventListener("backbutton", function(e){
                $("#app-status-ul").append('<li>backbutton event received</li>');

                    if( $("#home").length > 0){
                            // call this to get a new token each time. don't call it to reuse existing token.
                            //pushNotification.unregister(successHandler, errorHandler);
                            e.preventDefault();
                            navigator.app.exitApp();
                        }
                        else{
                            navigator.app.backHistory();
                        }
                    }, false);
                    try{ 
                    pushNotification = window.plugins.pushNotification;
                        $("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
                        if (device.platform == 'android' || device.platform == 'Android' || device.platform == 'amazon-fireos' ){
                                 pushNotification.register(successHandler, errorHandler, {"senderID":"527085141383","ecb":"onNotification"});   
                                  } else {
                             pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"});   // obbligatorio!
                        }
                    }
                    catch(err) { 
                        txt="There was an error on this page.\n\n"; 
                        txt+="Error description: " + err.message + "\n\n"; 
                        alert(txt); 
                    } 
        }   // fine onDeviceReady


        function onNotificationAPN(e) {
            if (e.alert) {
                 $("#app-status-ul").append('<li>push-notification: ' + e.alert + '</li>');
                 // showing an alert also requires the org.apache.cordova.dialogs plugin
                 navigator.notification.alert(e.alert);
            }

            if (e.sound) {
                // playing a sound also requires the org.apache.cordova.media plugin
                var snd = new Media(e.sound);
                snd.play();
            }

            if (e.badge) {
                pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);
            }
        }

        function onNotification(e) {
            $("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');

            switch( e.event ){
                case 'registered':
                            if ( e.regid.length > 0 )
                            {
                                $("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
                                // Your GCM push server needs to know the regID before it can push to this device
                                // here is where you might want to send it the regID for later use.
                                console.log("regID = " + e.regid);
                            }
                    break;

                case 'message':
                    // if this flag is set, this notification happened while we were in the foreground.
                    // you might want to play a sound to get the user's attention, throw up a dialog, etc.

                      var notificaOk = function(){
                        console.log("OK");
                      }
                      var notificaKo = function(){
                        console.log("KO");
                      }

                      window.plugin.notification.local.add({id: 1, title: "Product available", message: "Nexus 6 in stock", smallIcon: 'ic_dialog_email', icon: 'ic_launcher'}, notificaOk, notificaKo);

                    if (e.foreground){
                                   $("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');

                                  // on Android soundname is outside the payload. 
                                // On Amazon FireOS all custom attributes are contained within payload
                                var soundfile = e.soundname || e.payload.sound;
                                // if the notification contains a soundname, play it.
                                // playing a sound also requires the org.apache.cordova.media plugin
                                var my_media = new Media("/android_asset/www/"+ soundfile);

                                     my_media.play();

                              }
                              else{ // otherwise we were launched because the user touched a notification in the notification tray.

                                if (e.coldstart)
                                     $("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
                                else
                                   $("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
                            }

                            $("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
                              //android only
                            $("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
                              //amazon-fireos only
                              $("#app-status-ul").append('<li>MESSAGE -> TIMESTAMP: ' + e.payload.timeStamp + '</li>');

                      break;

                case 'error':
                            $("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
                          break;

                          default:
                            $("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
                          break;
                  }
        }

        function tokenHandler (result) {
            $("#app-status-ul").append('<li>token: '+ result +'</li>');
            // Your iOS push server needs to know the token before it can push to this device
            // here is where you might want to send it the token for later use.
        }

        function successHandler (result) {
            $("#app-status-ul").append('<li>success:'+ result +'</li>');
        }

        function errorHandler (error) {
            $("#app-status-ul").append('<li>error:'+ error +'</li>');
        }

             document.addEventListener('deviceready', onDeviceReady, true);

     </script>
    <div id="home">
        <div id="app-status-div">
            <ul id="app-status-ul">
                <li>Cordova PushNotification Plugin Demo</li>
            </ul>
        </div>
    </div>
</body>
</html>

我认为你还需要添加另一个插件,以便在后台模式下运行应用程序

请参考下面的链接,

另一个环节,,
我在使用PushPlugin和LocalNotification方面也有类似的经验

    @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) {
                createNotification(context, extras);
            }
        }
    }
}
就我而言,通知在后台工作,但android的smallicon是白色空白

我花了一整晚的时间检查LocalNotification插件的源代码,但结果证明这是PushPlugin本身的问题。(我会说,确切的问题是两个插件之间的断开连接)在PushPlugin的源代码中,它检查应用程序是在前台还是后台

如果应用程序在后台,通知事件不会触发cordova应用程序,但PushPlugin会创建自己的本地通知

    @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) {
                createNotification(context, extras);
            }
        }
    }
}
所以,如果您想在应用程序在后台运行时使用自定义的smallicon

我通过将初始代码重写为

    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(getResourceId(context, "pushicon", "drawable", context.getPackageName()))
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), getResourceId(context, "icon", "drawable", context.getPackageName())))
                .setWhen(System.currentTimeMillis())
                .setContentTitle(extras.getString("title"))
                .setTicker(extras.getString("title"))
                .setContentIntent(contentIntent)
                .setAutoCancel(true);

    String message = extras.getString("message");
    if (message != null) {
        mBuilder.setContentText(message);
    } else {
        mBuilder.setContentText("<missing message content>");
    }

    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());
}
public void createNotification(上下文上下文,Bundle extra)
{
NotificationManager mNotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION\u服务);
字符串appName=getAppName(此);
Intent notificationIntent=新的Intent(this,PushHandlerActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra(“推包”,extras);
PendingEvent contentIntent=PendingEvent.getActivity(this,0,notificationIntent,PendingEvent.FLAG_UPDATE_CURRENT);
int defaults=Notification.DEFAULT\u ALL;
if(extras.getString(“默认值”)!=null){
试一试{
默认值=Integer.parseInt(extras.getString(“默认值”);
}catch(numberformatexe){}
}
通知相容建筑商mBuilder=
新建NotificationCompat.Builder(上下文)
.setDefaults(默认值)
.setSmallIcon(getResourceId(上下文,“pushicon”,“drawable”,context.getPackageName())
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),getResourceId(context,“icon”,“drawable”,context.getPackageName()))
.setWhen(System.currentTimeMillis())
.setContentTitle(extras.getString(“标题”))
.setTicker(附加的getString(“标题”))
.setContentIntent(contentIntent)
.setAutoCancel(真);
字符串消息=extras.getString(“消息”);
如果(消息!=null){
mBuilder.setContentText(消息);
}否则{
mBuilder.setContentText(“”);
}
字符串msgcnt=extras.getString(“msgcnt”);
如果(msgcnt!=null){
mBuilder.setNumber(Integer.parseInt(msgcnt));
}
int notId=0;
试一试{
notId=Integer.parseInt(extras.getString(“notId”);
}
捕获(数字格式){
Log.e(标记,“数字格式异常-错误解析通知ID:+e.getMessage());
}
捕获(例外e){
Log.e(标记,“数字格式异常-错误解析通知ID”+e.getMessage());
}
mNotificationManager.notify((字符串)appName,notId,mBuilder.build());
}
现在,您只需将名为“pushicon”的图像放在drawable文件夹platforms/android/res/drawable/pushicon.png中 (我让它使用图像“图标”作为大图标)

如果有很多麻烦的话,我为此做了git回购

cordova插件添加


希望其他程序员不要经历我所经历的痛苦。

谢谢你的回答,我刚刚尝试了一个BackgroundService插件,但它是一样的;你不认为这是本地通知插件的问题吗?如果我正确理解了这段代码,PushPlugin只会在通知上有一个名为“message”的属性时向应用程序发送通知。如果通知没有说“message”,它在后台不会做任何事情,对吗?@nocompliance您是如何强迫Cordova用您的更改重新编译插件的?@DavidPrieto您必须先通过“Cordova plugin remove com.phonegap.plugins.PushPlugin”删除安装插件,然后“Cordova plugin add”就足够了。如果这不起作用,只需删除平台并从头开始构建即可。后一种方法始终有效:)