访问外部SQLite数据库时出错

时间:2015-01-05 13:26:22

标签: android sqlite android-sqlite ormlite

我有一个名为example.db的外部sqlite数据库,我尝试使用OrmLite进行创建。我在互联网上进行了一些搜索,每个人都推荐了这个教程http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/

所以我跟着它并且效果很好,但是当我尝试使用OrmLite做同样的事情时,我无法从外部文件(example.db)创建自己的数据库。我在调用createDatabase()方法时发现,数据库已经创建,当我使用不带OrmLite的OpenHelperDatabase时,它没有发生。

有人有任何想法吗?

代码是:

//imports

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {

private static String DB_PATH = "/data/data/com.example/databases/";
private static String DB_NAME = "example.db";
private static final int DATABASE_VERSION = 1;

private SQLiteDatabase exampleDB;
private final Context context;

public DatabaseHelper(Context context) {

    super(context, DB_NAME, null, DATABASE_VERSION);
    this.context = context;
}

public void createDataBase() throws IOException {

    boolean dbExist = checkDataBase();

    if(dbExist){
        Log.i(DatabaseHelper.class.getName(), "Database already exist!!! Here is the problem");
    }else{

        this.getReadableDatabase();

        try {

            copyDataBase();

        } catch (IOException e) {

            throw new Error("Error copying database");

        }
    }

}

private boolean checkDataBase(){

    SQLiteDatabase checkDB = null;

    try{
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

    }catch(SQLiteException e){

        //database does't exist yet.

    }

    if(checkDB != null){

        checkDB.close();

    }

    return checkDB != null ? true : false;
}

private void copyDataBase() throws IOException{

    //Open your local db as the input stream
    InputStream myInput = context.getAssets().open(DB_NAME);

    // Path to the just created empty db
    String outFileName = DB_PATH + DB_NAME;

    //Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    //transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    //Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();

}

@Override
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
    Log.i(DatabaseHelper.class.getName(), "onCreate");
    try {
        createDataBase();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
   //TODO
}


@Override
public synchronized void close() {

    if(exampleDB != null)
        exampleDB.close();

    super.close();

}
}

3 个答案:

答案 0 :(得分:3)

createDataBase方法

public void createDataBase() throws IOException {  

    boolean dbExist = checkDataBase();  

    if (dbExist) {  

    } else {  
        this.getReadableDatabase();  

        try {  
        copyDataBase(); 

        } catch (IOException e) {  
            throw new Error("Error copying database");  
        }  
    }  
}  

private boolean checkDataBase() {  
    File dbFile = new File(DB_PATH + DB_NAME);  
    return dbFile.exists();  
}  

复制数据库方法

private void copyDataBase() throws IOException {  

      InputStream myInput = context.getAssets().open(DB_NAME);  
      String outFileName = DB_PATH + DB_NAME;  
      OutputStream myOutput = new FileOutputStream(outFileName);  
      byte[] buffer = new byte[1024];  
      int length;  
      while ((length = myInput.read(buffer)) > 0) {  
       myOutput.write(buffer, 0, length);  
      }  
      // Close the streams  
      myOutput.flush();  
      myOutput.close();  
      myInput.close();  

     }  

打开数据库方法

public void openDataBase () throws SQLException{
    String path = DB_PATH +DB_NAME;
    db =SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.CREATE_IF_NECESSARY);
}

从数据库中检索数据

public Cursor getData() {  

      String myPath = DB_PATH + DB_NAME;  
      db = SQLiteDatabase.openDatabase(myPath, null,  
        SQLiteDatabase.OPEN_READONLY);  
      Cursor c = db.rawQuery("SELECT * FROM info", null);  
          return c;  
     }  

将数据插入数据库

public void addUser(Astro contact) {  
  //  SQLiteDatabase db = this.getWritableDatabase();  
    String myPath = DB_PATH + DB_NAME;  
    db = this.getWritableDatabase();

    ContentValues values = new ContentValues();  
    values.put(KEY_Date, contact.get_date()); // Contact Name  
    values.put(KEY_Time, contact.get_time()); // Contact Phone  
    // Inserting Row  
    db.insert(TABLE_ASTRO, null, values);  
    //2nd argument is String containing nullColumnHack  
    db.close(); // Closing database connection  
}

答案 1 :(得分:1)

我发现了问题,我已经放弃了,所以我正在研究另一种名为ActiveAndroid的ORM。当我看到这个页面时,我正在阅读文档页面:https://github.com/pardom/ActiveAndroid/wiki/Pre-populated-databases和以下语句:将所有主键字段重命名为命名Id(不像标准Android数据库那样_id)。

所以我修改了我的数据库并尝试使用上面的代码并且运行良好,问题解决了。但是,我仍然不知道为什么Android会复制数据库以及为什么我们必须更改id列的名称。

答案 2 :(得分:0)

我认为你只需要将名称加上扩展名example.db