我正在创建一个使用用户名/密码连接到服务器的应用程序,我想启用“保存密码”选项,这样用户就不必在每次应用程序启动时输入密码。
我试图用共享偏好来做,但不确定这是否是最好的解决方案。
我很感激任何关于如何在Android应用程序中存储用户值/设置的建议。
我正在创建一个使用用户名/密码连接到服务器的应用程序,我想启用“保存密码”选项,这样用户就不必在每次应用程序启动时输入密码。
我试图用共享偏好来做,但不确定这是否是最好的解决方案。
我很感激任何关于如何在Android应用程序中存储用户值/设置的建议。
当前回答
使用Richard提供的代码片段,您可以在保存密码之前对其进行加密。然而,首选项API并没有提供一种简单的方法来拦截值并加密它-你可以通过OnPreferenceChange监听器阻止它被保存,理论上你可以通过preferenceChangeListener修改它,但这会导致一个无休止的循环。
我之前建议添加一个“隐藏的”首选项来完成这个任务。这绝对不是最好的方法。我将提出另外两个我认为更可行的选择。
首先,最简单的,是在preferenceChangeListener中,你可以抓取输入的值,加密,然后保存到另一个首选项文件中:
public boolean onPreferenceChange(Preference preference, Object newValue) {
// get our "secure" shared preferences file.
SharedPreferences secure = context.getSharedPreferences(
"SECURE",
Context.MODE_PRIVATE
);
String encryptedText = null;
// encrypt and set the preference.
try {
encryptedText = SimpleCrypto.encrypt(Preferences.SEED,(String)newValue);
Editor editor = secure.getEditor();
editor.putString("encryptedPassword",encryptedText);
editor.commit();
}
catch (Exception e) {
e.printStackTrace();
}
// always return false.
return false;
}
第二种方法,也是我现在更喜欢的方法,是创建自己的自定义首选项,扩展EditTextPreference, @Override setText()和getText()方法,以便setText()加密密码,getText()返回null。
其他回答
您需要使用sqlite,安全工具来存储密码。 下面是最好的例子,它存储密码——passwordsafe。 这是来源和解释的链接 http://code.google.com/p/android-passwordsafe/
关于在Android Activity中存储单个首选项的最简单的方法是这样做:
Editor e = this.getPreferences(Context.MODE_PRIVATE).edit();
e.putString("password", mPassword);
e.commit();
如果您担心这些密码的安全性,那么您可以在存储密码之前对其进行加密。
我就是这么做的。
这不会在严格模式下给出错误。
public class UserPreferenceUtil
{
private static final String THEME = "THEME";
private static final String LANGUAGE = "LANGUAGE";
public static String getLanguagePreference(Context context)
{
String lang = getPreferenceByKey(context,LANGUAGE);
if( lang==null || "System".equalsIgnoreCase(lang))
{
return null;
}
return lang;
}
public static void saveLanguagePreference(Context context,String value)
{
savePreferenceKeyValue(context, LANGUAGE,value);
}
public static String getThemePreference(Context context)
{
return getPreferenceByKey(context,THEME);
}
public static void saveThemePreference(Context context, String value)
{
savePreferenceKeyValue(context,THEME,value);
}
public static String getPreferenceByKey(Context context, String preferenceKey )
{
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String value = sharedPreferences.getString(preferenceKey, null);
return value;
}
private static void savePreferenceKeyValue(Context context, String preferenceKey, String value)
{
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(preferenceKey,value);
editor.apply();
}
}
我的应用程序不需要密码。但是,我不会保存密码或加密密码,而是保存单向散列。当用户登录时,我将以同样的方式哈希输入,并将其与存储的哈希匹配。
使用Richard提供的代码片段,您可以在保存密码之前对其进行加密。然而,首选项API并没有提供一种简单的方法来拦截值并加密它-你可以通过OnPreferenceChange监听器阻止它被保存,理论上你可以通过preferenceChangeListener修改它,但这会导致一个无休止的循环。
我之前建议添加一个“隐藏的”首选项来完成这个任务。这绝对不是最好的方法。我将提出另外两个我认为更可行的选择。
首先,最简单的,是在preferenceChangeListener中,你可以抓取输入的值,加密,然后保存到另一个首选项文件中:
public boolean onPreferenceChange(Preference preference, Object newValue) {
// get our "secure" shared preferences file.
SharedPreferences secure = context.getSharedPreferences(
"SECURE",
Context.MODE_PRIVATE
);
String encryptedText = null;
// encrypt and set the preference.
try {
encryptedText = SimpleCrypto.encrypt(Preferences.SEED,(String)newValue);
Editor editor = secure.getEditor();
editor.putString("encryptedPassword",encryptedText);
editor.commit();
}
catch (Exception e) {
e.printStackTrace();
}
// always return false.
return false;
}
第二种方法,也是我现在更喜欢的方法,是创建自己的自定义首选项,扩展EditTextPreference, @Override setText()和getText()方法,以便setText()加密密码,getText()返回null。
我使用Android KeyStore在ECB模式下使用RSA加密密码,然后将其保存在SharedPreferences中。
当我想要回密码时,我从SharedPreferences中读取加密的密码,并使用KeyStore对其解密。
使用这个方法,你可以生成一个公共/私有密钥对,其中私有密钥对由Android安全存储和管理。
这里有一个关于如何做到这一点的链接:Android KeyStore教程