копирование sqlite db на устройство Android не удается - PullRequest
4 голосов
/ 26 марта 2011

У меня есть база данных sqlite, которую я скопировал в папку 'asset'.В своей проге я проверяю, существует ли база данных, если нет, создаю новую и копирую ее.Я использовал (более или менее) код из http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/comment-page-2/

    public void createDataBase() throws IOException {
    boolean dbExist = checkDataBase();

    if (dbExist) {
        Log.i(DEBUG_TAG, "createDataBase -> Datenbank existiert");
        // 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();
        Log.i(DEBUG_TAG, "else, db existiert nicht 1");
        try {
            copyDataBase();
            Log.i(DEBUG_TAG, "nach copydatabase");
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

/**
 * Checked ob Database bereits existiert
 * 
 * @return
 */
private boolean checkDataBase() throws SQLiteException {
    SQLiteDatabase checkDB = null;
    Boolean checkTable = false;
    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);
        Log.i(DEBUG_TAG, "checkdatabase1");

    } catch (SQLiteException e) {
        Log.e(DEBUG_TAG, "Fehler checkDataBase: ", e);
    }
    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 = dbContext.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();
    Log.i(DEBUG_TAG, "copydatabase");
}

В эмуляторе он работает отлично.

Я попытался запустить его на своем устройстве (HTC Desire HD).Там я получаю следующее сообщение:

03-26 17:02:05.053: INFO/Database(24458): sqlite returned: error code = 14, msg = cannot open file at line 27206 of [42537b6056]

Это происходит, когда я пытаюсь в первый раз открыть БД.Когда я запускаю Программу в эмуляторе, я не получаю это сообщение.Когда я запускаю программу 2 раза, она находит базу данных, ошибок при открытии нет, но таблицы не существуют.

Я несколько раз отлаживал программу на эмуляторе и устройстве, но не смогнайти какое-либо решение.

Может быть, это какая-то проблема с разрешениями?(Так как я также не могу видеть БД на устройстве с adb -> разрешение запрещено ')

Я очень плохо знаком с Android, поэтому, возможно, я просто пропустил что-то глупое ....

Спасибо

Ответы [ 2 ]

0 голосов
/ 06 сентября 2012

Я делаю это, создавая свой собственный каталог и помещая файл в каталог

String path=mContext.getDir("Folder_name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();

Код для создания папки.

Затем выполните нашу проверку базы данных и скопируйте ее.

enter code here 

 public void createDataBase() throws IOException { 
 String path=mContext.getDir("Folder_Name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();
 DB_PATH=path;
 boolean mDataBaseExist = checkDataBase(); 
 if(!mDataBaseExist) 
 { 
   try  
    { 
     copyDataBase(); 
    }  
    catch (IOException mIOException)  
    { 
    Log.d("Exception",mIOException.getMessage());
    throw new Error("ErrorCopyingDataBase"); 
    } 
} 
}


private boolean checkDataBase() 
{ 
    Log.d(TAG, "In checkDataBase :::::"); 
    File dbFile = new File( DB_PATH+DATABASE_NAME); 
    Log.d("dbFile", dbFile + "   "+ dbFile.exists()); 
    return dbFile.exists(); 
} 

//Copy the database from assets 
private void copyDataBase() throws IOException 
{ 
    Log.d(TAG, "In copyDataBase :::::"); 
    InputStream mInput = mContext.getAssets().open(DB_NAME);
    String outFileName = DB_PATH  + DATABASE_NAME;

    Log.d(TAG, "In copyDataBase  outFileName:::::"+outFileName);

    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 
{ 
    //DB_PATH +
    String mPath = DB_PATH+ DATABASE_NAME; 
    Log.v("mPath", mPath); 
    mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
    return mDataBase != null; 
} 

Надеюсь, это поможет новичкам.

Приветствия

0 голосов
/ 26 марта 2011
  1. Не создавать пути с помощью конкатенации строк. Используйте соответствующий конструктор File.
  2. Ваш DB_PATH может быть недействительным, но так как вы отказались показать его, мы не можем сказать наверняка.
  3. Если класс, из которого происходит этот код, является SQLiteOpenHelper, ваш вызов getReadableDatabase() создаст пустую базу данных.
  4. "(Так как я также не могу увидеть базу данных на устройстве с adb -> в доступе отказано '" - это ожидается, поскольку у вас нет прав на просмотр этого каталога на производственном устройстве.
...