Cordova local notification does not work when the application is in the background

I am developing an Android application using Cordova and it uses PushPlugin to receive push notifications from my server.

In particular, I am doing some tests using the PushPlugin Example .

I also use the Cordoba Local Notification plugin because I want the application to show a local notification as soon as it receives a push notification.

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

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

early

<!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 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 JavaScript script node:

 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); } }); 
+1
source share
2 answers

I had a similar experience using PushPlugin and LocalNotification.

In my case, the notification worked in the background, but smallicon for android was white.

I spent the whole night checking the source of the LocalNotification plugin, but it turned out to be a problem with PushPlugin itself. (I will say that the problem is disabling the two plugins). In the source code of PushPlugin, it checks if the application is in the foreground or in the background.

If the application is in the background, the notification event does not fire into the cordova application, but PushPlugin creates its 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 customized malinon when the application works in reverse order.

I quickly hacked by replacing the source code with

  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 have to do is put the image named "pushicon" into the platform folder platforms for platforms /android/res/drawable/pushicon.png(I also used the image icon for the big icon)

If this is due to a lot of hassle, I made a git repository for this https://github.com/zxshinxz/PushPlugin.git

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

I hope that another programmer is not experiencing the pain that I experienced.

+2
source

I think you also need to add another plugin to run the application in the background,

refer to the link below, https://github.com/Red-Folder/Cordova-Plugin-BackgroundService

another link, How to run cordova plugin in android background?

0
source

All Articles