2013-06-24 2 views
0

У меня есть база данных sqlite db в папке с ресурсами, и для первого запуска моего приложения я копирую его на путь «данные/данные/базы данных».Android: скопируйте sqlite из активов до Gingerbread

Это прекрасно работает на всех устройствах от Gingerbread, но для более старых версий я получаю исключение таблицы, которое не найдено, когда я запрашиваю db. Фактически папка db в базах данных пуста. Он содержит только таблицу android_metadata.

Вот эти два метода, которые я использую, чтобы скопировать БД:

public static void copyDBInMemoryIfNeeded(Context ctx, String pkgName) { 
    try { 
     String destPath = ctx.getFilesDir().getParentFile().getPath() + "/databases"; 
     File f = new File(destPath); 
     if (!f.exists()) { 
      f.mkdirs(); 
      f.createNewFile(); 
      copyDBInMemory(ctx.getAssets().open("mydb.sqlite"), 
        new FileOutputStream(destPath)); 
     } 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private static void copyDBInMemory(InputStream inputStream, OutputStream outputStream) 
     throws IOException { 
    // ---copy 1K bytes at a time--- 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = inputStream.read(buffer)) > 0) { 
     outputStream.write(buffer, 0, length); 
    } 
    inputStream.close(); 
    outputStream.close(); 
} 

и вот мой класс DBAdapter:

public class DBAdapter {  

final Context context; 
DatabaseHelper DBHelper; 
SQLiteDatabase db; 

public DBAdapter(Context ctx) { 
    this.context = ctx; 
    DBHelper= new DatabaseHelper(context); 
} 

private static class DatabaseHelper extends SQLiteOpenHelper { 

    DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion 
       + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS contacts"); 
     onCreate(db); 
    } 
} 

public DBAdapter open() throws SQLException { 
    db = DBHelper.getWritableDatabase(); 
    return this; 
} 

public void close() { 
    DBHelper.close(); 
}                        } 
+0

Насколько велик ваш файл sql в папке с ресурсами? – hardartcore

+0

это 4.7 мегабайт – TheModularMind

ответ

0

Я закончил разделение базы данных на HJSplit и затем поместил части в папку с ресурсами. Затем я копирую db в «данные/данные/базы данных» следующим образом:

private static void copyDataBase(Context ctx, FileOutputStream os) throws IOException { 
    AssetManager am = ctx.getAssets(); 
    byte[] b = new byte[1024]; 
    int r; 
    for (int i = 1; i <= 5; i++) { 
     InputStream is = am.open("mydb.sqlite.00" + i); 
     while ((r = is.read(b)) != -1) { 
      os.write(b, 0, r); 
     } 
     is.close(); 
    } 
    os.close(); 
} 
1

В Android 2.2 и ниже есть то, что вы должны учитывать при использовании SQLite файлы в папке с ресурсами. Файл размером более 1 МБ не сможет быть скопирован в папку личных баз приложений. Не уверен, что это ошибка или что-то еще, но если вы хотите использовать свою базу данных, вы можете создать целую схему базы данных в помощнике базы данных.

Обход: Не уверен, если это хороший вариант, но он работает в моей ситуации с базой данных 12MB SQLite, просто удалите .sqlite, .db или какое-либо расширения базы данных от имени вашего файла, и он должен сделать трюк.

+0

спасибо за разъяснение! Я пробовал ваш обходной путь, но, к сожалению, это не работает для меня ... Я попытаюсь разделить свой db в разных файлах и поместить их в папку с ресурсами. – TheModularMind

+0

Попробуйте поместить некоторые другие расширения файлов, если хотите, я пытался один раз с .mp3, и это действительно сработало. – hardartcore