【问题标题】:Android notification setSound is not workingAndroid 通知 setSound 不起作用
【发布时间】:2018-08-05 19:29:33
【问题描述】:

在我的面向 API 23+ 的混合 Cordova Android 应用程序中,我想为通知使用自定义声音。为此,我做了以下工作

  • 在我在应用程序中使用的单个自定义插件的plugin.xml 文件中声明<resource-file src="src/android/res/unysound.mp3" target="res/raw/mysound.mp3" />'

将 APK 作为 zip 存档打开,我看到 mp3 文件实际上已在 `res/raw/mysound.mp3' 中结束。 - 在构建通知时,我会执行以下操作

    Notification notification = new Notification.Builder(context)
    .setDefaults(0) //turns off ALL defaults
    .setVibrate(vibrate)  /sets to vibrate
    ....
    .setSound(uri).build();

在哪里

Uri uri = Uri.parse("android.resource://" + ctxt.getPackageName() + "/raw/mysound.mp3");

这似乎是我在谷歌搜索时发现的许多文章中指出的配方,甚至在 SO 上的其他线程中也是如此。然而,当我发出通知时,我没有听到预期的声音。我可能做错了什么?


下面的答案没有帮助,因为在我的混合 Cordova 应用程序的上下文中,尝试构建 APK 的自定义插件会引发类似于 class R not known/found... 的错误

【问题讨论】:

    标签: android uri android-notifications android-6.0-marshmallow


    【解决方案1】:

    以下代码将为您提供帮助:

     String CHANNEL_ID="1234";
    
        Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ getApplicationContext().getPackageName() + "/" + R.raw.mysound);
        NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); 
        
      //For API 26+ you need to put some additional code like below:
        NotificationChannel mChannel;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    mChannel = new NotificationChannel(CHANNEL_ID, Utils.CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
                    mChannel.setLightColor(Color.GRAY);
                    mChannel.enableLights(true);
                    mChannel.setDescription(Utils.CHANNEL_SIREN_DESCRIPTION);
                    AudioAttributes audioAttributes = new AudioAttributes.Builder()
                            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                            .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                            .build();
                    mChannel.setSound(soundUri, audioAttributes);
        
                    if (mNotificationManager != null) {
                        mNotificationManager.createNotificationChannel( mChannel );
                    }
            }
    
       //General code:
         NotificationCompat.Builder status = new NotificationCompat.Builder(getApplicationContext(),CHANNEL_ID);     
                              status.setAutoCancel(true)
                                    .setWhen(System.currentTimeMillis())
                                    .setSmallIcon(R.drawable.logo)
                                    //.setOnlyAlertOnce(true)
                                    .setContentTitle(getString(R.string.app_name))
                                    .setContentText(messageBody)
                                    .setVibrate(new long[]{0, 500, 1000})
                                    .setDefaults(Notification.DEFAULT_LIGHTS )
                                    .setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE+ "://" +mContext.getPackageName()+"/"+R.raw.apple_ring))
                                    .setContentIntent(pendingIntent)
                                    .setContent(views);
                            
                            mNotificationManager.notify(major_id, status.build());
    

    mysound 是我的铃声,放在 res/raw 文件夹下。

    注意:您必须只输入铃声名称而无需扩展名,例如 raw/mysound

    注意:在 Android Oreo 中,您必须更改频道 ID 才能使更改生效。在 Oreo 版本之前,使用“.setDefaults()”会阻止自定义声音播放。

    【讨论】:

    • 我接受您的回答,因为它最接近于确定潜在问题 - 导致问题的扩展名 mp3。如果没有扩展,我的原始代码会提供所需的结果。请注意,在 Cordova 应用程序中,R.java 无法识别,因此您上面显示的内容并不真正适用。
    • 你为什么要给setDefaults打两次电话?
    • 我在AudioAttributes 中找不到CONTENT_TYPE_NOTIFICATION,所以我省略了它,解决方案仍然有效。
    • 在 Android Oreo 中,您必须更改您的频道 ID 才能使更改生效。在 Oreo 版本之前,使用“.setDefaults()”会阻止自定义声音播放。
    • 请在您的答案中添加@ThiagoYou 评论作为注释。它为我节省了很多时间。
    【解决方案2】:
    1. 尝试清除数据(或全新安装)
    2. 再试一次

    这些设置是在您首次创建频道时设置的,然后不会修改,除非您通过全新安装或清除数据手动进行。

    有关这方面的更多信息,请阅读此处的最佳答案: Android Oreo notification keep making Sound even if I do not set sound. On Older version, works perfectly

    【讨论】:

    • 我感到沮丧的是,无论我添加到 NotificationCompat.BuilderNotificationChannel 的任何声音或振动设置都没有什么区别,直到我清除了应用程序数据并且突然它起作用了。谢谢,你的回答拯救了我的一天。
    • 我花了几个小时试图弄清楚为什么没有任何改变,你拯救了我的一天,谢谢
    • 如何解决这个问题,我已将振动设置为用户偏好,因此基于该用户会更改,但它仅适用于全新安装
    【解决方案3】:

    对于 API 26+,您需要在通知通道上设置声音:

    Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ getApplicationContext().getPackageName() + "/" + R.raw.siren);
    NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel mChannel;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mChannel = new NotificationChannel(Utils.CHANNEL_SIREN_ID, Utils.CHANNEL_SIREN_NAME, NotificationManager.IMPORTANCE_HIGH);
                mChannel.setLightColor(Color.GRAY);
                mChannel.enableLights(true);
                mChannel.setDescription(Utils.CHANNEL_SIREN_DESCRIPTION);
                AudioAttributes audioAttributes = new AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                        .build();
                mChannel.setSound(soundUri, audioAttributes);
    
                if (mNotificationManager != null) {
                    mNotificationManager.createNotificationChannel( mChannel );
                }
        }
    
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, Utils.CHANNEL_SIREN_ID)
                .setSmallIcon(R.drawable.ic_stat_maps_local_library)
                .setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher))
                .setTicker(title)
                .setContentTitle(contentTitle)
                .setContentText(contentText)
                .setAutoCancel(true)
                .setLights(0xff0000ff, 300, 1000) // blue color
                .setWhen(System.currentTimeMillis())
                .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                mBuilder.setSound(soundUri);
        }
    
        int NOTIFICATION_ID = 1; // Causes to update the same notification over and over again.
        if (mNotificationManager != null) {
            mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
        }
    

    【讨论】:

    • mChannel.setSound(soundUri, audioAttributes); 使声音在 Oreo 中发挥作用
    • 谢谢,这不是很好,因为如果我们想要频道内不同通知的不同声音怎么办。
    【解决方案4】:

    您可以在处理通知时调用此方法

        public void playNotificationSound() {
        try {
            Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
                    + "://" + mContext.getPackageName() + "/raw/notification");
            Ringtone r = RingtoneManager.getRingtone(mContext, alarmSound);
            r.play();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    【讨论】:

    • 在这里投赞成票,因为我怀疑使用ContentResolver 而不是android.resource:// 是一种更面向未来的做事方式。
    • 您在这里所做的事情 - 通过 RingToneManager - 有效,但这是不正确的,不应该这样做,因为 Notification.Builder 有自己的 setSound 方法
    • 是的,Android 中有很多不应该做的事情,我在过去 4 年中学到了,不要假设任何事情都可以正常工作或在 Android 中已经为您完成,直到你亲眼所见...仅供参考
    • 唯一对我有用的方法。
    【解决方案5】:
     Notification.Builder builder = new Notification.Builder(context);
        builder.setContentTitle(mTitle);
        builder.setContentText(mContentText);
        builder.setSmallIcon(R.mipmap.ic_launcher);
    
        builder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
        builder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
        builder.setDefaults(Notification.DEFAULT_ALL);
    

    用它来处理声音,我希望它能解决你的问题,干杯!

    【讨论】:

      【解决方案6】:

      用它来设置声音

      Uri defaultSoundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + mContext.getPackageName() + "/raw/mysound");
      
      
      NotificationCompat.Builder mBuilder =
                      new NotificationCompat.Builder(mContext)
                              .setContentIntent(mainPIntent)
                              .setSmallIcon(R.mipmap.ic_launcher)
                              .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher))
                              .setContentTitle("" + title)
                              .setAutoCancel(true)
                              .setSound(defaultSoundUri)
                              .setContentText("" + body);
      
              NotificationManager mNotificationManager =
                      (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
              mNotificationManager.notify(title, NOTIFICATION_ID, mBuilder.build());
      

      【讨论】:

        【解决方案7】:

        您正在访问资源子文件夹中的声音

        将你的 uri 的来源更改为

        Uri uri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.siren);
        

        对于默认声音,使用:

        notification.defaults |= Notification.DEFAULT_SOUND;
        

        【讨论】:

        • 唯一的问题是当使用 R.raw.mysound.mp3 时我无法编译应用程序 - 错误 R cannot be resolved to a variable。请记住,我有一个带有自定义插件的 Cordova 项目。我将通知、setsound 等代码与相关声音资源一起放入该插件中
        【解决方案8】:

        我不确定,但我认为问题是你做错了"/raw/mysound.mp3

        Uri uri = Uri.parse("android.resource://" + ctxt.getPackageName() + "/raw/mysound.mp3");
        

        首先在清单中添加权限:uses-permission android:name="android.permission.VIBRATE" /&gt; 然后你可以设置默认声音:-

        Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        mBuilder.setSound(alarmSound);
        

        对于振动:

        mBuilder.setVibrate(new long[] { 1000, 1000});
        

        对于自定义声音,将 mp3 文件放在此路径:Res\raw\sound.mp3 然后

        Notification notification = builder.build();
         notification.sound = Uri.parse("android.resource://"
                + context.getPackageName() + "/" + R.raw.sound);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多