问题 从 Android Studio 中的资产文件夹中读取 SQLite 版本 3



我像这样用C#.net构建sqlite

SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
if (!File.Exists("MyDatabase.sqlite"))
{
SQLiteConnection.CreateFile("MyDatabase.sqlite");
m_dbConnection.Open();
string sql = "CREATE TABLE IF NOT EXISTS farmakology(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,tabaghe TEXT,name TEXT,enname TEXT,img TEXT,farmaco TEXT,amal TEXT,balin TEXT,masraf TEXT,tadakhol TEXT,amozesh TEXT,avarez TEXT);";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
command.ExecuteNonQuery();
}

然后我将一些数据存储到这个 sqlite 并将其复制到我的 android 项目的 assets 文件夹中,然后使用以下代码读取它:

public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "MyDatabase.sqlite";
private static final int DATABASE_VERSION = 3;
private static final String ENNAME="enname";
private static final String POSES_TABLE="farmakology";
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public ArrayList<Poses> getPoses(){
SQLiteDatabase db=getWritableDatabase();
String[] columns={MyDatabase.ENNAME};
Cursor cursor=db.rawQuery("SELECT * FROM farmakology" , null);
ArrayList<Poses> questionsArrayList=new ArrayList<>();
while(cursor.moveToNext()){
Poses questions=new Poses();
questions.enname=cursor.getString(cursor.getColumnIndex(MyDatabase.ENNAME));
questionsArrayList.add(questions);
}
return questionsArrayList;
}
}

但是,logcat 显示此错误(没有这样的表(

java.lang.RuntimeException: Unable to start activity ComponentInfo{ir.toolha.pharmacology/ir.toolha.pharmacology.asli}: android.database.sqlite.SQLiteException: no such table: farmakology (code 1): , while compiling: SELECT * FROM farmakology

问题出在哪里? 如何解决?

编辑

我也使用SQLiteOpenHelper,但仍然没有帮助,对我不起作用

public class SqlLiteDataBaseHelper extends SQLiteOpenHelper {
private static final String TAG = SqlLiteDataBaseHelper.class.getSimpleName();
private static final int DATABASE_VERSION = 3;
private static final String DATABASE_PATH = "/data/data/ir.toolha.pharmacology/databases/";
private static final String DATABASE_NAME = "MyDatabase.sqlite";
private static final String TABLE_NAME = "farmakology";
private static final String COL_Name = "enname";
private Context context;
private SQLiteDatabase db;
public SqlLiteDataBaseHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}

//This method is just retuning total no of recode in your table Getting single contact count
public int  getDataCount() {
String userRollNo = null;
String query = "SELECT * FROM " + TABLE_NAME ;
Cursor cursor = db.rawQuery(query, null);
return cursor.getCount();
}

public void openDataBase () throws SQLException {
String path = DATABASE_PATH+DATABASE_NAME;
db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.CREATE_IF_NECESSARY);
}
public void CopyDataBaseFromAsset() throws IOException {
InputStream in  = context.getAssets().open(DATABASE_NAME);
Log.e("sample", "Starting copying");
String outputFileName = DATABASE_PATH+DATABASE_NAME;
File databaseFile = new File( "/data/data/ir.toolha.pharmacology/databases");
// check if databases folder exists, if not create one and its subfolders
if (!databaseFile.exists()){
databaseFile.mkdir();
}
OutputStream out = new FileOutputStream(outputFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer))>0){
out.write(buffer,0,length);
}
Log.e("sample", "Completed" );
out.flush();
out.close();
in.close();
}
public void deleteDb() {
File file = new File(DATABASE_PATH);
if(file.exists()) {
file.delete();
Log.d(TAG, "Database deleted.");
}
}
public boolean checkDataBase() {
boolean checkDB = false;
try {
File file = new File(DATABASE_PATH);
checkDB = file.exists();
} catch(SQLiteException e) {
Log.d(TAG, e.getMessage());
}
return checkDB;
}
}

Java 代码中存在一些错误。

您将数据库存储在资产文件夹中。因此,在使用它之前,必须将其复制到正确的数据库文件夹。这可以通过CopyDataBaseFromAsset().但是,您的代码不会调用该方法。

