2011-03-26 77 views
4

我有一個sqlite數據庫,我複製到'資產'文件夾。在我的編程中,我檢查數據庫是否已經存在,如果沒有,我創建一個新的並複製它。 我用(或多或少)的代碼從http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/comment-page-2/複製sqlite數據庫到Android設備失敗

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] 

發生這種情況時,我嘗試第一次打開數據庫。當我在模擬器中運行程序時,我沒有收到此消息。當我第二次運行程序時,它發現數據庫,打開時沒有錯誤,但表不存在。

我已經調試過仿真器和設備上的程序多次,但找不到任何解決方案。

這可能是某種權限問題嗎? (因爲我也不能看到與亞行的設備上的DB - >權限被拒絕')

我很新到Android,所以也許我只是錯過了一些愚蠢的....

謝謝

回答

0
  1. 不要通過字符串連接創建路徑。使用合適的File構造函數。
  2. 您的DB_PATH可能無效,但由於您拒絕顯示,因此我們無法確定。
  3. 如果此代碼來自的類是SQLiteOpenHelper,那麼您致電getReadableDatabase()將創建一個空數據庫。
  4. 「(因爲我也無法在設備上看到adb - >權限被拒絕的數據庫」「 - 這是預期的,因爲您無權查看生產設備上的該目錄。
+1

感謝您的回答。使用File構造函數的提示非常有用。我在http://www.anddev.org/networking-database-problems-f29/missing-table-in-sqlite-with-specific-version-of-desire-hd-t50364.html上找到了解決方案不知道,這是一個設備特定的問題,所以我搜索了幾個小時錯誤的關鍵詞。 – user678199 2011-03-26 21:07:53

+0

@ user678199:非常感謝鏈接... :)這應該是一個答案...不是評論.. – Deepzz 2013-01-04 06:15:57

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; 
} 

希望這會幫助新來者。

乾杯