利用SQLChiper对Android SQLite数据库加密
前言: 上篇文章讲了Android studio+SQLCipher加密SQLite数据库的几个坑,跳过这几个坑,那么SQLCipher的前提就处理完成,本片文章接着讲如何使用SQLCiper加密数据库。

一、与SQLite的使用相似先继承SQLiteOpenHelper,实现其中的OnCreate和onUpgrade两个抽象方法,同时必须super其中至少一个构造函数。代码如下:

package com.tuoqun.Tool;import android.content.Context;
import android.util.Log;import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;public class DBCipherHelper extends SQLiteOpenHelper {private static final String TAG = "DatabaseHelper";public static String DB_NAME;//数据库名字public static String DB_PWD;//数据库密码public static int DB_VERSION;   // 数据库版本//private String createTableSQL="";//创建数据库表的SQL语句(eg: "CREATE TABLE TABLE_NAME(FIELD_ID integer primary key autoincrement , FIELD_NAME text not null);")public DBCipherHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);//不可忽略的,进行so库加载;这个千万别忘记调用!!!!SQLiteDatabase.loadLibs(context);Log.e(TAG, "CreateDB:---------------"+name+"---------------Success");}public DBCipherHelper(Context context) {this(context, DB_NAME, null, DB_VERSION);}@Overridepublic void onCreate(SQLiteDatabase sqLiteDatabase) {//createTable(sqLiteDatabase);}@Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {onCreate(sqLiteDatabase);}
}

注意,参照多篇文章,他们都是在OnCreate实现中创建数据表,但是,我觉得这种方法创建表有时候不太灵验,而且不利于多张表的创建。因此,我并未在OnCreate实现中创建表,我把创建表的方法单独拿出去,何时需要创建表,何时创建,这样会比较灵活。

二、创建数据库管理类,用来管理数据库表的创建,以及表数据的增删改查,代码如下:

package com.tuoqun.Tool;import android.content.ContentValues;
import android.content.Context;
import android.util.Log;import net.sqlcipher.Cursor;
import net.sqlcipher.SQLException;
import net.sqlcipher.database.SQLiteDatabase;import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;public class DBCipherManager {private static final String TAG = "DatabaseManager";// 静态引用private volatile static DBCipherManager mInstance;//volatile关键字会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值(参考https://www.cnblogs.com/dolphin0520/p/3920373.html)。// DatabaseHelperprivate DBCipherHelper dbHelper;private DBCipherManager(Context context) {dbHelper = new DBCipherHelper(context);}/*** 获取单例引用** @param context* @return*/public static DBCipherManager getInstance(Context context) {DBCipherManager inst = mInstance;//Java 中的双重检查(Double-Check)if (inst == null) {synchronized (DBCipherManager.class) {inst = mInstance;if (inst == null) {inst = new DBCipherManager(context);mInstance = inst;}}}return inst;}/*** 插入数据* @param tableName 待插入数据表的表名* @param contentValues 要修改或者插入的键值对(表中字段名,对应值)eg:ContentValues values=new ContentValues();*                                                                   values.put("fieldname","fieldValue");*/public void insertData(String tableName,ContentValues contentValues) {//获取写数据库SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);// insert 操作db.insert(tableName, null, contentValues);//关闭数据库db.close();}/*** 未开启事务批量插入* @param tableName 待插入数据表的表名* @param contentValuesList 要修改或者插入的键值对列表*/public void insertDatasByNomarl(String tableName, List<ContentValues> contentValuesList){//获取写数据库SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);for(int i =0;i<contentValuesList.size();i++ ){// insert 操作db.insert(tableName, null, contentValuesList.get(i));Log.e(TAG, "insertDatasByNomarl");}//关闭数据库db.close();}/*** 开启事务批量插入* @param tableName 待插入数据表的表名* @param contentValuesList 要修改或者插入的键值对列表*/public void insertDatasByTransaction(String tableName, List<ContentValues> contentValuesList){//获取写数据库SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);db.beginTransaction();  //手动设置开始事务try{//批量处理操作for(int i =0;i<contentValuesList.size();i++ ){// insert 操作db.insert(tableName, null, contentValuesList.get(i));Log.e(TAG, "insertDatasByTransaction");}db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交}catch(Exception e){}finally{db.endTransaction(); //处理完成//关闭数据库db.close();}}/*** 删除数据* @param tableName 待删除数据表的表名* @param whereClause 删除数据条件语句 eg: StringBuffer whereBuffer = new StringBuffer();* whereBuffer.append(DBCipherHelper.FIELD_NAME).append(" = ").append("'").append(name).append("'");*/public void deleteData(String tableName,StringBuffer whereClause) {//获取写数据库SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);// delete 操作db.delete(tableName, whereClause.toString(), null);//关闭数据库db.close();}/*** 删除所有数据* @param tableName 待删除数据表的表名*/public void deleteDataAll(String tableName){String sql="delete from "+ tableName;//可以在不删除表的情况下删除所有的行execSQL(sql);}/*** 更新数据* @param tableName 待更新数据表的表名* @param whereClause 更新数据条件语句* @param newValue 更新数据的新值*/public void updateData(String tableName,StringBuffer whereClause,ContentValues newValue) {//获取写数据库SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);// update 操作db.update(tableName, newValue, whereClause.toString(), null);//关闭数据库db.close();}/*** 指定条件查询数据* @param tableName 待查询数据表的表名* @param whereClause 查询条件(if whereClause=null,则为查询所有数据 )* @param queryColumns 查询列 eg: String[] queryColumns = {fieldName};* @return <列名,列值>*/public List<Map<String,String>> queryDatas(String tableName,StringBuffer whereClause,String[] queryColumns){List<Map<String,String>> queryResultList=new ArrayList<>();Map<String,String> queryResult;String columName="";String  columValue="";//获取可读数据库SQLiteDatabase db = dbHelper.getReadableDatabase(DBCipherHelper.DB_PWD);//查询数据库Cursor cursor;try {if (whereClause==null)cursor = db.query(tableName, queryColumns,null, null, null, null, null);elsecursor = db.query(tableName, queryColumns, whereClause.toString(), null, null, null, null);while (cursor.moveToNext()) {queryResult=new LinkedHashMap<>();int count = cursor.getColumnCount();for (int i=0;i<count;i++){columName = cursor.getColumnName(i);columValue = cursor.getString(i);queryResult.put(columName,columValue);}queryResultList.add(queryResult);//Log.e(TAG, "count = " + count + " columName = " + columName + "  name =  " +tname);}//关闭游标防止内存泄漏if (cursor != null) {cursor.close();}} catch (SQLException e) {Log.e(TAG, "queryDatas" + e.toString());}//关闭数据库db.close();return queryResultList;}/*** 执行sql语句*/public void execSQL(String sql){//获取写数据库SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);//直接执行sql语句db.execSQL(sql);//或者//关闭数据库db.close();}
}

