android 如何实现附加现有数据库?而不是每次安装的时候都创建新的数据库。
最近做一个应用,在数据库中要内置很多数据,但有不想在每次安装的时候都重新创建数据库并插入数据,原因是插入数据时间较长,用户体验不好,所以特地想问问大家,有没有什么办法,让我一次吧数据库的内容都填充好,再以后的安装过程中不用再重新创建数据库了,类似sqlserver中的附加数据库!
最近做一个应用,在数据库中要内置很多数据,但有不想在每次安装的时候都重新创建数据库并插入数据,原因是插入数据时间较长,用户体验不好,所以特地想问问大家,有没有什么办法,让我一次吧数据库的内容都填充好,再以后的安装过程中不用再重新创建数据库了,类似sqlserver中的附加数据库!
解决方案 »
- 录像时调用MediaRecorder的start()时发生start failed: -19错误
- 关于android一个程序运行时出现的错误:
- android连接ftp服务器
- android的事件处理
- 做Hello案例的时候,要Create an AVD,我双击android.bat出来的dos窗口加图形化设置AVD的界面
- android 源码
- 关于TabHost问题
- 准备编译适配CM9 device的适配问题 大神帮忙
- 怎么在listview中清除原数据
- eclipse用集成SDK报错,运行项目闪退
- 参考Android下的系统级服务AlarmManagerService,自己加一个类似服务,系统老是不断重启!
- 怎么为一个学校教务信息网站做一个手机(先选android)客户端?
public DataBase(Context context) {
// 创建一个名为realcode_tes的数据库
super(context, "realcode_tes", null,3);
}3这个参数指的是数据库的版本,你下次安装如果你的新程序还是3则不会再创建数据库,会保留你之前的数据而覆盖安装是指在文件管理里面的安装才能实现,通过其他方式安装好像都是卸载后重新安装
哦,你的意思是不是说,把数据库文件直接打包到apk中,然后程序里就不创建了,直接去读取这个数据库文件?
如果是这样,那可以把数据库文件xx.db,放在assets目录,程序中访问:
AssetManager am = context.getAssets();
InputStream is = am.open(fileName);
SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFilename, null); //打开数据库
databaseFilename="/sdcard/crazynovel/crazynovel.db" //这是路径在数据库类中的open中打开现有数据库
。
private class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
...
}
public DbControl open() throws SQLException
{
// mDbHelper = new DatabaseHelper(mCtx);
// db = mDbHelper.getWritableDatabase();
copyDb co = new copyDb(mCtx);
db = co.openDatabase(); //这里是打开数据库的方法调用,现在没法调用getWritableDatabase();方法了}
databaseFilename="/sdcard/crazynovel/crazynovel.db" //这是路径
你这个是创建一个数据库,并不是打开你资源文件里面的数据库,当然是空的。
建议:先将你的数据库里面的数据处理好,放到你的资源文件夹下面,比如asset或则res-raw(这个得自己创建),然后通过文件流的方式将其写到你的手机上面,不管是sdcard还是内存。然后再打开这个数据库即可。
这里你就备份个数据库文件就可以了,下次安装就只要更新APK里代码就OK了,
具体我也没实现,你可以按照这个思路去查查资料,网上有很多的。
其实我对楼主的问题有个疑问,即使是程序创建数据库,也不是每次启动就插数据啊。你程序第一次启动就会在默认目录下创建数据库并初始化(如果你有初始化动作的话),以后也是在此基础上进行增删查找的。难道你的程序每次关闭的时候都干掉数据库?不懂,求解。
http://www.cnblogs.com/zhegebucuo/archive/2010/09/11/1823964.html
就是先将数据库存到raw上,然后在第一次安装的时候复制到sdcard上,以后就直接打开数据库了。
一下是代码: private Context context;
private String rootDirectory = "/data/data/CrazyNovelV1_0.com/data/";
private final String DATABASE_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/crazynovel";
private final String DATABASE_FILENAME = "crazynovel.db";//复制小于1M的数据库程序
public SQLiteDatabase openDatabase()
{
try
{
// 获得dictionary.db文件的绝对路径
String databaseFilename = DATABASE_PATH+ "/" + DATABASE_FILENAME;
File dir = new File(DATABASE_PATH);
// 如果/sdcard/dictionary目录不中存在,创建这个目录
if (!dir.exists())
dir.mkdir();
// 如果在/sdcard/dictionary目录中不存在
// dictionary.db文件,则从res\raw目录中复制这个文件到
// SD卡的目录(/sdcard/dictionary)
if (!(new File(databaseFilename)).exists())
{
// 获得封装dictionary.db文件的InputStream对象
InputStream is = context.getResources().openRawResource(R.raw.crazynovel);
FileOutputStream fos = new FileOutputStream(databaseFilename);
byte[] buffer = new byte[7168];
int count = 0;
// 开始复制dictionary.db文件
while ((count = is.read(buffer)) > 0)
{
fos.write(buffer, 0, count);
}
fos.close();
is.close();
}
// 打开/sdcard/dictionary目录中的dictionary.db文件
SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFilename, null);
return database;
}
catch (Exception e)
{
}
}
小于1M的可以用上面的方法复制,但是如果文件大于1M则不行,需要分割后再合并,最终拷贝到sdcard上。现在还没实现,等我实现了再贴上。如果哪位大侠这道可帮一把。
databaseFilename, null);
得到的database 是null呢?
空可能是应为路径不对吧,或者是的的数据库有问题,下载到本地后用SQLiteSpy.exe工具看看,能不能打开。
首先用文件分割器把数据库分割为小于1M的文件,并拷贝到raw下,然后就是在程序里把文件拷贝到sdcard卡上,并把分割后的文件合并成数据库文件。代码如下:private Context context;
private String rootDirectory = "/data/data/CrazyNovelV1_0.com/data/";
private final String DATABASE_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/crazynovel";
private final String DATABASE_FILENAME = "crazynovel.db";//复制小于1M的数据库程序
public SQLiteDatabase openDatabase()
{
try
{
// 获得dictionary.db文件的绝对路径
String databaseFilename = DATABASE_PATH+ "/" + DATABASE_FILENAME;
File dir = new File(DATABASE_PATH);
// 如果/sdcard/dictionary目录不中存在,创建这个目录
if (!dir.exists())
dir.mkdir();
// 如果在/sdcard/dictionary目录中不存在
// dictionary.db文件,则从res\raw目录中复制这个文件到
// SD卡的目录(/sdcard/dictionary)
if (!(new File(databaseFilename)).exists())
{
//复制文件
copydb(R.raw.crazynovel1,DATABASE_PATH+ "/crazynovel1",944128);
copydb(R.raw.crazynovel2,DATABASE_PATH+ "/crazynovel2",944128);
copydb(R.raw.crazynovel3,DATABASE_PATH+ "/crazynovel3",944128);
copydb(R.raw.crazynovel4,DATABASE_PATH+ "/crazynovel4",944128);
copydb(R.raw.crazynovel5,DATABASE_PATH+ "/crazynovel5",944128);
copydb(R.raw.crazynovel6,DATABASE_PATH+ "/crazynovel6",944128);
copydb(R.raw.crazynovel7,DATABASE_PATH+ "/crazynovel7",944128);
copydb(R.raw.crazynovel8,DATABASE_PATH+ "/crazynovel8",944128);
copydb(R.raw.crazynovel9,DATABASE_PATH+ "/crazynovel9",944128);
copydb(R.raw.crazynovel10,DATABASE_PATH+ "/crazynovel10",944128);
copydb(R.raw.crazynovel11,DATABASE_PATH+ "/crazynovel11",944128);
copydb(R.raw.crazynovel12,DATABASE_PATH+ "/crazynovel12",669696);
//合并文件
File[] files = new File[12];
files[0] = new File(DATABASE_PATH+ "/crazynovel1");
files[1] = new File(DATABASE_PATH+ "/crazynovel2");
files[2] = new File(DATABASE_PATH+ "/crazynovel3");
files[3] = new File(DATABASE_PATH+ "/crazynovel4");
files[4] = new File(DATABASE_PATH+ "/crazynovel5");
files[5] = new File(DATABASE_PATH+ "/crazynovel6");
files[6] = new File(DATABASE_PATH+ "/crazynovel7");
files[7] = new File(DATABASE_PATH+ "/crazynovel8");
files[8] = new File(DATABASE_PATH+ "/crazynovel9");
files[9] = new File(DATABASE_PATH+ "/crazynovel10");
files[10] = new File(DATABASE_PATH+ "/crazynovel11");
files[11] = new File(DATABASE_PATH+ "/crazynovel12");
FileOutputStream fos = new FileOutputStream(databaseFilename);
CreateFromRawDbFiles(files,fos); }
catch (Exception e)
{
}
}
//复制文件
private void copydb(int dbint,String databaseFilename,int FileSize)
{
try
{
// 获得封装dictionary.db文件的InputStream对象
InputStream is = context.getResources().openRawResource(dbint);
FileOutputStream fos = new FileOutputStream(databaseFilename);
byte[] buffer = new byte[FileSize];
int count = 0;
// 开始复制dictionary.db文件
while ((count = is.read(buffer)) > 0)
{
fos.write(buffer, 0, count);
}
fos.close();
is.close();
}
catch(Exception e)
{}
}
//合并并拷贝数据
private void CreateFromRawDbFiles(File[] filelist,FileOutputStream Fos)
{
try
{
for (File file : filelist)
{
InputStream inputFile = new FileInputStream(file);
int TotalLength = 0;
try
{
TotalLength = inputFile.available();
}
catch (IOException e)
{
}
// Reading and writing the file Method 1 :
byte[] buffer = new byte[TotalLength];
int len = 0;
try
{
len = inputFile.read(buffer);
}
catch (IOException e)
{
}
Fos.write(buffer,0,len);
inputFile.close();
}
Fos.close();
}
catch(IOException e)
{}
}由于拷贝文件和合并文件都是很费时的事情,最好大家用线程来调用上面的代码,并加进度条显示当前进度。具体就写了。希望对大家有帮助。