详解轻型数据库SharedPreferences及登录界面的应用

 大家好,今天给大家带来轻型数据库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));  
    }  
}

今天给大家的讲解就到这里了,今天是情人节,情人节快乐,今晚小编情绪不高,前几个星期和女朋友分手了,碰上了今天的情人节,心情郁闷,感想颇多,希望大家有情人终成眷属,渐渐的习惯了一个人前进的滋味。晚安











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值