Cách phát âm thanh thông báo Android


168

Tôi đã tự hỏi làm thế nào tôi có thể phát một âm thanh thông báo mà không phát nó qua luồng phương tiện truyền thông. Ngay bây giờ tôi có thể thực hiện việc này thông qua trình phát phương tiện, tuy nhiên tôi không muốn nó phát dưới dạng tệp phương tiện, tôi muốn nó phát dưới dạng thông báo hoặc cảnh báo hoặc nhạc chuông. đây là một ví dụ về mã của tôi trông như thế nào ngay bây giờ:

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

Câu trả lời:


420

Nếu bất cứ ai vẫn đang tìm giải pháp cho vấn đề này, tôi đã tìm thấy câu trả lời tại Cách phát nhạc chuông / âm thanh báo thức trong Android

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

Bạn có thể thay đổi TYPE_NOTIFICATION thành TYPE_ALARM, nhưng bạn sẽ muốn theo dõi Nhạc chuông r của mình để dừng phát nó ... giả sử, khi người dùng nhấp vào nút hoặc thứ gì đó.


2
Ví dụ, điện thoại Motorola đã mở rộng hoạt động tùy chọn và cho phép người dùng xác định âm thanh thông báo cho sms và các danh mục khác. Phương pháp trên sẽ không hoạt động với loại điện thoại này. Bạn có bất cứ ý tưởng làm thế nào để giải quyết vấn đề này?
David

2
Tôi đã có một lỗi với điều này : MediaPlayer - Should have subtitle controller already set. Nó có nghĩa là gì?
De Khánh

Sử dụng giải pháp này, sau 28/29 lần, âm thanh sẽ ngừng phát. Có ai biết tại sao không?
Tom Brinkkemper

1
Tại sao bạn bắt mọi ngoại lệ? Cái nào có thể được ném?
Miha_x64

2
@Sam, vâng. stackoverflow.com/q/39876885/2614353 . Về cơ bản, không tạo đối tượng RingTone mỗi khi bạn chơi nó. Tạo nó một lần, và sau đó chơi cùng một đối tượng nhiều lần.
Tom Brinkkemper

205

Bây giờ bạn có thể làm điều này bằng cách bao gồm âm thanh khi tạo thông báo thay vì gọi riêng âm thanh.

//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
Điều này giải quyết một vấn đề khác - không phải "cách phát âm thanh thông báo", mà là "cách phát thông báo hiển thị âm thanh". Câu trả lời được chấp nhận là hợp lý trong giải pháp của nó.
Fabian Tamp

7
Có lẽ bạn cũng nên thiết lập tính năng này để phát qua STREAM_NOTIFICATION để nó được phát với tùy chọn âm lượng thông báo hiện tại của hệ điều hành: .setSound (soundUri, AudioManager.STREAM_NOTIFICATION)
mwk

@Rob Riddle Nó hoạt động tốt. nhưng trong trường hợp có nhiều thông báo, ví dụ 100 thông báo song song âm thanh sẽ bị lẫn với âm thanh thông báo tiếp theo. một cách hợp lý nếu âm thanh đã được phát thì nên chờ hoàn thành lần phát trước. Bạn có thể vui lòng giúp đỡ trong kịch bản này?
Waqas Ali Razzaq

không phát âm thanh khi ứng dụng ở chế độ nền. Bất kì lời đề nghị nào?
Sagar Nayak

47

Nếu bạn muốn phát âm thanh thông báo mặc định, thì bạn có thể sử dụng phương thức setDefaults (int) của NotificationCompat.Builderlớp:

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

Tôi tin rằng đó là cách dễ nhất để hoàn thành nhiệm vụ của bạn.


không phát âm thanh khi ứng dụng ở chế độ nền. Bất kì lời đề nghị nào?
Sagar Nayak

13

Thử cái này:

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

