2010-08-23 66 views
13

我想用現有的SQLite數據庫部署一個應用程序。什麼是現有SQLite數據庫的完整Android數據庫幫助器類?

我已經通讀並試圖在線實現多個示例,但是我發現它們總是缺少一些代碼,並且不會按照所宣傳的進行編譯或工作。

有沒有人有一個完整的Android數據庫幫助類在Android上部署現有的SQLite數據庫?

+0

我用你的代碼嘗試,但它卡住在這一部分: ActivityManager:開始:意向{行動= android.intent.action.MAIN貓= [android.intent.category.LAUNCHER] CMP = com.mdegges/.MicheleActivity。 data/data/com.mdegges/database文件永遠不會被創建。 – mdegges 2012-03-06 20:10:40

+0

@mdegges我不知道那裏出了什麼問題。從你的其他問題看,你似乎也陷在了LAUNCHER部分。在包含db代碼之前,您能夠執行hello world測試嗎? – 2012-03-06 21:36:07

+0

是的,我已經能夠在開發者網站上完成大量的內容(包括hello world)。奇怪的是,我嘗試過的指南都沒有工作。數據庫在我的資產文件夾中,我將DB_PATH更改爲正確的輸出文件夾,並且將db名稱更改爲我的數據庫(有和沒有擴展名),但沒有運氣! – mdegges 2012-03-06 21:55:48

回答

27

這就是我想出來的,希望它可以幫助其他有麻煩的人。

package com.MyPackage; 

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

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; 
import android.util.Log; 

public class AnyDBAdapter { 

    private static final String TAG = "AnyDBAdapter"; 
    private DatabaseHelper mDbHelper; 
    private static SQLiteDatabase mDb; 

    //make sure this matches the 
    //package com.MyPackage; 
    //at the top of this file 
    private static String DB_PATH = "/data/data/com.MyPackage/databases/"; 

    //make sure this matches your database name in your assets folder 
    // my database file does not have an extension on it 
    // if yours does 
    // add the extention 
    private static final String DATABASE_NAME = "data"; 

    //Im using an sqlite3 database, I have no clue if this makes a difference or not 
    private static final int DATABASE_VERSION = 3; 

    private final Context adapterContext; 

    public AnyDBAdapter(Context context) { 
     this.adapterContext = context; 
    } 

    public AnyDBAdapter open() throws SQLException { 
     mDbHelper = new DatabaseHelper(adapterContext); 

     try { 
      mDbHelper.createDataBase(); 
     } catch (IOException ioe) { 
      throw new Error("Unable to create database"); 
     } 

     try { 
      mDbHelper.openDataBase(); 
     } catch (SQLException sqle) { 
      throw sqle; 
     } 
     return this; 
    } 
    //Usage from outside 
    // AnyDBAdapter dba = new AnyDBAdapter(contextObject); //in my case contextObject is a Map 
    // dba.open(); 
    // Cursor c = dba.ExampleSelect("Rawr!"); 
    // contextObject.startManagingCursor(c); 
    // String s1 = "", s2 = ""; 
    // if(c.moveToFirst()) 
    // do { 
    // s1 = c.getString(0); 
    // s2 = c.getString(1); 
    // } while (c.moveToNext()); 
    // dba.close(); 
    public Cursor ExampleSelect(string myVariable) 
    { 
     String query = "SELECT locale, ? FROM android_metadata"; 
     return mDb.rawQuery(query, new String[]{myVariable}); 
    } 

    //Usage 
    // AnyDBAdatper dba = new AnyDBAdapter(contextObjecT); 
    // dba.open(); 
    // dba.ExampleCommand("en-CA", "en-GB"); 
    // dba.close(); 
    public void ExampleCommand(String myVariable1, String myVariable2) 
    { 
     String command = "INSERT INTO android_metadata (locale) SELECT ? UNION ALL SELECT ?"; 
     mDb.execSQL(command, new String[]{ myVariable1, myVariable2}); 
    } 

    public void close() { 
     mDbHelper.close(); 
    } 

    private static class DatabaseHelper extends SQLiteOpenHelper { 

     Context helperContext; 

     DatabaseHelper(Context context) { 
      super(context, DATABASE_NAME, null, DATABASE_VERSION); 
      helperContext = context; 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      Log.w(TAG, "Upgrading database!!!!!"); 
      //db.execSQL(""); 
      onCreate(db); 
     } 

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

       //make sure your database has this table already created in it 
       //this does not actually work here 
       /* 
       * db.execSQL("CREATE TABLE IF NOT EXISTS \"android_metadata\" (\"locale\" TEXT DEFAULT 'en_US')" 
       *); 
       * db.execSQL("INSERT INTO \"android_metadata\" VALUES ('en_US')" 
       *); 
       */ 
       this.getReadableDatabase(); 
       try { 
        copyDataBase(); 
       } catch (IOException e) { 
        throw new Error("Error copying database"); 
       } 
      } 
     } 

     public SQLiteDatabase getDatabase() { 
      String myPath = DB_PATH + DATABASE_NAME; 
      return SQLiteDatabase.openDatabase(myPath, null, 
        SQLiteDatabase.OPEN_READONLY); 
     } 

     private boolean checkDataBase() { 
      SQLiteDatabase checkDB = null; 
      try { 
       String myPath = DB_PATH + DATABASE_NAME; 
       checkDB = SQLiteDatabase.openDatabase(myPath, null, 
         SQLiteDatabase.OPEN_READONLY); 
      } catch (SQLiteException e) { 
      } 
      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 = helperContext.getAssets().open(DATABASE_NAME); 

      // Path to the just created empty db 
      String outFileName = DB_PATH + DATABASE_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 + DATABASE_NAME; 
      mDb = SQLiteDatabase.openDatabase(myPath, null, 
        SQLiteDatabase.OPEN_READWRITE); 
     } 

     @Override 
     public synchronized void close() { 

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

      super.close(); 

     } 
    } 

} 
+1

