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

代码地址以下:
http://www.demodashi.com/demo/15058.htmlhtml

前言

在android系统不断升级的过程当中,Sharepreferences存储出现多中问题,其中有些是读写权限形成,有些是由于加密问题引发。下面介绍下SpUtil这个工具类,它是在Sharepreferences基础上进行了封装优化,具有存储不一样数据类型,而后有加密功能,使用简单,在介绍的工程中,还会涉及到一些权限方面的讲解。
存储数据类型包括:
boolean、int、float、long、String,List,object,其中 存储 String 具有加密功能,在存储 object的时候,object 须要是可序列化的对象android

今天涉及的内容有:json

  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动态权限申请,网上这方面知识不少,你们能够搜搜,这里就不详细讲解了。app

android 7.0开始

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

<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>

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

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

<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());
五.项目结构图和效果图

项目结构图
image.png
效果图
image.pngSpUtil多样加密存储,兼容android9.0

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

注:本文著做权归做者,由demo大师代发,拒绝转载,转载须要做者受权