Search code examples
javaandroidandroid-preferencesringtone

Setting Ringtone from android preferences is not working


I am having an reminder application that will allow the user to set the required ringtone for notification from settings option which I implemnted using android preferences.

The ringtone dialog is displayed with the list and the ringtone I select is updated but the selected ringtone is not set to the notification. It always notifies with the default ringtone of the device.

I referred and tried the answers for similar questions but its not working

Preferences.xml

<?xml version="1.0" encoding="utf-8"?>
  <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  <PreferenceCategory
            android:title="Settings">
    <RingtonePreference
            android:name="RingtonePreference"
            android:summary="Select a ringtone"
            android:title="Ringtones"
            android:key="@string/ringtonePref"
            android:defaultValue="content://settings/system/notification_sound"
    />
</PreferenceCategory>
</PreferenceScreen>

Prefrence.java

public class Preferences extends PreferenceActivity implements OnPreferenceChangeListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);
}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    String ringtonePreference;
    SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(getBaseContext());
    ringtonePreference = prefs.getString("ringtonePref",
            "DEFAULT_RINGTONE_URI");
}
@Override
protected void onResume() {
    super.onResume();
    RingtonePreference pref = (RingtonePreference) findPreference(getString(R.string.ringtonePref));
    pref.setOnPreferenceChangeListener(this);

}

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    // TODO Auto-generated method stub
    updateRingtoneSummary((RingtonePreference) preference, Uri.parse((String) newValue));
    return true;
}

private void updateRingtoneSummary(RingtonePreference preference, Uri ringtoneuri) {
    // TODO Auto-generated method stub
    Ringtone ringtone = RingtoneManager.getRingtone(this, ringtoneuri);
    if (ringtone != null)
        preference.setSummary(ringtone.getTitle(this));
    else
        preference.setSummary("Silent");
}

}

MainActivity.java

    @Override
     public boolean onMenuItemSelected(int featureId, MenuItem item) {
    switch(item.getItemId()) {

    case R.id.menu_settings: 
        Intent intent = new Intent(this, Preferences.class); 
        startActivity(intent); 
        return true;
    case R.id.menu_about: 
        Intent i = new Intent(this, About.class); 
        startActivity(i); 
    }

    return super.onMenuItemSelected(featureId, item);
}

NotificationService.java

NotificationManager mgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

    Intent notificationIntent = new Intent(this, ReminderEditActivity.class); 
    notificationIntent.putExtra(RemindersDbAdapter.KEY_ROWID, rowId); 

    PendingIntent pi = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT); 

    Notification note=new Notification(R.drawable.ic_icon, title, System.currentTimeMillis());
    note.setLatestEventInfo(this, title, "You have a task to be done!", pi);
note.flags |= Notification.FLAG_AUTO_CANCEL;
int id = (int)((long)rowId);
    mgr.notify(id, note); 

Solution

  • Step 1) Get the ringtone from preferences.

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    // DO NOT ever call getBaseContext() unless you know what you're doing. "this" or "getApplicationContext() is perfect. Google the difference.
    String ringtonePreference = prefs.getString("ringtonePref", "DEFAULT_RINGTONE_URI");
    // The key of preference was "@string/ringtonePref" which is useless since you're hardcoding the string here anyway.
    Uri ringtoneuri = Uri.parse(ringtonePreference);
    

    Consider using DEFAULT_NOTIFICATION_URI instead of DEFAULT_RINGTONE_URI.

    Step 2) Set it to the notification.

    NotificationCompat.Builder b = new NotificationCompat.Builder(context)
        .setSound(ringtoneuri)
        ...