3

I'm using the PushPlugin for cordova, and in android, I can't make the push notification play a sound while the app is not running or in background (the banner in status bar is presented ok). Here's the function that gets called on android push notifications-

function onNotification(e) {
    .
    .
    .
        case 'message':
        {    
            var myMedia = new Media("/android_asset/www/res/raw/tritone.mp3");
            myMedia.play({ numberOfLoops: 2 })

the sound plays fine while app is running in foreground.

This is the 'e' param value of the function "onNotification(e)" after a push is received while I'm in foreground (which does play the sound fine)-

{  
   "message":"body text...",
   "payload":{  
      "message":"body text...",
      "soundname":"/android_asset/www/res/raw/tritone.mp3",
      "title":"sometitle"
   },
   "collapse_key":"do_not_collapse",
   "from":"969601086761",
   "soundname":"/android_asset/www/res/raw/tritone.mp3",
   "foreground":true,
   "event":"message"
}

I have a feeling that the "function onNotification(e)" block is not called at all while the app is not running or in background.

In the end, what I want is very simple- to play a custom sound file on push notification while app is not running, or app is in background.

Thanks in advance.

Alon Amir
  • 4,913
  • 9
  • 47
  • 86

4 Answers4

4

I observed the java code added to the android platform project by the Cordova PushPlugin, looking at the file "GCMIntentService". in the 'onMessage' function, I saw this-

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

Then it became clear, see the line PushPlugin.sendExtras(extras)? this is the line that triggers the code on the javascript webview side. As you might have noticed, the problem is that this line is only called if the app isInForeground().

At first, I thought I should add this line also inside the else block, right below the line extras.putBoolean("foreground", false), but that would only help in a situation where the app is actually in background, it won't help if the app is not running at all.

for the reason above, I will simply play the audio file in Java code, like this (tested and working)-

if (PushPlugin.isInForeground()) {
    extras.putBoolean("foreground", true);
    PushPlugin.sendExtras(extras);
}
else {
    extras.putBoolean("foreground", false);

    MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.mytone);
    mediaPlayer.start();

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

It works, but it's not a perfect solution, I would have preferred to do the handling of notifications while in background or destroyed INSIDE THE JAVASCRIPT code in my webview, and not in Java. hopefully this functionality will be added to the PushPlugin.

Maybe at least they can add a parameter for "soundname" to be played in their call to createNotification(Context context, Bundle extras), which would also be a good enough solution for me using this plugin.

Clarification:

I used the following code to play the notification sound file name:

String soundName = extras.getString("soundname");               
AssetFileDescriptor afd = getAssets().openFd(soundName);
MediaPlayer player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
player.prepare();
player.start(); 

On the server side, I would pass a JSON looking like this when sending for Android (iOS has different keys):

{
  ...
  soundname: 'www/res/raw/yoursoundfile.mp3'
  ...
}
Alon Amir
  • 4,913
  • 9
  • 47
  • 86
  • Hi, how did you manage to make this work? And where did you put your custom sound? inside the www/ folder..? – user1027620 Feb 19 '15 at 18:35
  • @user1027620 I put the sound files in [www or app]/res/raw. I got this to work by changing the native part of the PushPlugin in Java code, as shown above. – Alon Amir Feb 21 '15 at 20:38
  • @AlonAmir.. How can i save the received notification payload in sqlite when the app is not running. – Subhendu Pratap Singh Feb 23 '15 at 21:33
  • @subhendupsingh, you don't need to do anything with sqlite to play push sound. however, if you have some reason to do so, I guess you could write your sqlite code in Java (only for cases when the app is not running). – Alon Amir Feb 24 '15 at 01:05
  • That's very well said, but in that case, how would i access the database created by cordova sqlite plugin? – Subhendu Pratap Singh Feb 24 '15 at 18:32
  • @subhendupsingh There's a Cordova plugin for it: https://github.com/brodysoft/Cordova-SQLitePlugin. But to access SQLite when the app is offline and triggered by a push, you would have to use the native APIs, lookup some Android SQLite tutorial online, anyhow it has not much to do with this Q&A entry. – Alon Amir Feb 24 '15 at 19:45
  • I know about SQLite Helper in native android and Cordova SQLite plugin and i have used it previously. But my question is , how would i access db created by cordova sqlite through native SQLite Helper as i don't know the location where this db is created. – Subhendu Pratap Singh Feb 24 '15 at 20:47
  • I tried your example but the cordova build is blowing up on the line for "AssetFileDescriptor" saying that it "cannot find symbol" for AssetFileDescriptor. Any ideas? I am working with the file platforms/android/source/com/plugin/gcm/GCMIntentService.java Thx – Matthew Goodwin Mar 16 '15 at 18:47
  • nevermind! I found this, which seems to resolve it once and for all: https://github.com/phonegap-build/PushPlugin/pull/421/files?diff=split – Matthew Goodwin Mar 16 '15 at 19:38
1

There is a Pull Request on the official repository that has never been merged but allows you to specify the mp3 file to play from the payload It works nice. The only disadvantage is that you have to put the mp3 file in the android/res/raw directory (you cannot put it in the www directory)

Have a look here https://github.com/phonegap-build/PushPlugin/pull/301

All you have to do is to send a payload with data.payload = {sound: 'myAlert', message:'blabla'} (note to remove the .mp3 extension in the payload) and put the myAlert.mp3 in the platform/android/res/raw directory in your cordova project.

alexislg
  • 1,018
  • 13
  • 20
0

just edit at the file "GCMIntentService". in the 'onMessage' function . call the method PushPlugin.sendExtras(extras) also in ' else '

Working code

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);
                PushPlugin.sendExtras(extras);

                // Send a notification if there is a message
                if (extras.getString("message") != null && extras.getString("message").length() != 0) {
                    createNotification(context, extras);
                }
            }
jiz
  • 308
  • 3
  • 7
  • This will not work if the app is neither in background or foreground, as I've mentioned in my answer: "At first, I thought I should add this line also inside the else block, right below the line extras.putBoolean("foreground", false), but that would only help in a situation where the app is actually in background, it won't help if the app is not running at all." – Alon Amir May 13 '15 at 07:55
0

In the gcm configuration to send the message (server side ) you need to add the configuration: 'data' => 'sound' => "default",

Fabien Thetis
  • 1,666
  • 15
  • 11