因此,我建议按如下方式更新您的代码:

SqlLiteDataBaseHelper.java

此类仅用于打开数据库。您不在此处执行查询。它应该只管理数据库的创建。 我刚刚删除了一些方法并更新了构造函数。

public class SqlLiteDataBaseHelper extends SQLiteOpenHelper {
private static final String TAG = SqlLiteDataBaseHelper.class.getSimpleName();
private static final int DATABASE_VERSION = 3;
private static final String DATABASE_PATH = "/data/data/ir.toolha.pharmacology/databases/";
private static final String DATABASE_NAME = "MyDatabase.sqlite";
private static final String TABLE_NAME = "farmakology";
private static final String COL_Name = "enname";
public SqlLiteDataBaseHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
if (!checkDataBase()) {
try {
CopyDataBaseFromAsset();
} catch (IOException e) {
throw new RuntimeException("Error creating source database", e);
}
}
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// Do nothing here
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
// Do nothing here
}
public void CopyDataBaseFromAsset() throws IOException {
InputStream in  = context.getAssets().open(DATABASE_NAME);
Log.e("sample", "Starting copying");
String outputFileName = DATABASE_PATH+DATABASE_NAME;
File databaseFile = new File( "/data/data/ir.toolha.pharmacology/databases");
// check if databases folder exists, if not create one and its subfolders
if (!databaseFile.exists()){
databaseFile.mkdir();
}
OutputStream out = new FileOutputStream(outputFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer))>0){
out.write(buffer,0,length);
}
Log.e("sample", "Completed" );
out.flush();
out.close();
in.close();
}
public boolean checkDataBase() {
boolean checkDB = false;
try {
File file = new File(DATABASE_PATH);
checkDB = file.exists();
} catch(SQLiteException e) {
Log.d(TAG, e.getMessage());
}
return checkDB;
}
}

我的数据库.java

然后,创建一个新类,该类将负责从数据库中读取值并转换为正确的格式(在您的情况下,转换为数组列表(

public class MyDatabase {
private SqlLiteDataBaseHelper mSqlHelper;
public MyDatabase(Context context) {
mSqlHelper = new SqlLiteDataBaseHelper(context);
}
public ArrayList<Poses> getPoses(){
SQLiteDatabase db = mSqlHelper.getWritableDatabase();
String[] columns={MyDatabase.ENNAME};
Cursor cursor=db.rawQuery("SELECT * FROM farmakology" , null);
ArrayList<Poses> questionsArrayList=new ArrayList<>();
// You need to move to first item before doing anything
if(cursor != null) {
if(cursor.moveToFirst()) {
while(cursor.moveToNext()){
Poses questions=new Poses();
questions.enname=cursor.getString(cursor.getColumnIndex(MyDatabase.ENNAME));
questionsArrayList.add(questions);
}
}
cursor.close(); // Don't forget to close the cursor.
}
db.close(); // Don't forget to close the database once your job is done
return questionsArrayList;
}
}

重要:

  1. 您必须将数据库从资产文件夹复制到正确的数据库文件夹 (/data/data/ir.toolha.pharmacology/databases/(

  2. SQLiteOpenHelper帮助您打开和关闭数据库。

  3. 打开数据库、
  4. 读取值、关闭数据库并返回结果需要第三个类。

  5. 您可以将所有内容封装在单个类中。但是,我认为最好将这些代码分成两类。

  6. 我没有测试我建议的代码。因此,请谨慎使用..我在这里的目的只是展示您应该在代码中改进的要点。

希望对您有所帮助

为什么不使用SQLiteOpenHelper而不是SQLiteAssetHelper,并在onCreate中创建数据库:

public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "MyDatabase.sqlite";
private static final int DATABASE_VERSION = 3;
private static final String ENNAME="enname";
private static final String POSES_TABLE="farmakology";
string sql = "CREATE TABLE IF NOT EXISTS farmakology(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,tabaghe TEXT,name TEXT,enname TEXT,img TEXT,farmaco TEXT,amal TEXT,balin TEXT,masraf TEXT,tadakhol TEXT,amozesh TEXT,avarez TEXT);";
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(sql);
}
}

相关内容

最新更新