问题描述
我正在开发一个随机生成密码的应用程序。
我正在添加“保存”功能,以便用户可以将其密码保存在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>
该方法返回一个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
两个集合中的东西转换为ArrayList
,并将数组列表中的东西添加到地图中并返回。
唷! 那是很多工作!
现在,当用户生成密码并将其保存时,这两组密码包含正确的内容:(这些是伪数据)
keys: key1 values: value1
很好 但是,当我生成另一个密码并将其保存时,这两个密码会变得混乱:
keys: key1 key2 values: value2 value1
现在,当我调用getPasswords
方法时,它将返回
{key1, value2}, {key2, value1}
这是不正确的。 查看文档后,我发现:
它不保证集合的迭代顺序。 特别是,它不能保证顺序会随着时间的推移保持恒定。
我猜这是导致错误结果的原因。
所以我想知道是否还有其他方法可以存储这些密码及其名称?
1楼
当您存储多个名称和密码时,我建议使用本地SQLite数据库。 SharedPreferences用于单个值,而不是值集。
如果您不必烦恼设置整个SQLiteOpenHelper和所有原始SQL代码,则可以看看一些ORM帮助器,例如SugarOrm(我目前正在使用它,它的EXTREMELY易于设置和使用)
2楼
我建议使用一个数据库,例如 ,以便用户可以为该应用提供主密码,并且所有数据都以加密方式存储在设备上。
但是,让我们假装,为了成功抵抗外星人的入侵并防止无数人的大屠杀,您必须使用SharedPreferences
来实现这一点。
此后,您将需要与一个明智的同伴一起乘坐被征服的外星飞船,并将您的应用程序成功上载到其中一艘外星人母舰的计算机系统中(幸运的是,碰巧正在运行Android,因为Android具有卓越的整个银河系的市场份额)。
或者:
将每个键和值分别作为
SharedPreferences
单独条目。 毕竟,SharedPreferences
是一个键值存储。 对您的键和值使用专用的首选项文件(以免与您可能要存储的其他内容冲突),然后您就会知道所有键都是用户的。将
HashMap
编组为JSON或XML或其他内容,并将其另存为字符串,然后根据需要将其解组。