Как установить значение RingtonePreference из кода? - PullRequest
6 голосов
/ 19 мая 2011

У меня есть следующие предпочтения:

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

Когда пользователь изменяет это предпочтение, я вручную сохраняю Uri в базе данных:

public boolean onPreferenceChange(Preference pref, Object change) {
    String ringtone = change.toString();

    // save it to a db
    ...

    return true;
}

Моя проблема в том, что когда пользователь закрывается и затем возвращается к PreferenceScreen, значение по умолчанию RingtonePreference всегда равно Silence. Конечно, я должен установить значение вручную.

Попробовал это в моем 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) );
}

К сожалению, предпочтение остается на «Безмолвии» (что означает «пустой»). Я думал, что когда Preference не persistent, будет использоваться значение по умолчанию.

Я не могу сделать это persistent, потому что предпочтение используется для нескольких элементов, и данные, которые я получаю из БД, изменяются в соответствии с некоторыми дополнительными данными, передаваемыми в намерение.

Тем не менее, я не хочу устанавливать значение по умолчанию, но текущее значение, которое я получаю из базы данных. Думаю, это может быть обходной путь. Так что любой другой способ тоже был бы хорош.

Двойная проверка сохранения и извлечения из БД работает, так что это не проблема.

Как я могу установить значение RingtonePreference из кода?


Редактировать: Вот небольшое объяснение того, что я хочу сделать, может быть, есть другой способ.

У меня есть несколько пунктов меню (количество зависит от пользователя), для которого пользователь может выбрать мелодию звонка. Выбор мелодии звонка работает с xml выше, идентификатор пункта меню передается с Intent на PreferenceActivity. URI рингтона затем сохраняется в базе данных.

Когда одна из записей изменяется, сигнал тревоги воспроизводится в соответствии с выбором мелодии звонка, сделанным пользователем. Так что он знает, какой из них изменился. Пока проблем нет.

Проблема в том, что когда пользователь хочет изменить мелодию звонка для записи, для которой он уже определен. Если пользователь выбрал рингтон Foo ранее, то при нажатии на RingtonePreference рингтон Foo уже должен быть предварительно выбран. Это не серьезная ошибка (больше похоже на глюк), но все же очень раздражает.

Насколько я могу судить, нет способа предварительно выбрать по умолчанию RingtonePreference из кода? Или я делаю это "просто неправильно"?


Редактировать 2: Окей, я думаю, что нет способа сделать это. Очень странно, ядро ​​андроида. Позволяет нам использовать Preference и получать значения из него, но не возвращать значения обратно. Должно быть, это была настоящая спешка. Я рад, что они позволили нам проверить CheckBoxPreference из кода ...

Ответы [ 3 ]

6 голосов
/ 04 октября 2011

Я искал, как установить значение по умолчанию для мелодии звонка, и понял то же самое, что и вы, что, когда предпочтение не установлено, значение является пустым, а беззвучный режим выбран по умолчанию.Но я делаю это

// 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();
}

Я не знаю, поможет ли это вам, но я надеюсь, что это поможет кому-то еще.Кстати, я волнуюсь, находя этот обходной путь

3 голосов
/ 07 сентября 2013

Столкнулся с этим при попытке решить ту же самую проблему через 2 года, не нашел хороших ответов, поэтому я опубликую свое решение.

В отличие от многих других настроек, RingtonePreference, по-видимому, не зависит от вызова setDefaultValue (). Я попробовал то же самое и не смог заставить его работать там, где он работал нормально для большинства других предпочтений.

Я немного посмотрел на API и нашел серию обратных вызовов, которые RingtonePreference использует для хранения и восстановления состояния. Особого внимания заслуживает метод RingtonePreference.onRestoreState ()

Таким образом, когда открывается средство выбора мелодии звонка, он вызывает этот метод для выбора мелодии звонка. Чтобы выбрать мелодию звонка, выбранную изначально, необходимо переопределить этот метод и вернуть URI, который вы хотите выбрать.

Мое решение было следующим

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

Я решил анонимно переопределить метод и затем вручную вставить предпочтение в PreferenceScreen.

Вы также можете создать подкласс RingtonePreference, который переопределяет метод, и затем использовать этот подкласс в XML вместо RingtonePreference.

0 голосов
/ 19 мая 2011

Похоже, вы не указали путь к звуковому файлу при вставке мелодии звонка в базу данных, поэтому он будет переходить в "беззвучный режим" всякий раз, когда вы пытаетесь установить приложение. Когда вы говорите, что должны установить значение вручную, создается впечатление, что звуковой файл извлекается при сканировании мультимедиа медиа / рингтонов и вставляется в базу данных в этот момент. Приведенный ниже код необходимо будет изменить в соответствии с тем, как вы это делаете, но надеюсь, что он даст вам правильное представление.

Попробуйте что-то вроде:

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