проблема чтения sqlite версии 3 из папки активов в Android Studio - PullRequest
0 голосов
/ 24 октября 2018

Я создаю sqlite с помощью C # .net следующим образом

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 и копирую их в папку assets моего проекта Android, а затем использую этот код для чтения:

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

где проблема?как это исправить?

EDITED

Я также использую 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;
    }
}

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

В вашем 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;
    }
}

MyDatabase.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. Я не проверял код, который я предложил .. Итак, используйте с осторожностью ... мое намерение здесьпросто покажите те моменты, которые вы должны улучшить в своем коде.

Надеюсь, это поможет вам

0 голосов
/ 24 октября 2018

Почему бы вам не использовать 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);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...