转自:http://www.cnblogs.com/xiaowenji/archive/2011/01/03/1925014.html

我们平时见到的android数据库操作一般都是在程序开始时创建一个空的数据库,然后再进行相关操作。如果我们需要使用一个已有数据的数据库怎么办呢?

我们都知道android系统下数据库应该存放在 /data/data/com.*.*(package name)/ 目录下,所以我们需要做的是把已有的数据库传入那个目录下。操作方法是用FileInputStream读取原数据库,再用FileOutputStream把读取到的东西写入到那个目录。操作方法:1. 把原数据库包括在项目源码的 res/raw 目录下,然后建立一个DBManager类,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.android.ImportDatabase;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
 
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.util.Log;
 
public class DBManager {
    private final int BUFFER_SIZE = 400000;
    public static final String DB_NAME = "countries.db"; //保存的数据库文件名
    public static final String PACKAGE_NAME = "com.android.ImportDatabase";
    public static final String DB_PATH = "/data"
            + Environment.getDataDirectory().getAbsolutePath() + "/"
            + PACKAGE_NAME;  //在手机里存放数据库的位置
 
    private SQLiteDatabase database;
    private Context context;
 
    DBManager(Context context) {
        this.context = context;
    }
 
    public void openDatabase() {
        this.database = this.openDatabase(DB_PATH + "/" + DB_NAME);
    }
 
    private SQLiteDatabase openDatabase(String dbfile) {
        try {
            if (!(new File(dbfile).exists())) {  //判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库
                InputStream is = this.context.getResources().openRawResource(
                        R.raw.countries); //欲导入的数据库
                FileOutputStream fos = new FileOutputStream(dbfile);
                byte[] buffer = new byte[BUFFER_SIZE];
                int count = 0;
                while ((count = is.read(buffer)) > 0) {
                    fos.write(buffer, 0, count);
                }
                fos.close();
                is.close();
            }
            SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile,
                    null);
            return db;
        } catch (FileNotFoundException e) {
            Log.e("Database", "File not found");
            e.printStackTrace();
        } catch (IOException e) {
            Log.e("Database", "IO exception");
            e.printStackTrace();
        }
        return null;
    }
1
//do something else here<br>
1
2
3
4
    public void closeDatabase() {
        this.database.close();
    }
}

然后在程序的首个Activity中示例化一个DBManager对象,然后对其执行openDatabase方法就可以完成导入了,可以把一些要对数据库进行的操作写在DBManager类里,然后通过DBManager类的对象调用;也可以在完成导入之后通过一个SQliteDatabase类的对象打开数据库,并执行操作。

我的做法是 在程序的首个Activity中导入数据库:

1
2
3
4
5
6
7
8
9
package com.android.ImportDatabase;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
 
public class RootView extends Activity {
 
    public DBManager dbHelper;
1
2
3
4
5
6
7
8
9
10
11
12
    @Override
    public void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        dbHelper = new DBManager(this);
        dbHelper.openDatabase();
        dbHelper.closeDatabase();
 
    }
}

此时在DDMS中可以查看到,外部数据库已经成功导入

在需要使用数据库的类里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.android.ImportDatabase;
 
import java.util.ArrayList;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
 
public class TaxiActivity extends Activity {
 
    private SQLiteDatabase database;
        ArrayList<CityClass> CITY;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        database = SQLiteDatabase.openOrCreateDatabase(DBManager.DB_PATH + "/" + DBManager.DB_NAME, null);
 
        CITY = getCity();
         
        // do something with CITY
 
        database.close();
    }
 
    private ArrayList<CityClass> getCity() {
         
        Cursor cur = database.rawQuery("SELECT city.id_city, city.name FROM taxi, city WHERE city.id_city = taxi.id_city GROUP BY city.id_city", null);
         
        if (cur != null) {
            int NUM_CITY = cur.getCount();
            ArrayList<CityClass> taxicity = new ArrayList<CityClass>(NUM_CITY);
            if (cur.moveToFirst()) {
                do {
                    String name = cur.getString(cur.getColumnIndex("name"));
                    int id = cur.getInt(cur.getColumnIndex("id_city"));
                    CityClass city = new CityClass("", 0);
                    System.out.println(name);  //额外添加一句,把select到的信息输出到Logcat
                    city.city_name = name;
                    city.city_id = id;
                    taxicity.add(city);
                } while (cur.moveToNext());
            }
            return taxicity;
        } else {
            return null;
        }
    }
}

查看输出的结果:

如果导入的数据库大小有问题,或使用InputStream读取出错了,请看此贴 [iPhone/Android] 导入程序的数据库大小与原数据库大小不一致怎么办?

