假设使用默认的系统管理,默认放在包以下。比較省心。并且在卸载app后不会造成数据残留。可是这样也有一个问题。比方我做一个背单词的软件,那么当用户卸载掉这个app时,他辛辛苦苦下载的单词库也没了...

所以我想到的解决方式。就是把数据库路径改下。不放到包以下,放到SD卡上。

细致看看。还真不easy做,网上有人甚至去更改源代码。只是最后还是找到了解决方式:

查看SQLiteOpenHelper源代码。会发现有这样一段代码:

 if (mName == null) {
db = SQLiteDatabase.create(null);
}
else {
db = mContext.openOrCreateDatabase(mName, 0, mFactory);
}

能够看到,当mName非空的时候。由mContext进行完毕创建和打开。而这个mContext能够通过构造函数传入。

看下sqlliteOpenhelper这个实现类:

package cn.com.xx.xx.util;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; /**
* DataBase helper class
* @author howlaa
* @date 2015-1-5 14:38:28
*/
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String DBNAME = "test.db";
private static final int VERSION = 11;
public DBOpenHelper(Context context) {
super(context, DBNAME, null, VERSION);//it's location is data/data/pakage/database
} @Override
public void onCreate(SQLiteDatabase db) {//It will be called when the database was created first
db.execSQL("CREATE TABLE IF NOT EXISTS exam_type (id integer primary key autoincrement, type_name varchar(100), type_id INTEGER)"); } @Override // It'll be called when the database was updated
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
}

剩下的就要完毕这个mContext的实现了:

package cn.com.smartcost.scexam.util;

