而应用程序是在后台科尔多瓦本地通知不起作用 [英] Cordova local notification doesn't work while app is in background

查看:282
本文介绍了而应用程序是在后台科尔多瓦本地通知不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发使用科尔多瓦的Andr​​oid应用程序,它使用PushPlugin从我的服务器接收推送通知。

在我特别使用 PushPlugin示例<正在做一些测试/ A>。

我还使用了科尔多瓦本地通知插件因为我想应用程序一旦显示了本地通知,因为它收到一个推送通知。

以下code ++工程和本地通知显示,但只有当应用程序在前台。

我要本地通知显示即使该应用程序是在后台。
可能吗?我怎样才能使它工作?

在此先感谢

 &LT;!DOCTYPE HTML&GT;
&LT; HTML和GT;
    &LT; HEAD&GT;
        &LT;标题&GT; com.PhoneGap.c2dm&LT; /标题&GT;
    &LT; /头&GT;
    &LT;身体GT;    &LT;脚本类型=文/ JavaScript的字符集=utf-8SRC =cordova.js&GT;&LT; / SCRIPT&GT;
    &LT;脚本类型=文/ JavaScript的字符集=utf-8SRC =jquery_1.5.2.min.js&GT;&LT; / SCRIPT&GT;
    &LT;脚本类型=文/ JavaScript的SRC =PushNotification.js&GT;&LT; / SCRIPT&GT;    &LT;脚本类型=文/ JavaScript的&GT;
        VAR pushNotification;        功能onDeviceReady(){
            $(#应用程序状态-UL)追加('&LT;立GT; deviceready事件接收到的LT; /李&GT;');                    document.addEventListener(后退按钮功能(E){
                $(#应用程序状态-UL)追加('&LT;立GT;后退按钮的事件接收到的LT; /李&GT;');                    如果($(#家)长度方式&gt; 0){
                            //调用这个每次得到一个新的令牌。不要把它重用现有的令牌。
                            //pushNotification.unregister(successHandler,的ErrorHandler);
                            亦即preventDefault();
                            navigator.app.exitApp();
                        }
                        其他{
                            navigator.app.backHistory();
                        }
                    },FALSE);
                    尝试{
                    pushNotification = window.plugins.pushNotification;
                        $(#应用程序状态-UL)追加('&LT;立GT;注册'+ device.platform +'&LT; /李&GT;');
                        如果(device.platform =='机器人'|| device.platform =='Android的'|| device.platform =='亚马逊fireos'){
                                 pushNotification.register(successHandler,的ErrorHandler,{senderID:527085141383,欧洲央行:onNotification});
                                  }其他{
                             pushNotification.register(tokenHandler,的ErrorHandler,{徽章:真正的,声音:真,警告:真,欧洲央行:onNotificationAPN}); // obbligatorio!
                        }
                    }
                    赶上(错误){
                        TXT =有此页面上的错误。\\ n \\ n;
                        TXT + =错误描述:+ err.message +\\ n \\ n;
                        警报(TXT);
                    }
        } //罚款onDeviceReady
        功能onNotificationAPN(五){
            如果(e.alert){
                 $(#应用程序状态-UL)追加('&LT;立GT;推通知:'+ e.alert +'&LT; /李&GT;');
                 //显示警报也需要org.apache.cordova.dialogs插件
                 navigator.notification.alert(e.alert);
            }            如果(e.sound){
                //播放声音也需要org.apache.cordova.media插件
                VAR SND =新媒体(e.sound);
                snd.play();
            }            如果(e.badge){
                pushNotification.setApplicationIconBadgeNumber(successHandler,e.badge);
            }
        }        功能onNotification(五){
            $(#应用程序状态-UL)追加('&LT;立GT;活动 - GT&; RECEIVED:'+ e.event +'&LT; /李&GT;');            开关(e.event){
                情况下注册:
                            如果(e.regid.length大于0)
                            {
                                $(#应用程序状态-UL)追加('&LT;立GT;注册 - &GT; REGID:'+ e.regid +&LT; /李&GT;);
                                //你的GCM推送服务器需要知道REGID,才可以推动这个装置
                                //这里是你可能想给它发送REGID供以后使用。
                                的console.log(REGID =+ e.regid);
                            }
                    打破;                案消息:
                    //如果设置此标志,这个通知发生,而我们是在前台。
                    //你可能想播放声音,以获得用户的关注,扔了一个对话框,等等。                      VAR notificaOk =功能(){
                        的console.log(OK);
                      }
                      VAR notificaKo =功能(){
                        的console.log(KO);
                      }                      window.plugin.notification.local.add({ID:1,标题:产品可用消息:Nexus 6的股票,smallIcon:ic_dialog_email,图标:ic_launcher'},notificaOk,notificaKo);                    如果(e.foreground){
                                   $(#应用程序状态-UL)追加('&LT;立GT; - INLINE NOTIFICATION--'+'&LT; /李&GT;');                                  //在Android soundname是有效载荷之外。
                                //在亚马逊FireOS所有自定义属性都包含有效载荷内
                                VAR音效档= e.soundname || e.payload.sound;
                                //如果通知包含soundname,播放。
                                //播放声音也需要org.apache.cordova.media插件
                                VAR my_media =新媒体(/ android_asset /网络/+音效档);                                     my_media.play();                              }
                              其他{//否则,我们推出了因为用户感动在通知栏中的通知。                                如果(e.coldstart)
                                     $(#应用程序状态-UL)追加('&LT;立GT; - COLDSTART NOTIFICATION--'+'&LT; /李&GT;');
                                其他
                                   $(#应用程序状态-UL)追加('&LT;立GT; - 背景NOTIFICATION--'+'&LT; /李&GT;');
                            }                            $(#应用程序状态-UL)追加('&LT;李&gt;消息 - &GT;味精:'+ e.payload.message +'&LT; /李&GT;');
                              只有//机器人
                            $(#应用程序状态-UL)追加('&LT;李&gt;消息 - &GT; MSGCNT:'+ e.payload.msgcnt +'&LT; /李&GT;');
                              只有//亚马逊fireos
                              $(#应用程序状态-UL)追加('&LT;李&gt;消息 - &GT; TIMESTAMP:'+ e.payload.timeStamp +'&LT; /李&GT;');                      打破;                案错误:
                            $(#应用程序状态-UL)追加('&LT;立GT;错误 - &GT;味精:'+ e.msg +'&LT; /李&GT;');
                          打破;                          默认:
                            $(#应用程序状态-UL)追加('&LT;李&GT;活动 - &GT;未知,收到一个事件,我们不知道它为&lt; /李&GT;');
                          打破;
                  }
        }        功能tokenHandler(结果){
            $(#应用程序状态-UL)追加('&LT;立GT;令牌:'+结果+'&LT; /李&GT;');
            //你的iOS推送服务器需要知道令牌才可以推动这个装置
            //这里是你可能想给它发送令牌以备后用。
        }        功能successHandler(结果){
            $(#应用程序状态-UL)追加('&LT;立GT;成功:'+结果+'&LT; /李&GT;');
        }        功能的ErrorHandler(错误){
            $(#应用程序状态-UL)追加('&LT;立GT;错误:'+误差+'&LT; /李&GT;');
        }             document.addEventListener(deviceready',onDeviceReady,真正的);     &LT; / SCRIPT&GT;
    &LT; D​​IV ID =家&GT;
        &LT; D​​IV ID =应用程序状态-DIV&GT;
            &LT; UL ID =应用程序状态-UL&GT;
                &LT;立GT;科尔多瓦PushNotification插件演示&LT; /李&GT;
            &LT; / UL&GT;
        &LT; / DIV&GT;
    &LT; / DIV&GT;
&LT; /身体GT;
&LT; / HTML&GT;

然后我发送推送通知到我的设备具有以下脚本的NodeJS:

  VAR GCM =要求('GCM')GCM。VAR apiKey =***;VAR GCM =新的GCM(apiKey);VAR devRegIdTarget =APA9 ......;VAR消息= {
    消息:短信息,
    registration_id:devRegIdTarget,
    标题:标题,
    msgcnt:'1',
    collapseKey:MSG1
    soundname:beep.wav
};message.timeToLive = 3000;
message.delayWhileIdle = TRUE;gcm.send(消息功能(呃,MESSAGEID){
    如果(ERR){
        的console.log(有些事情出了问题!);
    }其他{
        的console.log(已发送使用消息ID:邮件ID);
    }
});


解决方案

我在使用PushPlugin和LocalNotification类似的经历。

有关我的情况,通报工作的背景,但smallicon为Android是白色的空白。

我花了整个晚上检查LocalNotification插件的源代码,但原来它是与PushPlugin本身的问题。 (我会说,确切的问题是两个插件之间断开)在PushPlugin源$ C ​​$ C,它检查应用程序是否在前台或后台。

如果应用程序在后台运行,不会触发到科尔多瓦的应用程序通知事件,但PushPlugin创建本身它自己的本地通知。

  @覆盖
保护无效的onMessage(上下文的背景下,意图意图){
    Log.d(TAG的onMessage - 背景:+背景);    //从消息中提取有效载荷
    捆绑额外= intent.getExtras();
    如果(临时演员!= NULL)
    {
        //如果我们在前台,只是表面上的有效载荷,否则它发布到状态栏
        如果(PushPlugin.isInForeground()){
            extras.putBoolean(前台,真正的);
            PushPlugin.sendExtras(临时演员);
        }
        其他{
            extras.putBoolean(前台,FALSE);            //发送通知,如果有消息
            如果(extras.getString(消息)=空&放大器;!&放大器;!extras.getString(消息),长度()= 0){
                createNotification(背景下,临时演员);
            }
        }
    }
}

所以,如果你想在应用程序在运行的后面使用定制smallicon。

我通过重写初始code到

做了一个快速的黑客

 公共无效createNotification(上下文的背景下,捆绑演员)
{
    NotificationManager mNotificationManager =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    字符串的appName = getAppName(本);    意图notificationIntent =新意图(这一点,PushHandlerActivity.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    notificationIntent.putExtra(pushBundle,临时演员);    的PendingIntent contentIntent = PendingIntent.getActivity(这一点,0,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);    INT默认值= Notification.DEFAULT_ALL;    如果(extras.getString(违约)!= NULL){
        尝试{
            默认值=的Integer.parseInt(extras.getString(违约));
        }赶上(NumberFormatException的E){}
    }    NotificationCompat.Builder mBuilder =
            新NotificationCompat.Builder(上下文)
                .setDefaults(默认)
                .setSmallIcon(getResourceId(上下文中,pushicon,可拉伸,context.getPackageName()))
                .setLargeIcon(BitmapFactory.de codeResource(context.getResources(),getResourceId(背景下,图标,绘制,context.getPackageName())))
                .setWhen(System.currentTimeMillis的())
                .setContentTitle(extras.getString(标题))
                .setTicker(extras.getString(标题))
                .setContentIntent(co​​ntentIntent)
                .setAutoCancel(真);    字符串消息= extras.getString(信息);
    如果(消息!= NULL){
        mBuilder.setContentText(消息);
    }其他{
        mBuilder.setContentText(&LT;丢失邮件内容和GT;);
    }    串msgcnt = extras.getString(msgcnt);
    如果(msgcnt!= NULL){
        mBuilder.setNumber(的Integer.parseInt(msgcnt));
    }    INT notId = 0;    尝试{
        notId =的Integer.parseInt(extras.getString(notId));
    }
    赶上(NumberFormatException的E){
        Log.e(TAG,数字格式异常 - 错误解析通知ID:+ e.getMessage());
    }
    赶上(例外五){
        Log.e(TAG,数字格式异常 - 错误解析通知ID+ e.getMessage());
    }    mNotificationManager.notify((字符串)的appName,notId,mBuilder.build());
}

命名的文件夹绘制平台pushicon现在,所有你需要做的就是把图像/安卓/ RES /绘制/ pushicon.png
(我把它用图片图标大图标以及)

如果是到太多的麻烦,我做了一个混帐回购本
https://github.com/zxshinxz/PushPlugin.git

科尔多瓦插件添加 https://github.com/zxshinxz/PushPlugin.git

希望其他程序员不通过我所经历的痛苦去了。

I'm developing an android application using Cordova and it uses PushPlugin to receive push notifications from my server.

In particular, I'm doing some test using the PushPlugin Example.

I'm also using the Cordova Local Notification plugin because I want the app shows a local notification as soon as it receives a push notification.

The following code works and the local notification appears but only when the app is in the foreground.

I want the local notification appear even when the app is in the background. Is it possible? How can I make it work?

thanks in advance

<!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>

then I send a push notification to my device with the following nodeJS script:

var GCM = require('gcm').GCM;

var apiKey = "***";

var gcm = new GCM(apiKey);

var devRegIdTarget = "APA9....";

var message = {
    message: "Text msg",
    registration_id : devRegIdTarget, 
    title : 'Title',
    msgcnt : '1',
    collapseKey : "msg1",
    soundname : 'beep.wav'
};

message.timeToLive = 3000;
message.delayWhileIdle = true;

gcm.send(message, function(err, messageId){
    if (err) {
        console.log("Something has gone wrong!");
    } else {
        console.log("Sent with message ID: ", messageId);
    }
});

解决方案

I had similar experience in using PushPlugin and LocalNotification.

For my case, notification worked on the background but smallicon for the android were white blank.

I spent whole night inspecting source of LocalNotification plugin but it turned out it was problem with PushPlugin itself. (I will say, the exact problem is disconnection between two plugins) In the source code of PushPlugin, It checks whether application is in foreground or background.

If application is in the background, notification event is not triggered to the cordova app but PushPlugin creates itself it's own local notification.

    @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);
            }
        }
    }
}

So, if you want to use customised smallicon when application is running in the back.

I did a quick hack by overriding initial code to

    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());
}

now, all you need to do is put image named "pushicon" in drawable folder platforms/android/res/drawable/pushicon.png (I made it use image "icon" for large icon as well)

if it's to much of hassle, I made a git repo for this https://github.com/zxshinxz/PushPlugin.git

cordova plugin add https://github.com/zxshinxz/PushPlugin.git

hope other programmer don't go through the pain I went through.

这篇关于而应用程序是在后台科尔多瓦本地通知不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