您的班級可以打開駐留在SD卡上的數據庫嗎? – Thiago 2011-07-20 19:51:52

+0

如果你有一個現有的數據庫,你自己複製到你的SD卡我想你可以嘗試刪除'copyDataBase()'調用並將DB_PATH更改爲適當的位置。但這只是一個猜測。我寧願不讓用戶直接訪問應用程序數據,所以我從來沒有考慮過這個選項。 – 2011-07-20 21:47:25

+0

其中是mContext定義? – Carnivoris 2011-07-26 17:53:22

4
DatabaseHelper dbHelper = new DatabaseHelper(getApplicationContext()); 

確保在應用程序生命週期中創建DatabaseHelper對象一次並重用它。

爲了讀取數據:

SQLiteDatabase db = dbHelper.getReadableDatabase(); 

對於讀/修改數據:

SQLiteDatabase db = dbHelper.getWritableDatabase(); 

下次使用insert()query()update(),SQLiteDatabase對象的delete()方法:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

你也不應該通過直接訪問sqlite文件來創建你在createNewDatabase方法中做的事情。 在onCreate(...)方法中使用SQLiteDatabase對象的execSQL()方法。在那裏執行你的CREATE TABLE查詢。

+0

嗨radek-k,你能擴展你的第一點嗎? '確保在應用程序生命週期中創建一次DatabaseHelper對象並重用它。' – 2010-08-23 19:30:18

+1

如果您多次創建DatabaseHelper對象,請確保先前已關閉數據庫 - getWritableDatabase.close()。在多線程應用程序模型中,當您沒有關閉前一個時,您不能重新創建DatabaseHelper。你只會得到一些例外。最好的方法是僅創建一次DatabaseHelper對象(例如,在Application中),並始終使用相同的對象引用。 – plugmind 2010-08-23 19:46:31

+1

我不會推薦使用'getApplicationContext()'。因爲無論對「getApplicationContext()」作出響應的是「Context」。 – CommonsWare 2010-08-23 21:51:17