如何在Android上调出可用通知音的列表


69

我正在Android应用程序中创建通知,并且希望在我的首选项中有一个选项可以设置用于通知的声音。我知道在“设置”应用程序中,您可以从列表中选择默认的通知声音。该列表从何而来,有没有办法让我在我的应用程序中显示相同的列表?

Answers:


107

只需从我的一个应用程序中复制/粘贴一些可以满足您所要查找内容的代码即可。

这在带有“设置铃声”或类似标签的按钮的onClick处理程序中:

Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone");
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri) null);
this.startActivityForResult(intent, 5);

此代码捕获了用户做出的选择:

@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
    if (resultCode == Activity.RESULT_OK && requestCode == 5) {
        Uri uri = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);

        if (uri != null) {
            this.chosenRingtone = uri.toString();
        } else {
            this.chosenRingtone = null;
        }
    }            
}

另外,我建议我的用户从Android Market安装“ Rings Extended”应用。然后,无论何时在设备上打开此对话框(例如,从我的应用程序或从手机的设置菜单中打开),用户都可以选择存储在设备上的任何mp3,而不仅仅是内置铃声。


谢谢。我能够使用您的代码成功显示铃声,但是在onActivityResult()方法中,我在行“ Uri uri”上收到错误消息“无法从类型Intent静态引用非静态方法getParcelableExtra(String)” = Intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);“
Dharmendra

1
该行应显示为“ Uri uri = intent.getParcelableExtra ...”。请注意“意图”中的小写字母“ i”。只是上面代码的错字。
zeh 2011年

4
我应该如何获取从ringtonePicker意图返回的铃声的名称?
android开发人员

1
记住上一次选择的小修正:intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,(chosenRingtone == null)?(Uri)null:Uri.parse(chosenRingtone));
亚历山大·西迪科夫·菲佛

5
要获取铃声的名称,请执行以下操作:Ringtone ringtone = RingtoneManager.getRingtone(context,uri); 字符串标题= ringtone.getTitle(this);
Vineet Ashtekar '16

49

或者只是将其保留在您的首选项XML中:

  <RingtonePreference android:showDefault="true"
     android:key="Audio" android:title="Alarm Noise"
     android:ringtoneType="notification" />

我的示例XML的全部内容仅用于上下文:

<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:title="Some value"
                    android:key="someval"
                    android:summary="Please provide some value" />
<EditTextPreference android:title="Some other value"
                    android:key="someval2"
                    android:summary="Please provide some other value" />
 <RingtonePreference android:showDefault="true"
     android:key="Audio" android:title="Alarm Noise"
     android:ringtoneType="notification" />

</PreferenceScreen>

18

这是我用来获取手机中可用通知音列表的方法:)

public Map<String, String> getNotifications() {
    RingtoneManager manager = new RingtoneManager(this);
    manager.setType(RingtoneManager.TYPE_NOTIFICATION);
    Cursor cursor = manager.getCursor();

    Map<String, String> list = new HashMap<>();
    while (cursor.moveToNext()) {
        String notificationTitle = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX);
        String notificationUri = cursor.getString(RingtoneManager.URI_COLUMN_INDEX);

        list.put(notificationTitle, notificationUri);
    }

    return list;
}

编辑:这是关于如何在NotificationCompat.Builder中设置声音的注释。相反,此方法获取手机使用的铃声ID,而不是另一种方法获得的人类可读TITLE。合并uri和id,即可获得铃声位置。

public ArrayList<String> getNotificationSounds() {
    RingtoneManager manager = new RingtoneManager(this);
    manager.setType(RingtoneManager.TYPE_NOTIFICATION);
    Cursor cursor = manager.getCursor();

    ArrayList<String> list = new ArrayList<>();
    while (cursor.moveToNext()) {
        String id = cursor.getString(RingtoneManager.ID_COLUMN_INDEX);
        String uri = cursor.getString(RingtoneManager.URI_COLUMN_INDEX);

        list.add(uri + "/" + id);
    }

    return list;
}

上面的代码将返回一个字符串列表,例如“ content:// media / internal / audio / media / 27” ..然后,您可以将其中一个字符串作为Uri传递到.setSound()中,如下所示:

.setSound(Uri.parse("content://media/internal/audio/media/27"))

希望这很清楚:)


很好,但是如何设置要使用NotificationCompat.Builder.setSound(uri)播放的声音?设置从RingtoneManager读取的Uri读数之一不起作用
2015年

我用答案@infero编辑了帖子,希望它清楚并解决您的问题!
Murphybro2

感谢更新。我曾尝试用id设置声音,但是使用了不存在的id-:-( grrrr。再次感谢
infero

通过修改上面的代码是否可以获得当前设置的通知声音?
SoulRayder

@SoulRayderUri actualUri = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_NOTIFICATION);为您提供用户在设备设置中选择的当前通知声音的Uri,以及RingtoneManager.getRingtone(this, actualUri).getTitle(this)提供其标题。
jk7

1
  public void listRingtones() {
            RingtoneManager manager = new RingtoneManager(this);
            manager.setType(RingtoneManager.TYPE_NOTIFICATION);
           // manager.setType(RingtoneManager.TYPE_RINGTONE);//For Get System Ringtone
            Cursor cursor = manager.getCursor();

            while (cursor.moveToNext()) {
                String title = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX);
                String uri = manager.getRingtoneUri(cursor.getPosition());

                String ringtoneName= cursor.getString(cursor.getColumnIndex("title"));



                Log.e("All Data", "getNotifications: "+ title+"-=---"+uri+"------"+ringtoneName);
                // Do something with the title and the URI of ringtone
            }
        }

1

这是另一种方法(在Kotlin中),是从该问题的其他答案中构建的,该方法允许您指定音调的名称,然后播放:

fun playErrorTone(activity: Activity, context: Context, notificationName: String = "Betelgeuse") {

    val notifications = getNotificationSounds(activity)

    try {
        val tone = notifications.getValue(notificationName)
        val errorTone = RingtoneManager.getRingtone(context, Uri.parse(tone))
        errorTone.play()
    } catch (e: NoSuchElementException) {
        try {
            // If sound not found, default to first one in list
            val errorTone = RingtoneManager.getRingtone(context, Uri.parse(notifications.values.first()))
            errorTone.play()
        } catch (e: NoSuchElementException) {
            Timber.d("NO NOTIFICATION SOUNDS FOUND")
        }
    }
}

private fun getNotificationSounds(activity: Activity): HashMap<String, String> {
    val manager = RingtoneManager(activity)
    manager.setType(RingtoneManager.TYPE_NOTIFICATION)
    val cursor = manager.cursor

    val list = HashMap<String, String>()
    while (cursor.moveToNext()) {
        val id = cursor.getString(RingtoneManager.ID_COLUMN_INDEX)
        val uri = cursor.getString(RingtoneManager.URI_COLUMN_INDEX)
        val title = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX)

        list.set(title, "$uri/$id")
    }

    return list
}

可能需要进行一些重构和优化,但是您应该了解一下。

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.