import java.io.File;
import java.io.IOException; import android.content.Context;
import android.content.ContextWrapper;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log; /**
* 用于支持对存储在SD卡上的数据库的訪问
**/
public class DatabaseContext extends ContextWrapper { /**
* 构造函数
* @param base 上下文环境
*/
public DatabaseContext(Context base){
super(base);
} /**
* 获得数据库路径,假设不存在,则创建对象对象
* @param name
* @param mode
* @param factory
*/
@Override
public File getDatabasePath(String name) {
//推断是否存在sd卡
boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState());
if(!sdExist){//假设不存在,
Log.e("SD卡管理:", "SD卡不存在。请载入SD卡");
return null;
}
else{//假设存在
//获取sd卡路径
String dbDir=android.os.Environment.getExternalStorageDirectory().toString();
dbDir += "/scexam";//数据库所在文件夹
String dbPath = dbDir+"/"+name;//数据库路径
//推断文件夹是否存在,不存在则创建该文件夹
File dirFile = new File(dbDir);
if(!dirFile.exists())
dirFile.mkdirs(); //数据库文件是否创建成功
boolean isFileCreateSuccess = false;
//推断文件是否存在,不存在则创建该文件
File dbFile = new File(dbPath);
if(!dbFile.exists()){
try {
isFileCreateSuccess = dbFile.createNewFile();//创建文件
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
isFileCreateSuccess = true; //返回数据库文件对象
if(isFileCreateSuccess)
return dbFile;
else
return null;
}
} /**
* 重载这种方法,是用来打开SD卡上的数据库的。android 2.3及下面会调用这种方法。
*
* @param name
* @param mode
* @param factory
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
SQLiteDatabase.CursorFactory factory) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
return result;
} /**
* Android 4.0会调用此方法获取数据库。
*
* @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String, int,
* android.database.sqlite.SQLiteDatabase.CursorFactory,
* android.database.DatabaseErrorHandler)
* @param name
* @param mode
* @param factory
* @param errorHandler
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
DatabaseErrorHandler errorHandler) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
return result;
}
}

使用:

DatabaseContext dbContext = new DatabaseContext(this);
SdCardDBHelper dbHelper = new SdCardDBHelper(dbContext);

最后不要忘记,加上读写SD卡的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

Android使用sqlliteOpenhelper更改数据库的存储路径放到SD卡上的更多相关文章

  1. android 使用相机拍照,并存储到手机sd卡上,并利用系统录像录像并播放

    //首先声明一个成员变量 String savePath,用来储存文件路径 /** * 保存照片路径 * @return 返回图片的一个文件 * @throws IOException 抛出一个异常 ...

  2. Android中的GreenDao框架修改数据库的存储路径

    目前android中比较热门的数据库框架有greenDAO.OrmLite.AndrORM,其中我比较喜欢用GreenDao,其运行效率最高,内存消耗最少,性能最佳.具体怎么使用GreenDao,网上 ...

  3. MYSQL 更改数据库data存储目录 创建用户 创建权限 设置远程访问的权限.

    一. 怎么更改数据库data存储目录:  1. 安装MYSQL. 2. 切换到 C:\Program Files\MySQL\MySQL Server 5.6 3. 新建my.ini. 加入如下配置: ...

  4. 【VMware】VMware的安装和更改虚拟机默认存储路径

    1.VMware Workstation 14中文破解版安装 网盘下载链接:https://pan.baidu.com/s/1pbDXpgpNQTdTRzzKNWfE1A linux镜像(CentOS ...

  5. Android 自定义Android ORM 框架greenDAO数据库文件的路径

    import android.content.Context; import android.content.ContextWrapper; import android.database.Datab ...

  6. 【Android】14.0 第14章 内部存储与外部SD卡存储—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 Android使用的文件系统是基于Linux的文件系统,在Android应用程序中,开发人员既可以建立和访问程序自 ...

  7. Android HTTP下载文件并保存到本地或SD卡

    想把文件保存到SD卡中,一定要知道SD卡的路径,获取SD卡路径: Environment.getExternalStorageDirectory() 另外,在保存之前要判断SD卡是否已经安装好,并且可 ...

  8. android学习笔记47——读写SD卡上的文件

    读写SD卡上的文件 通过Context的openFileInput.openFileOutput来打开文件输入流.输出流时,程序打开的都是应用程序的数据文件夹里的文件,其存储的文件大小可能都比较有限- ...

  9. Android开发之SD卡上文件操作

    1. 得到存储设备的目录:/SDCARD(一般情况下) SDPATH=Environment.getExternalStorageDirectory()+"/"; 2. 判断SD卡 ...

随机推荐

  1. Java易错知识点(1) - 关于ArrayList移除元素后剩下的元素会立即重排

    帮一个网友解答问题时,发现这样一个易错知识点,现总结如下: 1.易错点: ArrayList移除元素后,剩下的元素会立即重排,他的 size() 也会立即减小,在循环过程中容易出错.(拓展:延伸到所有 ...

  2. (四)mysql数据类型

    数据类型基本介绍 数值类型 整形类型:tinyint,int,bigint 浮点类型:float,double 字符串类型 char系列:char varchar text系列:text blob系列 ...

  3. HDU 6336.Problem E. Matrix from Arrays-子矩阵求和+规律+二维前缀和 (2018 Multi-University Training Contest 4 1005)

    6336.Problem E. Matrix from Arrays 不想解释了,直接官方题解: 队友写了博客,我是水的他的代码 ------>HDU 6336 子矩阵求和 至于为什么是4倍的, ...

  4. (24)python 无线破解

    import pywifi import time wifi = pywifi.PyWiFi() # iface = wifi.interfaces()[0]#获取第一块网卡 #print(iface ...

  5. Vim求生

    [TOC] Vim 是从 vi 发展出来的一个文本编辑器.其代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用.和 Emacs 并列成为类 Unix 系统用户最喜欢的编辑器. —— ...

  6. Encode and Decode Strings -- LeetCode

    Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...

  7. 【树链剖分】【线段树】bzoj2157 旅游

    #include<cstdio> #include<algorithm> using namespace std; #define INF 2147483647 #define ...

  8. 【博弈论】【SG函数】poj2311 Cutting Game

    由于异或运算满足结合律,我们把当前状态的SG函数定义为 它所能切割成的所有纸片对的两两异或和之外的最小非负整数. #include<cstdio> #include<set> ...

  9. 【模拟】洛谷 P1328 NOIP2014提高组 day1 T1 生活大爆炸版石头剪刀布

    把所有情况打表,然后随便暴力. #include<cstdio> using namespace std; int n,an,bn,p1,p2; ],b[]; ][]; int ans1, ...

  10. Java高级架构师(一)第18节:X-gen所需service、web层模板

    以X-gen的Controller为例: package $#modulePackge#.web; import org.springframework.beans.factory.annotatio ...