4

我有一个复制到“资产”文件夹的 sqlite 数据库。在我的程序中,我检查数据库是否已经存在,如果不存在,我创建一个新的并复制它。我使用(或多或少)来自http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/comment-page-2/的代码

    public void createDataBase() throws IOException {
    boolean dbExist = checkDataBase();

    if (dbExist) {
        Log.i(DEBUG_TAG, "createDataBase -> Datenbank existiert");
        // do nothing - database already exist
    } else {
        // By calling this method and empty database will be created into
        // the default system path
        // of your application so we are gonna be able to overwrite that
        // database with our database.
        this.getReadableDatabase();
        Log.i(DEBUG_TAG, "else, db existiert nicht 1");
        try {
            copyDataBase();
            Log.i(DEBUG_TAG, "nach copydatabase");
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

/**
 * Checked ob Database bereits existiert
 * 
 * @return
 */
private boolean checkDataBase() throws SQLiteException {
    SQLiteDatabase checkDB = null;
    Boolean checkTable = false;
    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);
        Log.i(DEBUG_TAG, "checkdatabase1");

    } catch (SQLiteException e) {
        Log.e(DEBUG_TAG, "Fehler checkDataBase: ", e);
    }
    if (checkDB != null) {
        checkDB.close();
    }
    return checkDB != null ? true : false;
}

/**
 * Copies your database from your local assets-folder to the just created
 * empty database in the system folder, from where it can be accessed and
 * handled. This is done by transfering bytestream.
 * */
private void copyDataBase() throws IOException {
    // Open your local db as the input stream
    InputStream myInput = dbContext.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();
    Log.i(DEBUG_TAG, "copydatabase");
}

在模拟器中它工作得很好。

然后我尝试在我的设备(HTC Desire HD)上运行它。在那里我收到以下消息:

03-26 17:02:05.053: INFO/Database(24458): sqlite returned: error code = 14, msg = cannot open file at line 27206 of [42537b6056]

当我第一次尝试打开数据库时,就会发生这种情况。当我在模拟器中运行程序时,我没有收到此消息。当我第二次运行程序时,它找到了数据库,打开时没有错误,但表不存在。

我已经在模拟器和设备上调试了几次程序,但找不到任何解决方案。

这可能是某种许可问题吗?(因为我也无法使用 adb --> 权限被拒绝'看到设备上的数据库)

我对android很陌生,所以也许我错过了一些愚蠢的东西......

谢谢

4

2 回答 2

0

我通过创建自己的目录并将文件放在目录中来使其工作

String path=mContext.getDir("Folder_name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();

创建文件夹的代码。

然后进行我们检查数据库和复制数据库的操作。

enter code here 

 public void createDataBase() throws IOException { 
 String path=mContext.getDir("Folder_Name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();
 DB_PATH=path;
 boolean mDataBaseExist = checkDataBase(); 
 if(!mDataBaseExist) 
 { 
   try  
    { 
     copyDataBase(); 
    }  
    catch (IOException mIOException)  
    { 
    Log.d("Exception",mIOException.getMessage());
    throw new Error("ErrorCopyingDataBase"); 
    } 
} 
}


private boolean checkDataBase() 
{ 
    Log.d(TAG, "In checkDataBase :::::"); 
    File dbFile = new File( DB_PATH+DATABASE_NAME); 
    Log.d("dbFile", dbFile + "   "+ dbFile.exists()); 
    return dbFile.exists(); 
} 

//Copy the database from assets 
private void copyDataBase() throws IOException 
{ 
    Log.d(TAG, "In copyDataBase :::::"); 
    InputStream mInput = mContext.getAssets().open(DB_NAME);
    String outFileName = DB_PATH  + DATABASE_NAME;

    Log.d(TAG, "In copyDataBase  outFileName:::::"+outFileName);

    OutputStream mOutput = new FileOutputStream(outFileName); 
    byte[] mBuffer = new byte[1024]; 
    int mLength; 
    while ((mLength = mInput.read(mBuffer))>0) 
    { 
        mOutput.write(mBuffer, 0, mLength); 
    } 
    mOutput.flush(); 
    mOutput.close(); 
    mInput.close(); 
} 

//Open the database, so we can query it 
public boolean openDataBase() throws SQLException 
{ 
    //DB_PATH +
    String mPath = DB_PATH+ DATABASE_NAME; 
    Log.v("mPath", mPath); 
    mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
    return mDataBase != null; 
} 

希望这对新来的人有所帮助。

干杯

于 2012-09-06T11:04:00.777 回答
0
  1. 不要通过字符串连接创建路径。使用适当的File构造函数。
  2. DB_PATH可能无效,但由于您拒绝出示,我们无法确定。
  3. 如果此代码来自的类是 a SQLiteOpenHelper,则您的调用getReadableDatabase()将创建一个空数据库。
  4. “(因为我也无法通过 adb --> 权限被拒绝'看到设备上的数据库” - 这是预期的,因为您无权在生产设备上查看该目录。
于 2011-03-26T18:16:38.027 回答