7

みんな、ローカル資産フォルダーから /data/data/package_name/databases ディレクトリにデータベースをコピーするときに問題があります。http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/チュートリアルを使用 してそれを行うと、空のファイルしか取得できません。

copyDataBase() メソッドの部分を引用しましたが、違いはありません。アプリが起動するたびに、ディレクトリと空のデータベースが作成されます。copyDataBase() を機能させる方法はありますか?

どうもありがとうございました!!

4

5 に答える 5

15

アセットからコピーしないのはなぜですか? そうするのは完全に正常です。ただし、onCreate でそれを行うことはできません。その時点で、空のデータベースが既に作成されています。事前に行う必要があります。私は通常、getWriteableDatabaseのオーバーライドでそれを行います。

public synchronized SQLiteDatabase getWritableDatabase() {
    SQLiteDatabase db = null;

    if (!doesDatabaseExist()) {
        try {
            copyDatabase();
            db = super.getWritableDatabase();
        } catch(Exception ex) {
            Log.e("Database Log", getDatabasePath() + " failed to copy correctly. " + ex.getLocalizedMessage());
        }
    }
    else {
        db = super.getWritableDatabase();
    }

    return db;
}
于 2011-06-30T20:59:00.400 に答える
1

assets-folder からデータベースをコピーしません。データベースに標準エントリが必要な場合は、メソッドでINSERTs を使用して追加できますonCreate()


更新:これは間違っているために反対票を投じられており (これはちょっと正しい)、削除できないため、少し更新します。

データベースに追加する標準エントリの数によって異なります。1 つまたは 2 つだけの場合、パッケージ化された DB を出荷する価値はありません。

とにかく、一部のアプリにはかなり大きなデータベースが付属しています (たとえば、レシピ コレクション)。もちろん、これらすべてをコードに追加することはできません。

  • 小さなテスト エントリの場合は、単純に に追加することをお勧めしonCreate()ます。
  • 大規模なデータベースの場合は、それらを事前に入力して、アプリと一緒に出荷する必要があります。

assets/後者が機能するには、データベース ファイルを app-folderにコピーする必要があります。あなたのためにそれを処理する素晴らしいライブラリがあります: android-sqlite-asset-helper

于 2011-05-25T06:43:32.203 に答える
0

私が使用するシンプルで便利なコードは次のとおりです。

public class DataBaseImportHelper {
    private DataBaseImportHelper() {}; // Avoid instantiation

/**
 * Creates a empty database on the system and rewrites it with your own database.
 */
public static boolean importDataBase(Context context) {
    InputStream myInput = null;
    OutputStream myOutput = null;
    try {
        // Open local db from assets as the input stream
        myInput = context.getAssets().open(DATABASE_NAME);
        createEmptyDatabase(context); // See this method below
        // Open the empty db as the output stream
        myOutput = new FileOutputStream(getDatabaseFile(context));

        // 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();
        myInput.close();
        myOutput.close();
        return true;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

/**
 * Check if the database already exists.
 * @return true if it exists, false if it doesn't
 */
public static boolean isDatabaseExists(Context context) {
    return getDatabaseFile(context).exists();
}

private static File getDatabaseFile(Context context) {
    return context.getDatabasePath(DatabaseHelper.DATABASE_NAME);
}

/**
 * Create an empty database into the default application database
 * folder.So we are gonna be able to overwrite that database with our database
 */
private static void createEmptyDatabase(Context context) {
            // use anonimous helper to create empty database
    new SQLiteOpenHelper(context, DatabaseHelper.DATABASE_NAME, null, 1) {
                    // Methods are empty. We don`t need to override them
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
        }
    }.getReadableDatabase().close();
}

}

そしてコードで使用する:

if(!DataBaseImportHelper.isDatabaseExists(this)){
    if (!DataBaseImportHelper.importDataBase(this)){
            throw new IllegalStateException("Database doesn`t exist and hasn`t been copied!");
    }
}
于 2013-02-20T07:20:10.273 に答える
0

上の例では、このように私のために働いた:

db = super.getWritableDatabase();
db.close;
copyDatabase();

そうしないと、IO エラーが発生しました。

于 2012-07-21T17:40:25.677 に答える