[Android]如何导入已有的外部数据库的更多相关文章

  1. Android 数据库升级中数据保持和导入已有数据库

    一.数据库升级: 在我们的程序中,或多或少都会涉及到数据库,使用数据库必定会涉及到数据库的升级,数据库升级带来的一些问题,如旧版本数据库的数据记录的保持,对新表的字段的添加等等一系列问题,还记得当我来 ...

  2. android studio 导入一个已有的android studio project作为lib使用

    android studio 导入一个已有的android studio project作为lib使用 新项目来了. 需要搭建框架. android studio对我来说还是很陌生,之前一个项目在同事 ...

  3. Android Studio 导入外部lib文件

    Android Studio 导入外部lib文件   1.将jar包放入Module里的lib文件夹中.(自己创建lib文件夹) 2.在project选中jar包点击右键"Add as li ...

  4. android开发学习---基础知识学习、如何导入已有项目和开发一个电话拨号器

    一.基础知识点学习  1.Android体系结构 如图所示,android 架构分为三层: (1)最底层是linux内核,主要是各种硬件的驱动,如相机驱动(Camera Driver),闪存驱动(Fl ...

  5. 关于“System.Data.OleDb.OleDbException,外部数据库驱动程序 (1) 中的意外错误。”的解决方案

    网站之前运行一直很正常,但有一次用户在导入格式为xls的excel文件,发生了错误,跟踪错误后抛出如下的异常: 错误提示: 未处理System.Data.OleDb.OleDbException HR ...

  6. CoreData: 如何预载/导入已有的数据

    原文地址:CoreData: 如何预载/导入已有的数据作者:出其东门 在系列教程一中,我们为对象建立了可视化数据模型,运行了快速肮脏测试并勾在一个表视图(table view)中来显示.而在这个教程, ...

  7. Android Studio导入第三方类库的方法

    Android Studio导入第三方类库的方法 本人也刚刚开始尝试做android app的开发,听说android studio是Google支持的android 应用开发工具,所以想应该肯定比E ...

  8. 《Entity Framework 6 Recipes》翻译系列 (4) -----第二章 实体数据建模基础之从已存在的数据库创建模型

    不知道对EF感兴趣的并不多,还是我翻译有问题(如果是,恳请你指正),通过前几篇的反馈,阅读这个系列的人不多.不要这事到最后成了吃不讨好的事就麻烦了,废话就到这里,直奔主题. 2-2 从已存在的数据库创 ...

  9. android studio 导入工程问题总结

    github上下了几个开源项目,在导入android studio时出现各种问题, 在网上查询各种资料后一一得以解决,现对个问题点进行简单的总结: 1. gradle project sync fai ...

随机推荐

  1. 当在命令行中执行virtualenv venv时报此错误:'utf-8' codec can't decode byte 0xd5 in position 38: invalid continuation by

    1.windows中安装虚拟环境virtualenv时, 当在命令行中执行virtualenv venv时报此错误:'utf-8' codec can't decode byte 0xd5 in po ...

  2. 操作系统OS,Python - 多进程(multiprocessing)、多线程(multithreading)

    多进程(multiprocessing) 参考: https://docs.python.org/3.6/library/multiprocessing.html 1. 多进程概念 multiproc ...

  3. 50道SQL练习题及答案与详细分析(MySQL)

    50道SQL练习题及答案与详细分析(MySQL) 网上的经典50到SQL题,经过一阵子的半抄带做,基于个人理解使用MySQL重新完成一遍,感觉个人比较喜欢用join,联合查询较少 希望与大家一起学习研 ...

  4. Vulnhub_bossplayersCTF 记录

    目录 经验 & 总结 步骤流水 经验 & 总结 CTF这种东西还是有一些脑洞和约定俗成的东西: 比如多次编码 比如cmd参数传入执行的命令 步骤流水 端口信息搜集nmap -A 192 ...

  5. VIM 练级

    https://coolshell.cn/articles/5426.html

  6. PTA的Python练习题(八)

    从 第3章-15 统计一行文本的单词个数 继续 1. s = input() count=0 for c in s: if c==' ': count=count+1 if c=='.': break ...

  7. 吴裕雄--天生自然ORACLE数据库学习笔记:管理控制文件和日志文件

    alter database add logfile ('D:\OracleFiles\LogFiles\REDO4_A.LOG', 'E:\OracleFiles\LogFiles\REDO4_B. ...

  8. java记录1--接口

    接口(interface)定义:抽象方法和常量值的集合.本质上讲,接口是一种特殊的抽象类 ps:1.接口中定义的属性必须是public static final 的,定义的方法必须是public ab ...

  9. Codeforces Round #584 - Dasha Code Championship - Elimination Round (rated, open for everyone, Div. 1 + Div. 2)C

    #define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;string s;pair<int,in ...

  10. Systemverilog for design 笔记(七)

    转载请标明出处 第一章 接口(interface) 1.1.    接口的概念 接口允许许多信号合成一组由一个端口表示. 1.2.    接口声明 //接口定义 Interface main_bus ...