2011-09-17 72 views
0

我真的有麻煩讓我的應用程序工作,我花了幾個小時嘗試沒有成功。如何將預先存在的sqlite數據庫文件從資產複製到數據庫文件夾?

我創建了一個包含1000個預先存在的行(在我的桌面上完成)的表的數據庫。由於數據量的原因,我不想在應用程序運行時填充應用程序數據庫。所以我打算讓應用程序部署將現有文件從assets文件夾複製到數據庫文件夾中。這必須是一個在人們的發展中重新發生的模式。

實現這個過程的代碼部分從這個鏈接: http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/

對不起,粘貼一段代碼,我通常不這樣做,但我已經花了幾個小時在此,看不到解決方案。

我的主要活動是,像這樣:

public class MainActivity extends ListActivity { 
     /** Called when the activity is first created. */ 


     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 


      try { 
      new DbHelper(this).createDataBase(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }       
      //.... 
     } 
} 

在DbHelper,copyDataBase被稱爲過度複製資產分貝。 當我打開數據庫時,沒有表格存在,只有android_metadata表格存在。所以不知何故複製失敗?

的DbHelper是像這樣:

public class DbHelper extends SQLiteOpenHelper { 
    private static final String TAG= "DbHelper"; 

    static final String DB_NAME = "mydatabase.sqlite"; 
    static final int DB_VERSION = 1; 
    private static String DB_PATH = ""; 

    private Context myContext; 

    public DbHelper(Context context) 
    { 
     super(context, DB_NAME, null, DB_VERSION); 
     this.myContext = context; 

     DB_PATH = "/data/data/" + context.getApplicationContext().getPackageName() + "/databases/"; 

    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     Log.d(TAG, "onCreate called"); 

     try { 
      Log.d(TAG, "Copying database..."); 
      copyDataBase(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }  
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // TODO Auto-generated method stub 

    } 

    public void createDataBase() throws IOException{ 

     boolean dbExist = checkDataBase(); 

     if(dbExist){ 
      //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.getWritableDatabase(); 
     } 

    } 

    public boolean checkDataBase(){ 

     SQLiteDatabase checkDB = null; 

     try{ 
      String myPath = DB_PATH + DB_NAME; 
      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
      Log.d(TAG, "db exists"); 
      } 
     catch(SQLiteException e){ 
      //database does't exist yet. 
      Log.d(TAG, "db doesn't exist"); 

     } 

     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 = myContext.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(); 
    } 
} 

任何人都可以擺脫任何光線到這是爲什麼不工作?

回答

0

看着我的代碼,不會基本上是同樣的事情,你應該有:

InputStream = myContext.getResources().getAssets().open(DB_NAME); 

我不知道隨便有什麼區別Context.getAssetsResources.getAssets之間,但不妨一試。

+0

當然,這應該是InputStream myInput =等 – gordonwd

+0

嗨,今天再次訪問。該文件實際上被複制並且在DDMS中長144,1792字節,所以我可以在那裏看到一個大文件。但是,當我把它拉下來時,在Sqlite3命令行工具或FireFox SQLManager加載項中打開它,它只有在那裏的android_metadata表。當我二進制比較這兩個文件時,我從DDMS下拉的原始AND文件是相同的!這裏發生了什麼?!? – jaffa

+0

我知道這是一箇舊線程,但我有完全相同的問題。你解決了這個問題嗎? – Opiatefuchs

0

我認爲你的SQLiteOpenHelper的onCreate方法可能不是你想要做副本的地方。您想在嘗試打開/創建文件之前複製該文件。

對於調試,我從我的應用程序的啓動代碼無數次這樣做,它工作得很好:

copyFile("/sdcard/dbs/latest_database.db", context.getDatabasePath("DatabaseNameHere").getPath()); 

(的CopyFile根本在於沒有你所期望一個小幫手功能)

你應該能夠調整它從你的資產目錄而不是SD卡複製它。

請注意,當我這樣做時,我正在複製我從應用程序的以前版本中提取的數據庫。如果您試圖複製您使用非android sqlite工具創建的數據庫,則可能需要先添加一個android_metadata表。據我所見,這只是一列(「區域設置」)和一行(如「en_US」)。

相關問題