访问外部 SQLite 数据库时出错

Error Accessing external SQLite database

我有一个名为 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();

}
}

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

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

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

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  
}