三、对上面管理类的使用方法,示例代码如下:

//建立Sqlite数据库所需
DBCipherHelper.DB_NAME="testDB";
DBCipherHelper.DB_PWD="shy";
DBCipherHelper.DB_VERSION=1;//创建表所需
String tableName="proofPhotoInfo";
String createTableSQL="CREATE TABLE "+tableName+"(ID integer primary key autoincrement,layerName text not null,picName text not null,azimuth text,pitch text,roll text,longitude text not null,latitude text not null);";//在SQLite数据库中创建表SQL语句(该表用于存储该类中信息)//1、建库和建表try {DBCipherManager.getInstance(context).execSQL(createTableSQL);//建库和建表} catch (Exception e) {e.printStackTrace();}
//2、插入数据
ContentValues photoInfo=new ContentValues();
photoInfo.put("layerName",CameraClass.layerDirName);
photoInfo.put("picName",basicDOClass.getFileName(CameraClass.currenImgFilePath));
photoInfo.put("azimuth",SensorEx.azimuth+"");
photoInfo.put("pitch",SensorEx.pitch+"");
photoInfo.put("roll",SensorEx.roll+"");
photoInfo.put("longitude",SensorEx.longitude+"");
photoInfo.put("latitude",SensorEx.latitude+"");
DBCipherManager.getInstance(context).insertData(tableName,photoInfo);//插入数据//3、查询数据
StringBuffer querySQLWhere=new StringBuffer();
String layerName=basicDOClass.getDirName(basicDOClass.getFilePath(photoPath));
String picName=basicDOClass.getFileName(photoPath);
querySQLWhere.append("layerName").append("=").append("'").append(layerName).append("'").append(" and ").append("picName").append("=").append("'").append(picName).append("'");
queryPhotoInfoResult=DBCipherManager.getInstance(context).queryDatas(tableName,querySQLWhere,new String[]{"ID","layerName","picName","azimuth","pitch","roll","longitude","latitude"});//查询数据

