6

我有以下偏好:

<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是 always 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,菜单项的 IDIntentPreferenceActivity. 然后将铃声的 URI 存储在数据库中。

当其中一个条目发生变化时,将根据用户所做的铃声选择播放警报。所以他知道是哪一个变了。到目前为止没有问题。

问题是,当用户想要更改他已经定义的条目的铃声时。如果用户之前选择了铃声 Foo,当点击 时RingtonePreference,应该已经预先选择了铃声 Foo。这不是严重的错误(更像是一个小故障),但仍然很烦人。

据我所知,没有办法RingtonePreference从代码中预先选择默认值?还是我这样做“只是错误的”?


编辑2:好吧,我认为没有办法做到这一点。很奇怪,安卓内核。允许我们使用 aPreference并从中获取值,但不能将值放回原处。一定很着急。我很高兴他们允许我们检查CheckBoxPreference代码...

4

3 回答 3

6

我正在搜索如何为铃声设置默认值,并意识到与您相同的事情,即当未设置首选项时,该值为空并且默认选择静音。但我这样做

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

我不知道这是否会帮助你,但我希望它对其他人有帮助。顺便说一句,我很害怕找到这个解决方法

于 2011-10-04T08:31:09.567 回答
3

两年后试图解决完全相同的问题时遇到了这个问题,没有找到任何好的答案,所以我将发布我的解决方案。

与许多其他首选项不同,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);

我选择匿名覆盖该方法,然后将 Preference 手动插入 PreferenceScreen。

您还可以创建覆盖该方法的 RingtonePreference 的子类,然后在 XML 中使用该子类而不是 RingtonePreference。

于 2013-09-07T15:01:20.413 回答
-1

将铃声插入数据库时​​,您似乎没有包含声音文件的路径,因此每当您尝试从应用程序设置时,它都会进入“静音”状态。当您说您必须手动设置该值时,看起来声音文件是通过媒体/铃声的媒体扫描拾取并在此时插入到数据库中的。下面的代码需要根据您的操作方式进行修改,但希望它能给您正确的想法。

尝试类似:

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); 
于 2011-05-19T17:10:52.853 回答