大家好,今天给大家带来轻型数据库SharedPreferences,它是一个非常便捷的数据库,存入的是xml键对值数据, 数据类型包(ints,floats,boolean,strings,longs,Set<String>(android 11以后),存放位置:/data/data/<包名>/shared_prefs,存放的是应用私有的数据,主要用于软件偏好设置,简单信息存取、数据缓存等,接下来我就用登录界面的例子,加深大家对sharePreference理解。
布局xml文件:
1.R.layout.activity_main
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_login" >
<ImageView
android:id="@+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="22dp"
android:src="@drawable/ic_logo" />
<EditText
android:id="@+id/account_et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/img1"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:background="@drawable/bg_yellow"
android:ems="10"
android:paddingLeft="40dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/account_et"
android:layout_marginLeft="60dp"
android:text="账号:" />
<EditText
android:id="@+id/pass_et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/account_et"
android:layout_centerVertical="true"
android:background="@drawable/bg_yellow"
android:ems="10"
android:paddingLeft="40dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/pass_et"
android:layout_marginLeft="60dp"
android:text="密码:" />
<CheckBox
android:id="@+id/rem_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/pass_et"
android:layout_below="@+id/pass_et"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:text="记住密码" />
<Button
android:id="@+id/login_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/pass_et"
android:layout_below="@+id/rem_cb"
android:layout_marginTop="34dp"
android:background="@drawable/login_selector"
android:onClick="login" />
<Button
android:id="@+id/register_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/login_btn"
android:layout_alignBottom="@+id/login_btn"
android:layout_alignRight="@+id/pass_et"
android:background="@drawable/register_selector"
android:onClick="register" />
</RelativeLayout>
布局很简单,就是用相对布局实现的。‘
2.activity_system.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_yellow">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pic8"
android:layout_centerInParent="true"/>
</RelativeLayout>
第二个页面是成功页面,由第一个页面跳到页面二就表示成功了。
3.MainActivity.java
public class MainActivity extends Activity {
private static final String SEED = "android";
private EditText mAccount_et;
private EditText mPass_et;
private CheckBox mRem_cb;
private Context context;
private SharedPreferences mSp;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initViews();// 初始化组件
getValue();// 得到SharedPreferences的值
}
/**
* 得到SharedPreferences的值
*/
private void getValue() {
// 参数二:默认值
if (mSp.getBoolean("isChecked", false)) {
String SpAccount = mSp.getString("username", null);
mAccount_et.setText(SpAccount);
String SpPass = mSp.getString("password", null);
try {
// 给密码解密
mPass_et.setText(AESEncryptor.decrypt(SEED, SpPass));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mRem_cb.setChecked(true);
}
}
/**
* 初始化组件
*/
private void initViews() {
mAccount_et = (EditText) findViewById(R.id.account_et);
mPass_et = (EditText) findViewById(R.id.pass_et);
mRem_cb = (CheckBox) findViewById(R.id.rem_cb);
context = this;
mSp = getSharedPreferences("info", MODE_PRIVATE);
}
/**
* 登录点击事件
*/
public void login(View v) {
String accountValue = mAccount_et.getText().toString().trim();
String passValue = mPass_et.getText().toString().trim();
// SharedPreferences编辑器
Editor edit = mSp.edit();
if (accountValue.length() > 0 && passValue.length() > 0) {
if (mRem_cb.isChecked()) {
// 创建编辑器
// edit.putString(key,value);
edit.putString("username", accountValue);
try {
// 把输入的密码加密encrypt
edit.putString("password",
AESEncryptor.encrypt(SEED, passValue));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
edit.putBoolean("isChecked", true);
} else {
edit.putBoolean("isChecked", false);
}
// 提交
edit.commit();
// 跳转页面
Intent intent = new Intent(MainActivity.this, SystemActivity.class);
startActivity(intent);
} else {
Toast.makeText(MainActivity.this, "账号和密码都不能为空..",
Toast.LENGTH_SHORT).show();
}
}
/**
* 注册点击事件
*/
public void register(View v) {
Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
}
}
我这里用到了加密和解密技术,因为密码是很私有的数据,不能把数据完全暴露给别人看,存在安全问题,我导入了一个加密和解密java文件,调用它的方法就行了。
4.AESEncryptor.java
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = null;
if (android.os.Build.VERSION.SDK_INT >= 17) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
sr.setSeed(seed);
kgen.init(256, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
今天给大家的讲解就到这里了,今天是情人节,情人节快乐,今晚小编情绪不高,前几个星期和女朋友分手了,碰上了今天的情人节,心情郁闷,感想颇多,希望大家有情人终成眷属,渐渐的习惯了一个人前进的滋味。晚安