web-dev-qa-db-fra.com

Comment afficher la liste des sons de notification disponibles sur Android

Je crée des notifications dans mon Android, et j'aimerais avoir une option dans mes préférences pour définir le son utilisé pour la notification. Je sais que dans l'application Paramètres, vous pouvez choisir un son de notification par défaut à partir d'une liste. D'où vient cette liste, et est-il possible pour moi d'afficher la même liste dans mon application?

63
robintw

Il suffit de copier/coller du code à partir de l'une de mes applications qui fait ce que vous recherchez.

C'est dans un gestionnaire onClick d'un bouton intitulé "définir la sonnerie" ou quelque chose de similaire:

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

Et ce code capture le choix fait par l'utilisateur:

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

De plus, je conseille à mes utilisateurs d'installer l'application "Rings Extended" à partir du marché Android. Ensuite, chaque fois que cette boîte de dialogue est ouverte sur leur appareil, par exemple depuis mon application ou depuis le menu des paramètres du téléphone, l'utilisateur aura le choix supplémentaire de choisir l'un des mp3 stockés sur son appareil, pas seulement les sonneries intégrées.

101
Mark B

Ou collez-le simplement dans vos préférences XML:

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

Contenu complet de mon exemple XML juste pour le contexte:

<?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>
49
JD.

C'est la méthode que j'utilise pour obtenir une liste des sons de notification disponibles dans le téléphone :)

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

EDIT: Ceci est pour le commentaire concernant la façon de définir le son dans NotificationCompat.Builder. Cette méthode obtient à la place l'ID de la sonnerie, ce que le téléphone utilise, au lieu du TITRE lisible par l'homme que l'autre méthode a obtenu. Combinez l'URI et l'ID, et vous avez l'emplacement des sonneries.

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

Le code ci-dessus renverra une liste de chaînes comme "content: // media/internal/audio/media/27" .. vous pouvez ensuite passer l'une de ces chaînes en tant qu'Uri dans le .setSound ( ) comme:

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

J'espère que c'était assez clair :)

16
Murphybro2
  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
            }
        }
0
Manthan Patel

Voici une autre approche (dans Kotlin), construite à partir d'autres réponses à cette question, qui vous permet de spécifier le nom du ton, puis de le jouer:

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
    }

Cela peut probablement prendre un peu de refactoring et d'optimisation, mais vous devriez avoir l'idée.

0
Nicolai Harbo