如何播放Android通知声音


169

我想知道如何在不通过媒体流播放通知声音的情况下播放通知声音。现在,我可以通过媒体播放器执行此操作,但是我不希望它作为媒体文件播放,我希望它作为通知或警报或铃声播放。这是我的代码现在看起来像的一个示例:

MediaPlayer mp = new MediaPlayer();
mp.reset();
mp.setDataSource(notificationsPath+ (String) apptSounds.getSelectedItem());
mp.prepare();
mp.start();

Answers:


421

如果有人仍在寻找解决方案,我在如何在Android中播放铃声/闹钟声音中找到了答案

try {
    Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
    r.play();
} catch (Exception e) {
    e.printStackTrace();
}

您可以将TYPE_NOTIFICATION更改为TYPE_ALARM,但是您希望跟踪自己的Ringring r以便停止播放……例如,当用户单击按钮或其他东西时。


2
例如,摩托罗拉电话扩展了首选项活动,并允许用户为短信和其他类别定义通知声音。上述方法不适用于此类手机。您知道如何解决此问题吗?
大卫,

2
我对此有误:MediaPlayer - Should have subtitle controller already set。这是什么意思?
德清2014年

使用此解决方案,在28/29次之后,声音停止播放。有人知道为什么吗?
汤姆·布林克坎伯

1
你为什么要抓住每一个例外?可能抛出哪一个?
Miha_x64

2
@山姆,是的。stackoverflow.com/q/39876885/2614353。基本上,不要在每次播放时都创建RingTone对象。创建一次,然后多次播放同一对象。
汤姆·布林克坎普

205

现在,您可以通过在构建通知时包括声音来实现此目的,而不必分别调用声音。

//Define Notification Manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

//Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext())
        .setSmallIcon(icon)
        .setContentTitle(title)
        .setContentText(message)
        .setSound(soundUri); //This sets the sound to play

//Display notification
notificationManager.notify(0, mBuilder.build());

12
这就解决了一个不同的问题-不是“如何播放通知声音”,而是“如何播放通知显示声音”。接受的答案在其解决方案中是合理的。
Fabian Tamp 2014年

7
也许您还应该将其设置为通过STREAM_NOTIFICATION播放,以便以OS当前通知音量首选项播放:.setSound(soundUri,AudioManager.STREAM_NOTIFICATION)
mwk 2014年

@Rob Riddle工作正常。但是如果有多个通知,例如100个通知并行,则声音会与下一个通知声音混合。从逻辑上讲,如果已经在播放声音,则应等待上一次播放的完成。在这种情况下,您能帮忙吗?
Waqas Ali Razzaq'17年

应用程序在后台运行时不播放声音。有什么建议吗?
Sagar Nayak

47

如果要播放默认的通知声音,则可以使用此类的setDefaults(int)方法NotificationCompat.Builder

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(someText)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setAutoCancel(true);

我相信这是完成任务的最简单方法。


应用程序在后台运行时不播放声音。有什么建议吗?
Sagar Nayak

13

试试这个:

public void ringtone(){
    try {
        Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
        r.play();
     } catch (Exception e) {
         e.printStackTrace();
     }
}

9

提问以来已有一段时间,但是...您是否尝试过设置音频流类型?

mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);

必须在准备之前完成。


2

我几乎有同样的问题。经过研究,我认为如果要播放默认的系统“通知声音”,则几乎必须显示一个通知,并告诉它使用默认声音。在其他一些答案中,还有一些要说的论点是,如果您正在播放通知声音,则还应该显示一些通知消息。

但是,对通知API进行一些调整,即可接近所需的内容。您可以显示空白通知,然后在几秒钟后自动将其删除。我认为这对我有用;也许它将为您工作。

我创建了一组便捷的方法,在com.globalmentor.android.app.Notifications.java这些方法中,您可以创建这样的通知声音:

Notifications.notify(this);

LED也会闪烁,如果您允许振动,将会发生振动。是的,通知图标将出现在通知栏中,但会在几秒钟后消失。

此时,您可能会意识到,由于无论如何该通知都会消失,因此您可能还会在通知栏中看到滚动条消息。您可以这样做:

Notifications.notify(this, 5000, "This text will go away after five seconds.");

此类中还有许多其他便利方法。您可以从其Subversion存储库下载整个库,并使用Maven进行构建。它取决于globalmentor-core库,该库也可以使用Maven构建和安装。


简单地播放声音就变得很复杂。您可以这样做:stackoverflow.com/a/9622040/1417267
slinden77 2012年


1

我认为“通知声音”的概念对于Android UI来说是错误的。

Android的预期行为是使用标准通知来提醒用户。如果您播放的通知声音中没有状态栏图标,则会使用户感到困惑(“那是什么声音?这里没有图标,也许我有听力障碍?”)。

如何在通知上设置声音,例如,在这里:设置通知的声音


1
并非如此,这可能是应用内通知。例如,如果您在聊天应用程序中,并且对传入和传出消息的声音效果很小。这些本质上是通知,您希望它们在电话处于静音模式时关闭。
copolii 2011年

好吧,你是对的,但这是另一回事。我在说“系统通知声音”(假设这是问题的话题),即在系统Android GUI上。当然,当您进入自己的应用程序时,一切由您自己决定。
think01 2011年

1
Intent intent = new Intent(this, MembersLocation.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("type",type);
    intent.putExtra("sender",sender);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = getString(R.string.default_notification_channel_id);

    Uri Emergency_sound_uri=Uri.parse("android.resource://"+getPackageName()+"/raw/emergency_sound");
   // Uri Default_Sound_uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    if(type.equals("emergency"))
    {
        playSound=Emergency_sound_uri;
    }
    else
    {
        playSound= Settings.System.DEFAULT_NOTIFICATION_URI;
    }

    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(R.drawable.ic_notification)
                    .setContentTitle(title)
                    .setContentText(body)
                    .setSound(playSound, AudioManager.STREAM_NOTIFICATION)
                    .setAutoCancel(true)
                    .setColor(getColor(R.color.dark_red))
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setContentIntent(pendingIntent);

   // notificationBuilder.setOngoing(true);//for Android notification swipe delete disabling...

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // Since android Oreo notification channel is needed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(channelId,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_HIGH);
        AudioAttributes att = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                .build();
        channel.setSound(Emergency_sound_uri, att);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(channel);
        }
    }

    if (notificationManager != null) {
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}

1
感谢您提供此代码段,它可能会提供一些有限的即时帮助。通过说明为什么这是一个很好的解决方案,正确的解释将大大提高其长期价值,对于其他有类似问题的读者来说,这样做将更为有用。请编辑您的答案以添加一些解释,包括您所做的假设。
NOhs '18

0

将声音设置为通知频道

        Uri alarmUri = Uri.fromFile(new File(<path>));

        AudioAttributes attributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_ALARM)
                .build();

        channel.setSound(alarmUri, attributes);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.