web-dev-qa-db-ja.com

SQLiteデータベースをアプリケーションに埋め込むにはどうすればよいですか?

私はいくつかの基本的な理解の問題があると思うので、誰かが助けることができるかもしれません:-)

私はAndroidアプリケーションを開発しています。このアプリケーションはデータベースを使用します(データベースからの読み取りのみが実装されます)。データベースには約4,000のエントリが含まれています。ソースコードを使用することはできませんので、すべてのレコードを含むデータベースを事前に作成しました。

しかし、どうすればこのデータベースファイルをアプリケーションに「埋め込み」、それからアクセスできますか?データベースのファイルサイズは約500 KBです。リモートサーバーからのダウンロードも許可されていないため、これもオプションではありません。

ありがとう、ロバート

31
Robert Strauch

私はその問題を次のように解決しました:

  1. 追加file.dbをproject/assetsフォルダーに入れます。

  2. 次のクラスを書く:

    public class LinnaeusDatabase extends SQLiteOpenHelper{
    
        private static String DATABASE_NAME = "Dragonfly.db";
        public final static String DATABASE_PATH = "/data/data/com.kan.linnaeus/databases/";
        private static final int DATABASE_VERSION = 1;
    
        private SQLiteDatabase dataBase;
        private final Context dbContext;
    
        public LinnaeusDatabase(Context context) {
            super(context, DBActivity.DatabaseName, null, DATABASE_VERSION);
            this.dbContext = context;
            DATABASE_NAME = DBActivity.DatabaseName;
            // checking database and open it if exists
            if (checkDataBase()) {
                openDataBase();
            } else
            {
                try {
                    this.getReadableDatabase();
                    copyDataBase();
                    this.close();
                    openDataBase();
    
                } catch (IOException e) {
                    throw new Error("Error copying database");
                }
                Toast.makeText(context, "Initial database is created", Toast.LENGTH_LONG).show();
            }
        }
    
        private void copyDataBase() throws IOException{
            InputStream myInput = dbContext.getAssets().open(DATABASE_NAME);
            String outFileName = DATABASE_PATH + DATABASE_NAME;
            OutputStream myOutput = new FileOutputStream(outFileName);
    
            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 {
            String dbPath = DATABASE_PATH + DATABASE_NAME;
            dataBase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
        }
    
        private boolean checkDataBase() {
            SQLiteDatabase checkDB = null;
            boolean exist = false;
            try {
                String dbPath = DATABASE_PATH + DATABASE_NAME;
                checkDB = SQLiteDatabase.openDatabase(dbPath, null,
                SQLiteDatabase.OPEN_READONLY);
            } catch (SQLiteException e) {
                Log.v("db log", "database does't exist");
            }
    
            if (checkDB != null) {
                exist = true;
                checkDB.close();
            }
            return exist;
        }
    }
    
27

ReignDesignブログの素晴らしい記事 Android applications で独自のSQLiteデータベースを使用する。基本的には、データベースを事前に作成し、apkのアセットディレクトリに配置します。 「/ data/data/YOUR_PACKAGE/databases /」ディレクトリへのコピーを使用します。

14
evilone

これまでに、アプリケーションのres/rawリソースにJSONファイルを格納し、最初のロード時にファイルをロードすることでこれを行いました。そこから、一括挿入モードを使用してエントリをバッチインポートできます。この手法の例として、 nitsのデータベースローダー を参照してください。 res/rawスタイルの1つの利点は、Androidリソース選択システムを使用してデータを異なる地域にローカライズできるため、異なるデータベース(またはその一部)を使用できることです異なる言語または地域。

生のSQLダンプを同様のファイルに入れて、最初のロード時にロードすることもできます。 openRawResource(int) を使用して、リソースからファイルを取得できます。事前に作成されたsqliteデータベースファイルを保存する代わりにこれをお勧めします。これにより、sqliteのバージョン間の互換性が高まり、データベースの保守が容易になります(アプリ開発ライフサイクルのPOVから)。

一括でロードする場合は、トランザクションを使用してください。トランザクションを使用すると、処理が高速化され、ロードの信頼性が高まります。

10
Steve Pomeroy

この答え へのコメントで、CommonsWareは、@ eviloneが提案したのと同じ方法(つまり、自分でアセットからデータベースをコピーする)を推奨しません。代わりに、実証済みのテスト済み SQLiteAssetHelper を使用する必要があります。私はこれをAndroid Studioで使用しましたが、うまく機能します。

directions はかなり明確です。主な抜粋をいくつか次に示します。

Gradleビルドシステムを使用している場合は、次の依存関係を_build.gradle_ファイルに追加するだけです。

_dependencies {
    compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
}
_

SQLiteAssetHelperSQLiteOpenHelperと同じように拡張し、データベース名とバージョン番号をコンストラクタに提供します。

_public class MyDatabase extends SQLiteAssetHelper {

    private static final String DATABASE_NAME = "northwind.db";
    private static final int DATABASE_VERSION = 1;

    public MyDatabase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
}
_

データベースを_assets/databases/northwind.db_に配置します(任意のデータベース名を使用します)。

データベースは、getReadableDatabase()またはgetWritableDatabase()が初めて呼び出されたときに使用可能になります。

5
Suragch