将sqlite db复制到android设备失败

时间:2011-03-26 17:27:22

标签: android sqlite device htc-android

我有一个sqlite数据库,我将其复制到'asset'文件夹中。在我的编程中,我检查数据库是否已经存在,如果没有,我创建一个新的并复制它。 我使用(或多或少)来自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很新,所以也许我只是错过了一些愚蠢的东西......

由于

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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; 
} 

希望这会有助于新来的人。

干杯