2012-04-11 41 views
1

我知道有数十亿线程关于SQL数据库,但我没有找到任何解决我的问题。 我已经制作了一个名为Beer Or No Beer的应用程序,它需要一个具有啤酒品牌和国家的Arraylist。现在我想用SQLite管理这个列表。我用SQLite数据库浏览器创建了一个数据库,并将数据库复制到资产文件夹(名称:sqbeerlist)中。 现在我创建了一个DatabaseHelper类来打开文件并将其写入一个数组列表。 但是当我想Android SQL数据库 - rawQuery()来源未找到

 Cursor c = myDataBase.rawQuery("SELECT _id, brand FROM " + DATABASE_TABLE, null); 

的DVM崩溃进入电影行和它说找不到源代码。我究竟做错了什么 ??

这里是整个助手类:

package com.celticwolf.alex; 

    import java.io.FileOutputStream; 

    import java.io.IOException; 

    import java.io.InputStream; 

    import java.io.OutputStream; 

    import java.util.ArrayList; 

    import android.content.Context; 

    import android.database.Cursor; 

    import android.database.SQLException; 

    import android.database.sqlite.SQLiteDatabase; 

    import android.database.sqlite.SQLiteDatabase.CursorFactory; 

    import android.database.sqlite.SQLiteException; 

    import android.database.sqlite.SQLiteOpenHelper; 

    public class DataBaseHelper extends SQLiteOpenHelper { 

    // The Androids default system path of your application database. 

    private static String DB_PATH = "/data/data/com.celticwolf.alex/databases/"; 

    private static String DB_NAME = "sqbeerlist"; 

    private static final String DATABASE_TABLE = "beers"; 

    private SQLiteDatabase myDataBase; 

    public static final String KEY_ROWID = "_id"; 

    public static final String KEY_NAME = "brand"; 

    public static final String KEY_COUNTRY = "country"; 

    private final Context myContext; 

    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 doesnt 
    */ 

    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 doest 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(); 

    } 

    public ArrayList gettheArray() { 

     ArrayList result = new ArrayList(); 

     try { 

      openDataBase(); 

     }catch(SQLException sqle){ 

      throw sqle; 

     } 

     Cursor c = myDataBase.rawQuery("SELECT _id, brand FROM " + DATABASE_TABLE, null); 

     c.moveToFirst(); 

     // Check if our result was valid. 

     if (c != null) { 

      // Loop through all Results 

      do { 

       result.add(c.getString(c.getColumnIndex(KEY_NAME))); 

      } while (c.moveToNext()); 

     } 

     close(); 

     return result; 

    } 

    @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(null); 
    myDbHelper = new DataBaseHelper(this); 

    try { 
     myDbHelper.createDataBase(); 

} catch (IOException ioe) { 

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

} 

      ArrayList<String> thelist = myDbHelper.gettheArray(); 

谢谢你,我希望有人能帮助(:

=== ================================================== ====================================== 问题解决! 这里是正确的代码! 这个标志标志着变化:C == 3

 
    package com.celticwolf.alex; 

    import java.io.FileOutputStream; 

    import java.io.IOException; 

    import java.io.InputStream; 

    import java.io.OutputStream; 

    import java.util.ArrayList; 

    import android.content.Context; 

    import android.database.Cursor; 

    import android.database.SQLException; 

    import android.database.sqlite.SQLiteDatabase; 

    import android.database.sqlite.SQLiteDatabase.CursorFactory; 

    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.celticwolf.alex/databases/"; 

    private static String DB_NAME = "sqbeerlist.sqlite"; 

    private static final String DATABASE_TABLE = "beers"; 

    private SQLiteDatabase myDataBase; 

    public static final String KEY_ROWID = "_id"; 

    public static final String KEY_NAME = "brand"; 

    public static final String KEY_COUNTRY = "country"; 

    private final Context myContext; 

    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(); 
     SQLiteDatabase db_Read = null; // c==3 

     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. 

      db_Read = this.getReadableDatabase(); // c==3 
      db_Read.close(); // c==3 

      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 doesnt 
    */ 

    private boolean checkDataBase() { 

     SQLiteDatabase checkDB = null; 

     try { 

      String myPath = DB_PATH + DB_NAME; 

      checkDB = SQLiteDatabase.openDatabase(myPath, null, 
        (SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS)); // c==3 

     } catch (SQLiteException e) { 

      // database doesnt 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 | SQLiteDatabase.NO_LOCALIZED_COLLATORS)); // c==3 

    } 

    @Override 
    public synchronized void close() { 

     if (myDataBase != null) 

      myDataBase.close(); 

     super.close(); 

    } 

    public ArrayList gettheArray() { 

     ArrayList result = new ArrayList(); 

     try { 

      openDataBase(); 

     }catch(SQLException sqle){ 

      throw sqle; 

     } 

     Cursor c = myDataBase.rawQuery("SELECT _id, brand FROM " + DATABASE_TABLE, null); 

     c.moveToFirst(); 

     // Check if our result was valid. 

     if (c != null) { 

      // Loop through all Results 

      do { 

       result.add(c.getString(c.getColumnIndex(KEY_NAME))); 

      } while (c.moveToNext()); 
     } 
     close(); 
     return result; 
    } 

    @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 itd 
    // be easy 
    // to you to create adapters for your views. 
} 

回答

2

我跨越最初复制数据库前一段时间有这个问题。

我结束了创建使用资源从头数据库(资产或原料)中的应用程序第一次运行的CSV格式(显然,这可能需要稍多的空间)

看看this thread和看看它是否有帮助。

+0

谢谢你的sooo多!此线程与Waqas解决方案完全解决了我的问题!真棒!我会在上面发布正确的类。 – LxSwiss 2012-04-11 23:47:36

2

你需要用SQLiteDatabase.NO_LOCALIZED_COLLATORS打开你的数据库,因为当你从android外部创建数据库时,它不包括android框架需要的表android_metadata

因此,如下打开数据库:

checkDB = SQLiteDatabase.openDatabase(myPath, null, 
     (SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS)); 

希望它应该解决您的问题

+0

不..没有解决问题。即使我对myDataBase = SQLiteDatabase.openDatabase(myPath,null,(SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS))也是这样做的; – LxSwiss 2012-04-11 13:06:51

+0

谢谢!您的解决方案与Steve_k的解决方案一起解决了问题!我会在上面发布正确的代码。 – LxSwiss 2012-04-11 23:48:53