Продолжение проблемы с открытием уже существующей базы данных sqlite в Android - PullRequest
3 голосов
/ 20 февраля 2012

Новичок здесь. Я получил некоторую хорошую информацию в предыдущем посте, который я сделал, и я надеюсь, что смогу получить немного больше помощи :) Спасибо за поиск.

Я отправляю предварительно заполненную базу данных sqlite с приложением. Я прошел процесс копирования базы данных из моей папки ресурсов в исходном коде в папку / database / через процедуру, которую я нашел в Интернете, и я уверен, что вы все знакомы (http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/). Похоже, это работает правильно. Используя DDMS, я могу видеть, как база данных копируется и отображается в соответствующем каталоге.

Теперь, однако, я не получаю никаких результатов. Когда я проверяю logcat, я вижу следующие ошибки при попытке открыть БД:

02-19 14:59:40.490: I/Database(4071): sqlite returned: error code = 14, msg = cannot open file at source line 25467
02-19 14:59:40.490: E/Database(4071): sqlite3_open_v2("/data/data/com.testapp.test/databases/pbaMainDb.sqlite", &handle, 2, NULL) failed

РЕДАКТИРОВАТЬ: Вот класс ListScreen, который я использую, чтобы открыть базу данных после установки и выполнить простой запрос из:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.lists);

   DbHelper db = new DbHelper(this);
    db = new DbHelper(this);



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



    try {
    myDbHelper.close();
    db.openDataBase(); 
    } catch(SQLException sqle){
        throw sqle;
  }




}


public Cursor fetchAllTables() {

    return myDbHelper.rawQuery("SELECT name FROM sqlite_master WHERE type='table'",
            new String[]{});

}

private void fillData() {

    //Cursor c = fetchAllTables();
    //startManagingCursor(c);

    String[] from = new String[] {"name"};
    int[] to = new int[] {R.id.listview};


    SimpleCursorAdapter notes = 
            new SimpleCursorAdapter (this, R.layout.list_view, cursor, from, to);
    setListAdapter(notes);

            }

    }

РЕДАКТИРОВАТЬ: Кроме того, из моего класса DbHelper (где код должен копировать мой существующий Db), вот код, где я делаю это (я извиняюсь, это немного дамп):

    public class DbHelper extends SQLiteOpenHelper {
// the default android path of the database files it creates
private static String DB_PATH = "/data/data/com.testdata.test/databases/";
private static String DB_NAME = "pbaMainDb.sqlite";
private SQLiteDatabase myDataBase;
private final Context myContext;

// constructor to keep a reference of the passed context in order to access the 

public DbHelper (Context context) {
    super(context, DB_NAME, null, 1);
    this.myContext = context;
}

// Create an empty database and then rewrite with original

public void createDatabase() throws IOException {
    boolean dbExist = CheckDataBase();
    if (dbExist) {
        // if exists, do nothing
    }else {
        //when we call this method the empty database will be created into 
        this.getReadableDatabase();
        try {
                copyDataBase();
        }
        catch (IOException e) {
                throw new Error("Error copying database");
        }
}
    this.close();
}

        // Check if the database already exists to avoid re-copy
private boolean CheckDataBase() {
    SQLiteDatabase checkDB = null;

    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null                 SQLiteDatabase.OPEN_READWRITE);
        //File dbfile = new File(myPath);
        //return dbfile.exists();
    } catch (SQLiteException e) {
            //database doesn't exist yet
    }
    if (checkDB != null) {
            checkDB.close();
    }
    return checkDB != null ? true : false;
}   
  // Copies database from assets folder to new empty folder

    private void copyDataBase() throws IOException {
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        //path to just created DB

        String outFileName = DB_PATH + DB_NAME;

        OutputStream myOutput = new FileOutputStream (outFileName);

        //transfer bytes from input file to output file

        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        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_READWRITE);
    }
    @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) {
    }

}

Ответы [ 2 ]

1 голос
/ 20 февраля 2012

Это может показаться простым, но попробуйте удалить расширение из имени базы данных.то есть, укажите путь "/data/data/com.testapp.test/databases/pbaMainDb" и снимите расширение с файла, когда вы также поместите его в папку ресурсов.

Кроме того, я думаю, что может быть ограничение размера файла базы данных.Насколько велик ваш файл?

И еще одна возможность: сразу после сбоя приложения снова откройте его (не компилируйте и не устанавливайте, а просто снова откройте на устройстве) и посмотрите, работает ли он.Иногда папка databases не создается в первый раз, поэтому вам, возможно, придется войти и создать ее с помощью чего-то вроде

File f = new File(DB_PATH);
if (!f.exists()) {
    f.mkdir();
}

РЕДАКТИРОВАТЬ: еще пара вопросов.После просмотра учебника, который вы использовали, вы также использовали метод createDataBase(), как он показывает в самом конце?

Кроме того, перед выполнением запроса попробуйте вызвать myDbHelper.close();, а затем снова вызвать метод open,Возможно, что созданная им в учебнике пустая версия все еще открыта и должна быть закрыта в первый раз около

Дайте мне знать, как это происходит, и я постараюсь продолжать помогать вам, если это необходимо.1016 *

РЕДАКТИРОВАТЬ: Замените ваши onCreate и fetchAllTables на мои правки ниже.По какой-то причине вы создали два экземпляра класса DbHelper, поэтому я удалил его.Кроме того, я не вижу, где вы объявили myDbHelper, что вы использовали в onCreate, но избавьтесь от всех ссылок на это.Мы будем использовать только один экземпляр DbHelper для взаимодействия с базой данных, и это db.Как вы можете видеть, я создаю это как переменную класса, которую мы будем использовать по всему классу, и создадим и откроем один раз в onCreate.Также обратите внимание, что ошибка изменится, потому что я сейчас сосредоточен только на том, чтобы заставить работать открытие базы данных.

DbHelper db;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.lists);

    db = new DbHelper(this);

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

    try {
        db.close();
        db.openDataBase(); 
    } catch(SQLException sqle){
        throw sqle;
    }
}

public Cursor fetchAllTables() {
    return db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
}
0 голосов
/ 15 марта 2014

У меня была такая же проблема, но, как сказал один из комментариев в "http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications", я просто сделал это:

заменить эту строку

String myPath = DB_PATH + DB_NAME;

в checkDataBase() метод с этим:

String myPath = Environment.getExternalStorageDirectory() + "/" + DB_NAME;

Это хорошо сработало для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...