利用SQLChiper对Android SQLite数据库加密相关推荐

  1. android sqlite数据库加密,(转)SQLite数据库的加密

    1.创建空的SQLite数据库. //数据库名的后缀你可以直接指定,甚至没有后缀都可以 //方法一:创建一个空sqlite数据库,用IO的方式 FileStream fs = File.Create( ...

  2. android sqlite加密数据库,Android Sqlite数据库加密

    Android使用的是开源的SQLite数据库,数据库本身没有加密,加密思路通常有两个: 1. 对几个关键的字段使用加密算法,再存入数据库 2. 对整个数据库进行加密 SQLite数据库加密工具: 收 ...

  3. Android SQLite数据库版本升级(分逐级升级和跨版本升级)

    参考:Android Sqlite数据库跨版本升级 保存之前数据 本文说的数据库升级是基于Android原生APISQLiteOpenHelper实现的逻辑,不涉及第三方库.其实如果使用官方推荐的Ro ...

  4. android 数据库表格数据库数据库中,Android SQLite数据库中的表详解

    Android SQLite数据库 前言 以前写PHP的时候,内置了print_r()和var_dump()两个函数用于打印输出任意类型的数据内部结构,现在做Android的开发,发现并没有这种类似的 ...

  5. android SQLite数据库的使用

    今天,简单讲讲android如何使用SQLite数据库.  最近,自己在做一个功能时又用到了SQLite数据库,发现自己还是掌握的不很全面.其实之前的app里面也一直用到了数据库,但是自己没有花时 ...

  6. Android SQLite 数据库详细介绍

    Android SQLite 数据库详细介绍我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软 ...

  7. android 获取位置数据库,尝试从webview获取位置时,Android“SQLite数据库无法从/CachedGeoposition.db加载”错误...

    我正在创建一个使用webkit和chrome客户端的android应用程序.我希望能够在网页请求时获取当前位置.我设置的网页适用于普通浏览器就好了.然而,当我尝试访问该网页WebKit中,我不断收到此 ...

  8. Android SQLite数据库导出/导入Excel

    Android SQLite数据库导出/导入Excel 前言 框架 使用方法 添加依赖 声明权限 导出数据库到Excel 声明实例 配置导出内容 导出监听 导入Excel到数据库 声明实例 导入监听 ...

  9. Android Sqlite数据库多表联合查询

    Android Sqlite数据库多表联合查询示例 工作上用数据库存储文件还是很便利的,所以有时候发现一张表存储数据感觉数据结构不是很清晰的时候,就需要新加第二张表或者多张表来进行联合查询对象信,一般 ...

最新文章

  1. 11. Leetcode 713. 乘积小于K的子数组 (数组-同向双指针-滑动窗口)
  2. 【Python】反转列表 list 的几种方法
  3. keras神经网络模型的保存与加载
  4. c语言课程设计加密程序,C语言课程设计文件加密解密.doc
  5. c语言以顺序结构存储的二叉树的非递归遍历,C语言二叉树的非递归遍历实例分析...
  6. userdel删除用户失败提示:userdel: user * is currently logged in 解决方法
  7. 人事管理系统为你解剖JSP
  8. python环境变量设置失败
  9. linux能虚拟化windows,在Linux和Windows下查看CPU是否支持虚拟化的方法
  10. 低频时码授时技术与中国电波钟表发展历程简介
  11. VelocityTracker使用总结
  12. GEE实战3:利用GEE获取区域的长系列日均气温变化【逐日气温变化分析】
  13. springboot项目结构_从零搭建Spring Boot脚手架(1):开篇以及技术选型
  14. pythonarp工具_Python 实现ARP扫描欺骗工具
  15. 7. 模糊操作/原理/API/种类/边缘保留
  16. 外卖返利系统外卖返利公众号外卖返利源码
  17. eclipse 解决 java.lang.NoClassDefFoundError: ilog/concert/IloException
  18. 实现textarea不自动换行
  19. 荣耀8开屏锁显示无法连接服务器,华为荣耀8解锁教程 华为荣耀8如何解锁
  20. Aras Innovator Method集成Visual Studio

热门文章

  1. python怎么输入程序代码_学习用 Thonny 写代码: 一个面向初学者的Python IDE
  2. 机器学习-分类算法-K-近邻算法06
  3. ceph osd跟cpu进行绑定
  4. vscode去除控制台ES6报错
  5. ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步
  6. Microsoft Fluent Design System
  7. 从菜鸟成为数据科学家的养成方案
  8. 对于java反射的理解
  9. 一仅仅小蜜蜂(杭电2044)
  10. Resharper 的快捷键