SpUtil多樣加密存儲,兼容android9.0


代碼地址如下:
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());
五.項目結構圖和效果圖

項目結構圖
image.png
效果圖
image.pngSpUtil多樣加密存儲,兼容android9.0

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

注:本文著作權歸作者,由demo大師代發,拒絕轉載,轉載需要作者授權


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM