I have this RingtonePreference (from Android Studio's default SettingsActivity):
pref_notification.xml:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<RingtonePreference
android:dependency="notifications_alarm"
android:key="notifications_alarm_ringtone"
android:title="@string/pref_title_ringtone"
android:ringtoneType="notification|all"
android:defaultValue="content://settings/system/notification_sound" />
SettingsActivity.java:
private void setupSimplePreferencesScreen() {
if (!isSimplePreferences(this)) {
return;
}
// Add 'general' preferences.
addPreferencesFromResource(R.xml.pref_general);
// Add 'notifications' preferences, and a corresponding header.
PreferenceCategory fakeHeader = new PreferenceCategory(this);
fakeHeader.setTitle(R.string.pref_header_notifications);
getPreferenceScreen().addPreference(fakeHeader);
addPreferencesFromResource(R.xml.pref_notification);
bindPreferenceSummaryToValue(findPreference("notifications_alarm_ringtone"));
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class NotificationPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_notification);
bindPreferenceSummaryToValue(findPreference("notifications_alarm_ringtone"));
}
}
I would like to add my app's custom ringtones from res/raw folder to the list. (I don't need them to be available for other apps.)
Finally I made my own ExtraRingtonePreference based on this answer: In preferences, select my sound just like with RingtonePreference
I'll include it here for future reference:
src/main/java/com/fletech/android/preference/ExtraRingtonePreference.java:
src/main/res/values.attrs.xml:
src/res/values/ringtone_preference_strings.xml:
and the usage in src/main/res/xml/pref_alarm.xml:
Option 1: Copy to device storage
Copy your ringtone files to the device's storage. I did basically this for an app on GitHub, here, where I copied alarm tones from raw resources to the device's alarms directory (you'll need to replace all the instances of "alarms" with "ringtones"). Then we use
ContentValues
to create metadata telling the system that the files are ringtones and useMediaStore.Audio.Media.getContentUriForPath
and thencontext.getContentResolver().insert(contentUri, contentValues)
to add the ringtones to the device's database, so they'll be included in theRingtonePreference
's list. You can also set a ringtone as the default usingRingtoneManager.setActualDefaultRingtoneUri()
, though you'll need theWRITE_SETTINGS
permission.Also, remember to use the URI you get from
getContentUriForPath()
when callinggetContentResolver().insert()
andRingtoneManager.setActualDefaultRingtoneUri()
. And, make sure you add to your AndroidManifest.xml:Option 2: Custom preference
Create a custom preference, as shown in this guide, or you can use (or subclass) the ListPreference. You will need to retrieve all the device's ringtones using
RingtoneManager.getCursor()
(docs) and add them to the list, and include your custom ringtones also.Then, in your preferences.xml file, instead of RingtonePreference, you would use
In your case, since it's okay if other apps have access to the ringtones as well, I'd recommend using the first method, since in general I feel it's better not to duplicate functionality already provided by the system, since it's best to utilize what the user is already familiar with.