如何在SharedPreferences中存储键值对?

时间:2015-10-17 14:36:14

标签: java android sharedpreferences key-value

我正在开发一个随机生成密码的应用程序。我正在添加“保存”功能,以便用户可以将密码保存在SharedPreferences中。 (这不是你应该用你的密码做的事)

我有一项名为PasswordActivity的活动,在该活动中,我会显示已保存的密码。

这是我保存密码的方式:我提示用户输入密码的名称/密钥,以便他/她以后可以识别。然后我在实用程序类中使用以下方法将密钥和密码保存在SharedPreferences中:

public static int savePassword (Context c, String passwordKey, String passwordValue) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
    Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
    Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
    SharedPreferences.Editor editor = prefs.edit ();

    boolean duplicateKey = !keys.add (passwordKey);
    boolean duplicateValue = !values.add (passwordValue);

    if (duplicateKey)
        return KEY_DUPLICATE;
    if (duplicateValue)
        return VALUE_DUPLICATE;

    editor.putStringSet (PASSWORD_KEYS, keys).
            putStringSet (PASSWORD_VALUES, values).apply ();

    return SUCCESS;
}

我写了另一种获取密码及其名称的方法。您可能已经猜到了该方法返回HashMap<String, String>

public static HashMap<String, String> getPasswords (Context c) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
    Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
    Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());

    ArrayList<String> keysList = new ArrayList<> ();
    ArrayList<String> valuesList = new ArrayList<> ();

    for (String key : keys) {
        keysList.add (key);
    }

    for (String value : values) {
        valuesList.add (value);
    }

    HashMap<String, String> map = new HashMap<> ();

    for (int i = 0 ; i < keys.size () ; i++) {
        map.put (keysList.get (i), valuesList.get (i));
    }

    return map;
}

我承认代码非常混乱。我首先得到两组中的东西并将它们转换为ArrayList s并将数组列表中的东西添加到地图中并返回。

唷!这是很多工作!

现在,当用户生成密码并保存密码时,这两组包含正确的内容:(这些是假数据)

keys:
key1

values:
value1

这一切都很好。但是当我生成另一个密码并保存它时,这两组变得混乱:

keys:
key1
key2

values:
value2
value1

现在,当我调用getPasswords方法时,它将返回

{key1, value2}, {key2, value1}

这是不正确的。看完文档后,我发现了:

  

它不保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。

我猜是造成错误结果的原因。

所以我想知道是否有其他方法来存储这些密码及其名称?

2 个答案:

答案 0 :(得分:1)

我建议使用数据库,例如SQLCipher for Android,这样用户就可以为应用提供主密码,并且所有数据都以加密方式存储在设备上。

但是,让我们假装,为了成功击退外星人的入侵并防止无数人的大规模屠杀,你必须使用SharedPreferences来实现这一点。在那之后,你将需要在一个被征用的外星人太空船中与一个明智的伙伴一起飞行并成功将你的应用程序上传到一个外星母船的计算机系统中(幸运的是,恰好运行Android,因为Android非常出色)整个银河系的市场份额。)

或者:

  1. 让每个键和值成为SharedPreferences中的单独条目。毕竟,SharedPreferences 键值存储。为您的密钥和值使用专用的首选项文件(以免与您可能想要存储的任何其他内容发生冲突),然后您知道所有密钥都是来自用户的密钥。

  2. HashMap标记为JSON或XML或其他内容并将其保存为字符串,根据需要对其进行解组。

答案 1 :(得分:1)

当你存储多个名字时密码,我会建议一个本地SQLite数据库。 SharedPreferences用于单个值,而不是值集。

如果您无法设置整个SQLiteOpenHelper和所有原始SQL代码,您可以查看一些ORM帮助程序,例如SugarOrm(我目前使用它,它非常易于设置和使用)< / p>