SharePreferance
SharedPreferences sp = getSharedPreferences("app", MODE_PRIVATE);
// 保存配置到 SharedPreferences
SharedPreferences.Editor editor = sp.edit();
// 添加内容到存储区
editor.putString("name", mTxtName.getText().toString());
editor.putString("pass", mTxtPass.getText().toString());
// Editor 必须要 提交 可以使用commit() 或者 apply() (API 9以上)
editor.apply();
SharedPreferences sp =getSharedPreferences("app",MODE_PRIVATE);
String name = sp.getString("name", null);
String pass = sp.getString("pass", null);
机型适配:
- 合理使用Wrap_content ,match_parent
- 尽可能使用RelativiLayout
- 针对不同的机型,使用不同的布局文件(Use Size Qualifiers):
res/layout/main.xml
res/layout-large/main.xml - 尽量使用点9图片(Use Nine-patch Bitmaps)
px:即像素,1px代表屏幕上一个物理的像素点;px单位不被建议使用,因为同样100px的图片,在不同手机上显示的实际大小可能不同,偶尔用到px的情况,是需要画1像素表格线或阴影线的时候,用其他单位如dp会显得模糊。
dp也可写为dip,即density-independent pixel。你可以想象dp更类似一个物理尺寸,比如一张宽和高均为100dp的图片在320×480和480×800的手机上“看起来”一样大。而实际上,它们的像素值并不一样。dp正是这样一个尺寸,不管这个屏幕的密度是多少,屏幕上相同dp大小的元素看起来始终差不多大。
sp:sp和dp很类似但唯一的区别是,Android系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),所以目前主流应用字体大小已经改用dp,不用sp,省去用户手动调整字体适配的麻烦。
加密解密:
package mobi.vhly.cryptodemo;
/**
* Created by vhly[FR].
* <p>
* Author: vhly[FR]
* Email: vhly@163.com
* Date: 2016/10/19
*/
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* 常用的加密算法
*/
public final class CryptUtil {
private CryptUtil(){}
///////////////////////////////////////////////////////////////////////////
// DES
///////////////////////////////////////////////////////////////////////////
/**
* DES 加密算法
* @param data 原始数据
* @param key 密码,必须是8个字节
* @return byte[] 经过加密之后的内容
*/
public static byte[] desEncrypt(byte[] data, byte[] key){
byte[] ret = null;
if (data != null && key != null) {
if(data.length > 0 && key.length == 8){
// 1. 使用 Cipher 引擎 来初始化 加密,并且设置密码
try {
Cipher cipher = Cipher.getInstance("DES");
// 1.1 DESKeySpec 用于描述DES的密码
DESKeySpec spec = new DESKeySpec(key);
// 1.2 使用 SecretKeyFactory 生成 Key对象
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey sk = factory.generateSecret(spec);
// 1.3 初始化 Cipher 为加密操作,并且指定密钥
cipher.init(Cipher.ENCRYPT_MODE, sk);
// 2. 加密数据
ret = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
return ret;
}
/**
* DES 解密算法
* @param data 原始数据
* @param key 密码,必须是8个字节
* @return byte[] 经过解密之后的内容
*/
public static byte[] desDecrypt(byte[] data, byte[] key){
byte[] ret = null;
if (data != null && key != null) {
if(data.length > 0 && key.length == 8){
// 1. 使用 Cipher 引擎 来初始化 解密,并且设置密码
try {
Cipher cipher = Cipher.getInstance("DES");
// 1.1 DESKeySpec 用于描述DES的密码
DESKeySpec spec = new DESKeySpec(key);
// 1.2 使用 SecretKeyFactory 生成 Key对象
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey sk = factory.generateSecret(spec);
// 1.3 初始化 Cipher 为解密操作,并且指定密钥
cipher.init(Cipher.DECRYPT_MODE, sk);
// 2. 解密数据
ret = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
return ret;
}
///////////////////////////////////////////////////////////////////////////
// AES 方式1
///////////////////////////////////////////////////////////////////////////
public static byte[] aesEncryptSimple(byte[] data, byte[] key){
byte[] ret = null;
if (data != null && key != null) {
if(data.length > 0 && key.length == 16){
// AES 128bit = 16bytes
try {
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
ret = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
return ret;
}
public static byte[] aesDecryptSimple(byte[] data, byte[] key){
byte[] ret = null;
if (data != null && key != null) {
if(data.length > 0 && key.length == 16){
// AES 128bit = 16bytes
try {
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
ret = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
return ret;
}
///////////////////////////////////////////////////////////////////////////
// AES 方式2 使用两套密码
///////////////////////////////////////////////////////////////////////////
/**
* 使用两套密码的加密,强度更高
* @param data 数据
* @param key 第一个密码
* @param ivData 第二个密码
* @return byte[]
*/
public static byte[] aesEncryptWithIv(byte[] data, byte[] key, byte[] ivData){
byte[] ret = null;
if (data != null && key != null && ivData != null) {
if(data.length > 0 && key.length == 16 && ivData.length == 16){
// 使用两套密码的,算法需要写成 AES/算法模式/填充模式
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 准备第一套密码
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// 准备第二套密码
IvParameterSpec iv = new IvParameterSpec(ivData);
// 设置两套密码的初始化
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
cipher.update(data);
ret = cipher.doFinal();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
return ret;
}
public static byte[] aesDecryptWithIv(byte[] data, byte[] key, byte[] ivData){
byte[] ret = null;
if (data != null && key != null && ivData != null) {
if(data.length > 0 && key.length == 16 && ivData.length == 16){
// 使用两套密码的,算法需要写成 AES/算法模式/填充模式
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 准备第一套密码
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// 准备第二套密码
IvParameterSpec iv = new IvParameterSpec(ivData);
// 设置两套密码的初始化
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
cipher.update(data);
ret = cipher.doFinal();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
return ret;
}
///////////////////////////////////////////////////////////////////////////
// RSA
///////////////////////////////////////////////////////////////////////////
// 1. 生成密钥对 公钥和私钥
/**
*
* @param bits 必须在 1024,2048
* @return
*/
public static KeyPair generateRsaKey(int bits){
KeyPair ret = null;
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(bits);
ret = kpg.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return ret;
}
/**
* RSA加密,使用公钥加密,那么必须使用私钥解密
* 使用私钥机密,那么必须使用公钥解密
* @param data
* @param key
* @return
*/
public static byte[] rsaEncrypt(byte[] data, Key key){
byte[] ret = null;
if (data != null && data.length > 0 && key != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
ret = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
return ret;
}
public static byte[] rsaDecrypt(byte[] data, Key key){
byte[] ret = null;
if (data != null && data.length > 0 && key != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
ret = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
return ret;
}
}