2013-09-22 43 views
1

我已經閱讀了一些教程,其中已存在的數據庫已複製到資產文件夾並編寫代碼以將此數據庫複製到應用程序數據庫的默認系統路徑。如何訪問和查詢複製到資產文件夾的數據庫?

package com.example.c1; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 

public class DataBaseHelper extends SQLiteOpenHelper { 

    //The Android's default system path of your application database. 
     private static String DB_PATH = "/data/data/com.example.c/databases/"; 

     private static String DB_NAME = "MyDatabase"; 

     private SQLiteDatabase myDataBase; 

     private final Context myContext; 

     /** 
      * Constructor 
      * Takes and keeps a reference of the passed context in order to access to the application assets and resources. 
      * @param context 
      */ 
     public DataBaseHelper(Context context) { 

     super(context, DB_NAME, null, 1); 
     this.myContext = context; 
     } 

     /** 
      * Creates a empty database on the system and rewrites it with your own database. 
      * */ 
     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.getReadableDatabase(); 

     try { 

     copyDataBase(); 

     } catch (IOException e) { 

     throw new Error("Error copying database"); 

     } 
     } 

     } 

     /** 
      * Check if the database already exist to avoid re-copying the file each time you open the application. 
      * @return true if it exists, false if it doesn't 
      */ 
     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; 
     } 

     /** 
      * 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 = 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(); 

     } 

     public void openDataBase() throws SQLException{ 

      //Open the database 
      String myPath = DB_PATH + DB_NAME; 
      myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

      } 

      @Override 
      public synchronized void close() { 

      if(myDataBase != null) 
      myDataBase.close(); 

      super.close(); 

      } 

      @Override 
      public void onCreate(SQLiteDatabase db) { 

      } 

      @Override 
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

      } 



      // Add your public helper methods to access and get content from the database. 
      // You could return cursors by doing "return myDataBase.query(....)" so it'd be easy 
      // to you to create adapters for your views. 

} 

我使用此代碼將數據庫從assets文件夾複製到默認路徑。

package com.example.c1; 

import java.io.IOException; 
import com.example.c1.DataBaseHelper; 
import android.os.Bundle; 
import android.app.Activity; 
import android.database.SQLException; 
import android.view.Menu; 
import android.widget.TextView; 

public class C1 extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.c1); 

     DataBaseHelper myDbHelper = new DataBaseHelper(this); 


     try { 

     myDbHelper.createDataBase(); 

     } catch (IOException ioe) { 

     throw new Error("Unable to create database"); 

     } 

     try { 

     myDbHelper.openDataBase(); 

     }catch(SQLException sqle){ 

     throw sqle; 

     } 


    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.c1, menu); 
     return true; 
    } 

} 

運行此模擬器說c1已停止。我點擊DDMS視圖,並在文件瀏覽器中選擇我的包。我找到了「數據庫」文件夾。我的數據庫在assets文件夾裏; 「MyDatabase」在這裏找到。但是,當我拉動文件,並在sqlite瀏覽器中打開它只顯示android_metadata表,但不顯示我的數據庫中的其他表。我也無法執行任何查詢。我如何訪問和查詢數據庫?如在DataBaseHelper類中執行「Select」語句並顯示其結果。我希望我的問題清楚。我有一個數據庫複製到資產文件夾和一個代碼來複制這個數據庫到默認路徑。代碼是否正確?如果不是,那麼我應該做出什麼修正?我需要執行查詢ñ如何做到這一點?

回答

1

你需要複製你的數據庫文件的應用程序目錄文件夾,然後將此文件利用這個

protected Boolean openDatabase() 
{ 
    if(isDatabaseExist(false)) 
    { 
     // Open the database 
     String myPath = DB_PATH + DB_NAME; 
     try 
     { 
      Log.i("Database", "Trying to Open Database!"); 
      if(myDataBase != null) 
      { 
       if(!myDataBase.isOpen()) 
       { 
        Log.i("Database", "Database is closed now opening it!"); 
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 

       } 
       else 
       { 
        Log.i("Database", "Database is already Open!"); 
       } 
       Log.i("Database", "Database is Opened successfully in OPEN_READWRITE Mode !"); 
       return true; 

      } 
      else 
      { 
       myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 
       Log.i("Database", "Database is Opened successfully in OPEN_READWRITE Mode !"); 
       return true; 
      } 

     } 
     catch(Exception e) 
     { 
      Log.e("Database", "Some error occured while opening Database Error:" + e.getMessage()); 
      myDataBase = null; 
      return false; 
     } 

    } 
    else 
    { 
     copyDataBase(); 
    } 
    return false; 
} 
打開數據庫

我使用它來copyDatabase

private void copyDataBase() 
{ 
    Log.i("Database", "New database is being copied to device!"); 
    byte[] buffer = new byte[1024]; 
    OutputStream myOutput = null; 
    int length; 
    // Open your local db as the input stream 
    InputStream myInput = null; 
    try 
    { 
     myInput = myContext.getAssets().open(DB_NAME); 
     // transfer bytes from the inputfile to the 
     // outputfile 
     myOutput = new FileOutputStream(DB_PATH + DB_NAME); 
     while((length = myInput.read(buffer)) > 0) 
     { 
      myOutput.write(buffer, 0, length); 
     } 
     myOutput.close(); 
     myOutput.flush(); 
     myInput.close(); 
     Log.i("Database", "New database has been copied to device!"); 
     cmn.mailDetails(); 

    } 
    catch(IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

開放

+0

我用你的代碼替換了我的copyDataBase()和openDataBase()。它爲我工作。現在我怎樣才能從表格中檢索?例如:我希望顯示錶格中第6行的內容。我怎樣才能做到這一點?對不起,我試圖標記你的答案,但它的要求15聲譽 – user2648852

+0

@ user2648852好吧,你可以在以後做 – Trikaldarshi

+0

以及sqlite.org或vogella的教程將幫助你更多關於sqlite或者你可以問問新的單獨問題的其他問題 – Trikaldarshi

相關問題