How to set RingtonePreference value from code?

I have the following preference:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <RingtonePreference android:showDefault="true" android:showSilent="true" android:title="@string/feed_alert_ringtone" android:ringtoneType="ringtone|notification|alarm|all" android:key="alertringtone" android:persistent="false"> </RingtonePreference> </PreferenceScreen> 

When the user changes this preference, I manually save the Uri in the database:

 public boolean onPreferenceChange(Preference pref, Object change) { String ringtone = change.toString(); // save it to a db ... return true; } 

My problem is that when the user closes and then returns to PreferenceScreen , the default RingtonePreference always Silence . Of course, I need to set the value manually.

Tried this in my PreferenceActivity :

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); // the XML above String database_ringtone = ... // get the string saved above from db // and according to some parameters passed // to the intent Preference ringtone = findPreference("alertringtone"); ringtone.setDefaultValue( database_ringtone ); // also tried: ringtone.setDefaultValue( Uri.parse(database_ringtone) ); } 

Unfortunately, the preference remains in "Silence" (which means "empty"). I thought that when the Preference not persistent , the default value will be used.

I cannot do this persistent , because preference is used for several elements, and the data that I get from the database changes according to some additional data passed to the intent.

However, I do not want to set the default value, but the current value that I get from the database. Thought it could be a workaround. So any other way will be good too.

Double-checked saving and retrieving from the database works, so no problem.

How can I set the RingtonePreference value from code?


Edit: here is a small explanation of what I want to do, maybe there is another way.

I have several menu entries (the number varies from user to user) for which the user can select a ringtone for the call. Selecting a ringtone works with the xml above, the identifier of the menu item is passed from Intent to PreferenceActivity . The ringtone URI is then stored in the database.

When one of the recordings changes, the sound signal is played in accordance with the ringtone selected by the user. Therefore, he knows which one has changed. There are no problems so far.

The problem is when the user wants to change the ringtone for the recording for which he has already defined. If the user has selected the Foo ringtone before, when clicking on the RingtonePreference , the Foo sound should be preselected. This is not a serious mistake (rather, it seems like a failure), but still very annoying.

As far as I can tell, there is no way to pre-select the default RingtonePreference from the code? Or am I doing this "just wrong"?


Edit 2: Okey, I think there is no way to do this. Very strange, the core of the android. Allows us to use Preference and get values ​​from it, but not return values. It must have been a real rush. I am glad that they allowed us to check the CheckBoxPreference code ...

+6
source share
3 answers

I searched how to set the default value for the ringtone, and implemented the same thing as you when the preference is not set, than the value is empty and the default is selected by default. But I do it

 // I read my ringtone setting (I read the value from my ringtone_uri key) // then if it is not set I set the value with the default value from the phone SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); Uri configuredUri = Uri.parse(sharedPrefs.getString("ringtone_uri", Settings.System.DEFAULT_RINGTONE_URI.toString())); // then I do this, I save the default ringtone to my settins if(configuredUri.equals(Settings.System.DEFAULT_RINGTONE_URI)){ sharedPrefs.edit() .putString("ringtone_uri", Settings.System.DEFAULT_RINGTONE_URI.toString()) .commit(); } 

I don't know if this will help you, but I hope this helps someone else. btw I'm worried about this workaround

+6
source

At the same time, when you tried to solve the same problem more than two years later, you did not find good answers, so I will publish my solution.

Unlike many other settings, RingtonePreference does not seem to affect the call to setDefaultValue (). I tried the same thing and couldn't get it to work, where it worked perfectly for most other settings.

I looked at the API a bit and found a series of callbacks that RingtonePreference uses to save and restore state. Of particular note is the RingtonePreference.onRestoreState () method

So, when the ringtone picker opens, it calls this method to select which ringtone will be selected. To select the melody you selected first, you need to override this method and return the URI that you want to select.

My solution was as follows:

  //Create a Ringtone Preference RingtonePreference ringtonePreference = new RingtonePreference(this){ @Override protected Uri onRestoreRingtone(){ if(database_ringtone.equals("")){ return null; } else{ return Uri.parse(database_ringtone); } } }; ringtonePreference.setTitle(getString(R.string.pref_title_ringtone)); ringtonePreference.setPersistent(false); //Set the summary to the initial value BasePreferenceChangeListener.updatePreference(ringtonePreference, agency.ringtone); getPreferenceScreen().addPreference(ringtonePreference); 

I decided to override the method anonymously, and then insert the Preference manually into the PreferenceScreen.

You can also create a subclass of RingtonePreference that overrides this method, and then use this subclass in XML instead of RingtonePreference.

+4
source

It seems that you do not include the path to the sound file when you insert the ringtone into the database, so it will be "silent" whenever you try to install from the application. When you say that you have to set the value manually, it looks like the sound file has been picked up by the media / ringtone media player and inserted into the database at that moment. The code below should be modified the way you do it, but hope that it gives you the right idea.

Try something like:

 File k = new File(path2, filename); ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath()); Uri uri = MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()); //kill database for this object before inserting getContentResolver().delete(uri, MediaStore.MediaColumns.DATA + "=\"" + k.getAbsolutePath() + "\"", null); Uri newUri = getContentResolver().insert(uri, values); 
-1
source

Source: https://habr.com/ru/post/888561/


All Articles