SpUtil多样加密存储,兼容android9.0
立即下载
金额: 4 元
支付方式:
友情提醒:源码购买后不支持退换货
立即支付
发布时间:2019-03-09
技术:android+sharepreferences
概述
在android系统不断升级的过程中,Sharepreferences存储出现多中问题,其中有些是读写权限造成,有些是因为加密问题引起。下面介绍下SpUtil这个工具类,它是在Sharepreferences基础上进行了封装优化,具备存储不同数据类型,然后有加密功能,使用简单,在介绍的工程中,还会涉及到一些权限方面的讲解。
存储数据类型包括:
boolean、int、float、long、String,List,object
使用简单便捷
详细
####前言
在android系统不断升级的过程中,Sharepreferences存储出现多中问题,其中有些是读写权限造成,有些是因为加密问题引起。下面介绍下SpUtil这个工具类,它是在Sharepreferences基础上进行了封装优化,具备存储不同数据类型,然后有加密功能,使用简单,在介绍的工程中,还会涉及到一些权限方面的讲解。
存储数据类型包括:
boolean、int、float、long、String,List,object,其中 存储 String 具备加密功能,在存储 object的时候,object 需要是可序列化的对象
今天涉及的内容有:
1. 读写权限及安装权限差异
2. 加密差异
3. SpUtil 的基本使用
4. 具体调用代码
5. 项目结构图和效果图
#####一. 读写权限及安装权限差异
######android 6.0以下
在android6.0 以前,我们在设置读写权限的时候,需要在android mainfast.xml中做权限申请:
```
```
######android 6.0开始
在android6.0以后,读写权限增加了动态申请,于是需要用到android动态权限申请,网上这方面知识很多,大家可以搜搜,这里就不详细讲解了。
######android 7.0开始
然后到了android7.0增加了 FileProvider 文件权限限制,需要在 mainfast 的配置文件中加入FileProvider注册:
```
```
然后在 res文件夹下建 xml文件 updat_files.xml(文件名自己定义,但是要与上面provider中的 meta-data 标签对应的 resource引用一致)
updat_files.xml文件代码如下:
```
```
要是项目涉及到自动下载安装的时候,则自动安装代码要改成类似下面这样:
```
/**
* 安装软件
*
* @param file
*/
private void installApk(File file) {
if (!file.exists()) {
return;
}
Uri uri = null;
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// UpdateConfig.FILE_PROVIDER_AUTH 即是在清单文件中配置的authorities
uri = FileProvider.getUriForFile(mContext, AUTHORITY_TAG, file);
// 给目标应用一个临时授权
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(file);
}
install.setDataAndType(uri, "application/vnd.android.package-archive");
mContext.startActivity(install);
}
```
其中FileProvider.getUriForFile(mContext, AUTHORITY_TAG, file);中的 AUTHORITY_TAG 即为 provider 注册中的 android:authorities 值。
######android 8.0开始
此版本开始后,增加了安装未知权限的限制,于是需要在 mainfast.xml中添加安装未知应用的权限:
```
```
#####二. 加密差异
######android 7.0 开始
android7.0之后的加密会出现问题,解决办法的话,之前我已经讲过,大家可以参考我的文章 [android-N在AES加密时出现:no such provider: Crypto 的问题](https://www.jianshu.com/p/b854e97fb856)
######android 9.0 开始
然而在android9.0出来后,加密这块仍然不消停,加密机制切换,导致获取秘钥数组的方式改变,主要是加密byte数组的获取,以及涉及加密类InsecureSHA1PRNGKeyDerivator,具体的大家可以看demo中代码
#####三. SpUtil 的基本使用
前面都讲过,下面就具体到 SpUtil 工具类的使用了。
SpUtil作为Sharepreferences的超级封装类,具备存储boolean、int、float、long、String,List及可序列化object功能,其中String还具备加密存储功能。SpUtil涉及到Gson,若你项目中引用了Retrofit,则无需另外引用gson,若需要单独引用gson,你需要在 项目的 gradle中添加gson引用:
```
//gson
implementation 'com.google.code.gson:gson:2.8.5'
```
######1.SpUtil存储涉及加密模块,故在使用SpUtil的任何存取方法前(最好在项目的Appliction中)设置秘钥
```
//设置秘钥,秘钥mak为16位数字字母组合的字符串
SpUtil.setMAK(String mak);
```
###### 2.存储String,int,boolean,float,long数据类型
```
//存储 当数据类型为String,int,boolean,float,long中任何一种的时候,put方法具备自动转型功能
SpUtil.put(String key, Object object);
```
###### 3.存储对象,对象需要实现Serializable接口
```
putObject(String key, Object object);
```
###### 4.获取对象,对象需要实现Serializable接口
```
getObject(String key)
```
###### 5.将复杂对象转换成json数据储存,需要配合gson使用
```
putJsonObject(String key, Object obj)
```
###### 6.取JsonObject,需要配合gson使用
```
getJsonObject(String key)
```
###### 7.取String,默认取null
```
getString(String key)
```
###### 8.取int,默认取number
```
getInt(String key,int number)
```
###### 9.取int,默认取0
```
getInt(String key)
```
###### 10.取float,默认取number
```
getFloat(String key,float number)
```
###### 11.取float,默认取0
```
getFloat(String key)
```
###### 12.取long,默认取number
```
getLong(String key,long number)
```
###### 13.取long,默认取0
```
getLong(String key)
```
###### 14.取boolean,默认取flag
```
getBoolean(String key,boolean flag)
```
###### 15.取boolean,默认取false
```
getBoolean(String key)
```
###### 16.存list
```
putList(String keyName, List> list)
```
###### 17.取list
```
getList(String key);
```
###### 18.移除某个key对应的value
```
removeKey(String key)
```
###### 19.清除所有数据
```
clear()
```
###### 20.查询某个key是否已经存在
```
contains(String key)
```
#####四.具体调用代码
下面贴出SpUtil在Mainactivity中调用的主要代码:
```
//存储boolean
SpUtil.put("a", true);
boolean a=SpUtil.getBoolean("a");
mTvBoolean.setText("存储布尔:"+a);
//存储int
SpUtil.put("b",10);
int b=SpUtil.getInt("b");
mTvInt.setText("存储int:"+b);
//存储float
SpUtil.put("c",10f);
float c=SpUtil.getFloat("c");
mTvFloat.setText("存储float:"+c);
//存储long
SpUtil.put("d",10L);
long d=SpUtil.getLong("d");
mTvLong.setText("存储long:"+d);
//存储String
SpUtil.put("e", "KFC");
String e = SpUtil.getString("e");
mTvString.setText("存储String:"+e);
//存储list
Listlist=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
SpUtil.putList("f",list);
Listlist2= (List) SpUtil.getList("f");
StringBuffer buffer=new StringBuffer();
for (int i = 0; i < list2.size(); i++) {
buffer.append(list2.get(i));
}
mTvList.setText("存储list:"+buffer.toString());
//存储对象
People people=new People();
people.setName("小明");
people.setAge(13);
SpUtil.putObject("g",people);
People p= (People) SpUtil.getObject("g");
mTvObj.setText("姓名:"+p.getName()+" 年龄:"+p.getAge());
```
#####五.项目结构图和效果图
项目结构图
![image.png](/contentImages/image/jianshu/6127340-2604acdadc21fa4e.png)
效果图
![image.png](/contentImages/image/jianshu/6127340-39077b29a3259393.png)