2013-04-08 35 views
0

我有我的nextQuestion方法,每次我需要使用導入的sqlite prepopulated數據庫時,我需要在我的遊戲中提出新問題。我想我做錯了,因爲每次我問新的問題我的數據庫被重新創建。但我試圖把數據庫的東西放在活動範圍,但我得到錯誤mDbHelper.createDatabase();行(標記createDatabase上的語法錯誤,在此標記之後預期的indetifier)。這是我的nextQuestion方法,我首先在onCreate方法中調用,然後在每個用戶回答後調用。如何正確打開並查詢數據庫?

public void nextQuestion() { 

     TestAdapter mDbHelper = new TestAdapter(this); 
     mDbHelper.createDatabase(); 

     try{ 

      mDbHelper.open(); //baza otvorena 

      Cursor c = mDbHelper.getTestData(generateWhereClause()); 
      mAnsweredQuestions.add(c.getLong(0)); 

      List<Answer> labels = new ArrayList<Answer>(); 

      labels.add(new Answer(c.getString(2), true)); 
      labels.add(new Answer(c.getString(3), false)); 
      labels.add(new Answer(c.getString(4), false)); 
      labels.add(new Answer(c.getString(5), false)); 

      Collections.shuffle(labels); 

      tacanOdg = c.getString(2); 


     question.setText(c.getString(1)); 

     bOdgovor1.setText(labels.get(0).option); 
     bOdgovor1.setTag(labels.get(0)); 
     bOdgovor1.setOnClickListener(clickListener); 

     bOdgovor2.setText(labels.get(1).option); 
     bOdgovor2.setTag(labels.get(1)); 
     bOdgovor2.setOnClickListener(clickListener); 

     bOdgovor3.setText(labels.get(2).option); 
     bOdgovor3.setTag(labels.get(2)); 
     bOdgovor3.setOnClickListener(clickListener); 

     bOdgovor4.setText(labels.get(3).option); 
     bOdgovor4.setTag(labels.get(3)); 
     bOdgovor4.setOnClickListener(clickListener); 
      } 

如何正確執行此操作?

這裏是我的助手,如果需要的話。

public class DataBaseHelper extends SQLiteOpenHelper 
{ 
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window 
//destination path (location) of our database on device 
private static String DB_PATH = "/data/data/rs.androidaplikacijekvizopstekulture/databases/"; 
private static String DB_NAME ="pitanja.sqlite";// Database name 
private static SQLiteDatabase mDataBase; 
private final Context mContext; 
private static final String KEY_ID = "_ID"; 
private static final String KEY_PITANJE = "PITANJE"; 
private static final String KEY_ODGOVOR = "ODGOVOR"; 
private static final String KEY_OPCIJA1 = "OPCIJA1"; 
private static final String KEY_OPCIJA2 = "OPCIJA2"; 
private static final String KEY_OPCIJA3 = "OPCIJA3"; 
private static final String TABLE_NAME = "tblPitanja"; 

public DataBaseHelper(Context mojContext) 
{ 
    super(mojContext, DB_NAME, null, 1);// 1? its Database Version 
    DB_PATH = mojContext.getApplicationInfo().dataDir + "/databases/"; 
    this.mContext = mojContext; 
} 

public void createDataBase() throws IOException 
{ 
    //If database not exists copy it from the assets 


     this.getReadableDatabase(); 
     this.close(); 
     try 
     { 
      //Copy the database from assests 
      copyDataBase(); 
      Log.e(TAG, "createDatabase database created"); 
     } 
     catch (IOException mIOException) 
     { 
      throw new Error("ErrorCopyingDataBase"); 
     } 
    } 
    /*Check that the database exists here: /data/data/your package/databases/Da Name 
    private boolean checkDataBase() 
    { 
     File dbFile = new File(DB_PATH + DB_NAME); 
     //Log.v("dbFile", dbFile + " "+ dbFile.exists()); 
     return dbFile.exists(); 
    } 
    */ 

    //Copy the database from assets 
    private void copyDataBase() throws IOException 
    { 
     InputStream mInput = mContext.getAssets().open(DB_NAME); 
     String outFileName = DB_PATH + DB_NAME; 
     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 
    { 
     String mPath = DB_PATH + DB_NAME; 
     //Log.v("mPath", mPath); 
     mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
     //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
     return mDataBase != null; 
    } 

    public void close() 
    { 
     if(mDataBase != null) 
      mDataBase.close(); 
     super.close(); 
    } 


    public void onCreate(SQLiteDatabase arg0) { 
     } 


    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { 
     Log.w("DataBaseHelper", "Upgrading database!!!!!"); 
      onCreate(arg0); 

    } 

} 

和TestAdapter:

public class TestAdapter 
{ 
    protected static final String TAG = "DataAdapter"; 

    private final Context mContext; 
    private SQLiteDatabase mDb; 
    private DataBaseHelper mDbHelper; 

    public TestAdapter(Context context) 
    { 
     this.mContext = context; 
     mDbHelper = new DataBaseHelper(mContext); 
    } 

    public TestAdapter createDatabase() throws SQLException 
    { 
     try 
     { 
      mDbHelper.createDataBase(); 
     } 
     catch (IOException mIOException) 
     { 
      Log.e(TAG, mIOException.toString() + " UnableToCreateDatabase"); 
      throw new Error("UnableToCreateDatabase"); 
     } 
     return this; 
    } 

    public TestAdapter open() throws SQLException 
    { 
     try 
     { 
      mDbHelper.openDataBase(); 
      mDbHelper.close(); 
      mDb = mDbHelper.getReadableDatabase(); 
     } 
     catch (SQLException mSQLException) 
     { 
      Log.e(TAG, "open >>"+ mSQLException.toString()); 
      throw mSQLException; 
     } 
     return this; 
    } 

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

    public Cursor getTestData(String whereClause) 
    {; 
     try 
     { 
      String sql ="SELECT * FROM tblPitanja WHERE 1 = 1 " + whereClause + " ORDER BY RANDOM() LIMIT 1"; 

      Cursor mCur = mDb.rawQuery(sql, null); 
      if (mCur!=null) 
      { 
       mCur.moveToNext(); 
      } 
      return mCur; 
     } 
     catch (SQLException mSQLException) 
     { 
      Log.e(TAG, "getTestData >>"+ mSQLException.toString()); 
      throw mSQLException; 
     } 
    } 
} 

OK,我已經編輯我的數據庫輔助類,並添加以下代碼,以檢查是否存在分貝:

** 
* 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 
*/ 
public 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; 
} 
在我的遊戲活動我

然後檢查此方法是否返回true或false,如果它是false,則創建db:

TestAdapter mDbHelper = new TestAdapter(this); 
     DataBaseHelper myDbHelper = new DataBaseHelper(this); 

     if(!myDbHelper.checkDataBase()){ 
     mDbHelper.createDatabase(); 
     } 

     try{ 

      mDbHelper.open(); 
} 

回答

0

YOu不應該一直呼叫createDatabase(),而是將DB創建放在幫助者的onCreate()中。你也應該close()你的分貝(mDbHelper.close())完成後。

編輯:你似乎想要基於存儲在資產中的sqlite文件初始化你的數據庫?如果是這樣,而不是重新發明車輪使用此幫手:https://github.com/jgilfelt/android-sqlite-asset-helper

+0

你能告訴我的onCreate放置該線方法?你是什​​麼意思的「幫手的onCreate」?我的DBHelper類中沒有onCreate方法。 – marjanbaz 2013-04-08 14:16:33

+0

而且,當我在我的onCreate()方法中放入createDatabase()時,我在我的nextQuestion()方法中導致錯誤,導致mDbHelper.open();導致createDatabase()在不同的範圍內。 – marjanbaz 2013-04-08 14:19:40

+0

假設您的TestAdapter擴展了SQLiteOpenHelper,則可以覆蓋一個SQLiteOpenHelper.onCreate(SQLiteDatabase數據庫)方法。那就是你應該放置表創建語句的地方。 – codebaum 2013-04-08 14:21:46

0

這裏是DataBaseHelper的很好的例子,你可以使用:

public class DataBaseHelper extends SQLiteOpenHelper{ 

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

private static String DB_NAME = "myDBName"; 

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. 

} 

,之後打開數據庫:

... 

DataBaseHelper myDbHelper = new 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; 

} 

... 
+0

是的,很好的例子,但我的adaper和dbHelper幾乎是一樣的。我只需要知道在我的遊戲活動中要做什麼,如何安全地打開和關閉數據庫。我想現在我已經設法通過刪除mDbHelper.createDatabase();線。 – marjanbaz 2013-04-08 15:22:03

+0

通過刪除mDbHelper.createDatabase()它僅適用於現在,因爲您只使用openDataBase()方法。如果你將刪除你的應用程序,然後重新安裝它,你將再次需要mDbHelper.createDatabase()。 – 2013-04-08 15:26:15

+0

我想你是對的。有沒有辦法糾正我的代碼,以避免這種情況?我寧願這樣做,然後使用另一個數據庫幫助程序代碼。 – marjanbaz 2013-04-08 15:48:38

相關問題