Đã được một thời gian kể từ câu hỏi của bạn, nhưng ... Bạn đã thử cài đặt loại luồng Âm thanh chưa?

mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);

Nó phải được thực hiện trước khi chuẩn bị.


2

Tôi đã có khá nhiều câu hỏi tương tự. Sau một số nghiên cứu, tôi nghĩ rằng nếu bạn muốn phát "âm thanh thông báo" mặc định của hệ thống, bạn sẽ phải hiển thị một thông báo và bảo nó sử dụng âm thanh mặc định. Và có điều gì đó để nói về lập luận trong một số câu trả lời khác rằng nếu bạn đang phát âm thanh thông báo, bạn cũng nên trình bày một số thông báo thông báo.

Tuy nhiên, một chút tinh chỉnh API thông báo và bạn có thể tiến gần đến những gì bạn muốn. Bạn có thể hiển thị thông báo trống và sau đó xóa nó tự động sau vài giây. Tôi nghĩ rằng điều này sẽ làm việc cho tôi; có lẽ nó sẽ làm việc cho bạn

Tôi đã tạo một tập hợp các phương thức tiện lợi com.globalmentor.android.app.Notifications.javacho phép bạn tạo âm thanh thông báo như thế này:

Notifications.notify(this);

Đèn LED cũng sẽ nhấp nháy và nếu bạn có quyền rung, sẽ có rung. Có, một biểu tượng thông báo sẽ xuất hiện trên thanh thông báo nhưng sẽ biến mất sau vài giây.

Tại thời điểm này, bạn có thể nhận ra rằng, vì dù sao thông báo sẽ biến mất, bạn cũng có thể có một thông báo đánh dấu cuộn trong thanh thông báo; bạn có thể làm điều đó như thế này:

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

Có nhiều phương pháp tiện lợi khác trong lớp này. Bạn có thể tải xuống toàn bộ thư viện từ kho Subversion của nó và xây dựng nó với Maven. Nó phụ thuộc vào thư viện corementor-core, cũng có thể được xây dựng và cài đặt với Maven.


Đó là cách phức tạp để chỉ đơn giản là phát ra âm thanh. Bạn chỉ có thể làm điều này: stackoverflow.com/a/9622040/1417267
slinden77


1

Tôi nghĩ rằng khái niệm "âm thanh thông báo" đôi khi sai đối với giao diện người dùng Android.

Hành vi dự kiến ​​của Android là sử dụng Thông báo tiêu chuẩn để cảnh báo người dùng. Nếu bạn phát âm thanh thông báo mà không có biểu tượng trên thanh trạng thái, bạn sẽ khiến người dùng bối rối ("âm thanh đó là gì? Không có biểu tượng nào ở đây, có lẽ tôi có vấn đề về thính giác?").

Cách đặt âm thanh trên thông báo, ví dụ, ở đây: Đặt âm thanh cho thông báo


1
Không thực sự, đây có thể là một thông báo trong ứng dụng. Ví dụ: nếu bạn đang ở trong một ứng dụng trò chuyện và có hiệu ứng âm thanh nhỏ cho các tin nhắn đến và đi. Đó là những thông báo thực chất và bạn muốn chúng im lặng khi điện thoại ở chế độ im lặng.
copolii

Vâng, bạn đúng nhưng đó là một điều khác. Tôi đã nói (giả sử đây là chủ đề của câu hỏi) về "âm thanh thông báo hệ thống", đó là trên GUI Android của hệ thống. Tất nhiên, khi bạn vào ứng dụng của riêng bạn, tất cả tùy thuộc vào bạn.
think01

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
Cảm ơn bạn vì đoạn mã này, có thể cung cấp một số trợ giúp hạn chế, ngay lập tức. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ giúp nó hữu ích hơn cho những người đọc tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích, bao gồm các giả định bạn đã thực hiện.
NOh

0

Đặt âm thanh thành kênh thông báo

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

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

        channel.setSound(alarmUri, attributes);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.