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.
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'
...
}
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.
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);
}
}
In the gcm configuration to send the message (server side ) you need to add the configuration:
'data' => 'sound' => "default",