【问题标题】:Cordova PushPlugin: Android won't play push sound while app not runningCordova PushPlugin:Android 在应用程序未运行时不会播放推送声音
【发布时间】:2014-07-21 22:44:28
【问题描述】:

我将PushPlugin 用于cordova,在android 中,当应用程序未运行或在后台(状态栏中的横幅显示正常)时,我无法让推送通知播放声音。 这是在 android 推送通知上调用的函数-

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

应用在前台运行时声音播放正常。

这是我在前台收到推送后函数“onNotification(e)”的“e”参数值(确实可以正常播放声音)-

{  
   "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"
}

我感觉“function onNotification(e)”块在应用未运行或后台运行时根本没有被调用。

最后,我想要的非常简单——在应用未运行或应用处于后台时在推送通知上播放自定义声音文件。

提前致谢。

【问题讨论】:

    标签: android cordova push-notification google-cloud-messaging phonegap-pushplugin


    【解决方案1】:

    我观察了 Cordova PushPlugin 添加到 android 平台项目的 java 代码,查看文件“GCMIntentService”。在“onMessage”函数中,我看到了这个-

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

    然后就清楚了,看到PushPlugin.sendExtras(extras)这一行了吗?这是在 javascript webview 端触发代码的行。 您可能已经注意到,问题在于只有在应用程序 isInForeground() 时才会调用此行。

    起初,我想我应该在 else 块内添加这一行,就在 extras.putBoolean("foreground", false) 行的正下方,但这只会在应用程序实际上处于后台的情况下有所帮助,它不会有帮助如果应用程序根本没有运行。

    由于上述原因,我将简单地在 Java 代码中播放音频文件,就像这样(测试和工作)-

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

    它有效,但它不是一个完美的解决方案,我宁愿在后台处理通知或在我的 web 视图中销毁 INSIDE THE JAVASCRIPT 代码,而不是在 Java 中。希望这个功能会被添加到 PushPlugin 中。

    也许他们至少可以在调用createNotification(Context context, Bundle extras) 时为“soundname”添加一个参数,这对于我使用这个插件来说也是一个足够好的解决方案。

    澄清:

    我使用以下代码播放通知声音文件名:

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

    在服务器端,我会在发送 Android 时传递一个如下所示的 JSON(iOS 有不同的键):

    {
      ...
      soundname: 'www/res/raw/yoursoundfile.mp3'
      ...
    }
    

    【讨论】:

    • 嗨,你是怎么做到的?你把自定义声音放在哪里了?在 www/ 文件夹内..?
    • @user1027620 我将声音文件放在 [www 或 app]/res/raw 中。我通过在 Java 代码中更改 PushPlugin 的本机部分来实现这一点,如上所示。
    • @AlonAmir.. 当应用程序未运行时,如何将收到的通知有效负载保存在 sqlite 中。
    • @subhendupsingh,你不需要对 sqlite 做任何事情来播放推音。但是,如果您有某些理由这样做,我想您可以用 Java 编写您的 sqlite 代码(仅适用于应用程序未运行的情况)。
    • 说的很好,但是那样的话,怎么访问cordova s​​qlite插件创建的数据库呢?
    【解决方案2】:

    官方仓库上有一个Pull Request,它从未被合并,但允许你指定要从payload中播放的mp3文件 它工作得很好。唯一的缺点就是mp3文件必须放到android/res/raw目录下(不能放到www目录下)

    看这里 https://github.com/phonegap-build/PushPlugin/pull/301

    您所要做的就是发送一个有效载荷 data.payload = {sound: 'myAlert', message:'blabla'}(注意删除有效负载中的 .mp3 扩展名)并将 myAlert.mp3 放在您的 cordova 项目的 platform/android/res/raw 目录中。

    【讨论】:

      【解决方案3】:

      只需编辑文件“GCMIntentService”。在“onMessage”功能中。在'else'中也调用PushPlugin.sendExtras(extras)方法

      工作代码

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

      【讨论】:

      • 如果应用程序既不在后台也不在前台,这将不起作用,正如我在回答中提到的那样:“起初,我认为我应该将这一行也添加到 else 块中,就在下面行 extras.putBoolean("foreground", false),但这只会在应用程序实际上在后台运行的情况下有所帮助,如果应用程序根本没有运行,它将无济于事。"
      【解决方案4】:

      在发送消息的gcm配置中(服务器端)需要添加配置: '数据' => '声音' => "默认",

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-10
        • 1970-01-01
        • 1970-01-01
        • 2017-05-24
        • 2013-01-18
        • 1970-01-01
        相关资源
        最近更新 更多