代码地址如下:
http://www.demodashi.com/demo/15058.html

前言

在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中做权限申请:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
android 6.0开始

在android6.0以后,读写权限增加了动态申请,于是需要用到android动态权限申请,网上这方面知识很多,大家可以搜搜,这里就不详细讲解了。

android 7.0开始

然后到了android7.0增加了 FileProvider 文件权限限制,需要在 mainfast 的配置文件中加入FileProvider注册:

        <provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/update_files" />
</provider>

然后在 res文件夹下建 xml文件 updat_files.xml(文件名自己定义,但是要与上面provider中的 meta-data 标签对应的 resource引用一致)

updat_files.xml文件代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="" name="download"/>
</paths>
</resources>

要是项目涉及到自动下载安装的时候,则自动安装代码要改成类似下面这样:

    /**
* 安装软件
*
* @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中添加安装未知应用的权限:

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
二. 加密差异
android 7.0 开始

android7.0之后的加密会出现问题,解决办法的话,之前我已经讲过,大家可以参考我的文章 android-N在AES加密时出现:no such provider: Crypto 的问题

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
List<String>list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
SpUtil.putList("f",list);
List<String>list2= (List<String>) 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());
五.项目结构图和效果图

项目结构图



效果图

SpUtil多样加密存储,兼容android9.0

代码地址如下:
http://www.demodashi.com/demo/15058.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

SpUtil多样加密存储,兼容android9.0的更多相关文章

  1. 使用BCrypt算法加密存储登录密码用法及好处

    //导入import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** *使用BCrypt算法加密存储登录密码 ...

  2. Spring Security笔记:使用BCrypt算法加密存储登录密码

    在前一节使用数据库进行用户认证(form login using database)里,我们学习了如何把“登录帐号.密码”存储在db中,但是密码都是明文存储的,显然不太讲究.这一节将学习如何使用spr ...

  3. Localstorage本地存储兼容函数

    前言HTML5提供了本地存储的API:localstorage对象和sessionStorage对象,实现将数据存储到用户的电脑上.Web存储易于使用.支持大容量(但非无限量)数据同时存储,同时兼容当 ...

  4. Mongodb数据库加密存储(python)

     需求: 不知道大家有没有遇到过这样的需求:自己的服务器出于对数据库安全的保护,需要对存储的数据进行加密保护.这样万一数据库被人拿到,别人也不能拿到数据库里面的内容.这里还有一个前提:前端的展示页面是 ...

  5. tomcat安全配置之证书密码加密存储

    最近项目组要完成一个新Web Servicer接口的开发,其中有项要求是支持外部客户程序以https方式访问这些SOAP接口.项目组当前基于tomcat6.0.29开发,axis版本为1.4.拿到这个 ...

  6. 在IOS中使用DES算法对Sqlite数据库进行内容加密存储并读取解密

    在IOS中使用DES算法对Sqlite 数据库进行内容加密存储并读取解密 涉及知识点: 1.DES加密算法: 2.OC对Sqlite数据库的读写: 3.IOS APP文件存储的两种方式及读取方式. 以 ...

  7. Android9.0新特性曝光,你准备好了吗

    Android9.0最早出现在2018年1月25日的谷歌官网上,初步代号已经确定为“Pistachio Ice Cream”(开心果冰淇淋),不过按照Google的惯例,如此长的三个单词代号,通常都只 ...

  8. DES ECB 模式 JAVA PHP C# 实现 加密 解密 兼容

    版本一: JAVA: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sun.misc.BASE64Decoder; i ...

  9. 【原】webapp开发中兼容Android4.0以下版本的css hack

    话说现在的手机型号越来越多,主要还是android和ios这2个巨头称霸了江湖,而他们自带的浏览器内核是webkit,那对于做移动网页开发的同事来说,一般只要做好webkit内核浏览器的展现效果就行了 ...

随机推荐

  1. js扩展运算符(spread)是三个点(...)

    作用:将一个数组转为用逗号分隔的参数序列. //该运算符主要用于函数调用.function push(array, ...items) { array.push(...items); } functi ...

  2. Django项目中使用Redis

    Django项目中使用Redis DjangoRedis 1 redis Redis 是一个 key-value 存储系统,常用于缓存的存储.django-redis 基于 BSD 许可, 是一个使 ...

  3. linux 进阶命令

    进阶命令 1    df指令   查看磁盘的空间 # df -h    -h表示可读性更高,方便读取 执行指令后(Filesystem:磁盘名称  size:磁盘总大小  Used: 被使用的大小  ...

  4. C#-常用知识点

    1.日期相关 获取英文月份名称 : DateTime.Now.ToString("MMMM") 1.1 各个字母所代表的意思 1.MM:月份 2.mm:分钟 3. MMMM:文字形 ...

  5. YOLO系列:YOLO v3解析

    本文好多内容转载自 https://blog.csdn.net/leviopku/article/details/82660381 yolo_v3 提供替换backbone.要想性能牛叉,backbo ...

  6. BZOJ.1568.[JSOI2008]Blue Mary开公司(李超线段树)

    题目链接 线段树每个节点记录\(f(mid)\)最大的直线(在\(mid\)处函数值最大的直线),称作优势线段(还是直线啊...无所谓了). 如果是在区间插入线段会影响\(O(\log n)\)个区间 ...

  7. Scrapy基础(八)————图片下载后将本地路径添加到Item中

    前边讲到简单的图片下载,但是怎样将图片的本地路径和存储在Item中的数据对应起来,所以本篇博文讲解到如何将 本地的下载后的图片路径写入到Item中 思路:自定义pipline,多加个管道,该管道继承下 ...

  8. (数据存储)Android系统存储数据

    移动设备需要存储数据,处理数据并输出处理后的信息. 主题一:存储键值对 If you have a relatively small collection of key-values that you ...

  9. BZOJ4912 : [Sdoi2017]天才黑客

    建立新图,原图中每条边在新图中是点,点权为$w_i$,边权为两个字符串的LCP. 对字典树进行DFS,将每个点周围一圈边对应的字符串按DFS序从小到大排序. 根据后缀数组利用height数组求LCP的 ...

  10. pythonweb服务器编程(四)

    Web动态服务器-1 #coding=utf-8 import socket import sys from multiprocessing import Process import re clas ...