私はいくつかの基本的な理解の問題があると思うので、誰かが助けることができるかもしれません:-)
私はAndroidアプリケーションを開発しています。このアプリケーションはデータベースを使用します(データベースからの読み取りのみが実装されます)。データベースには約4,000のエントリが含まれています。ソースコードを使用することはできませんので、すべてのレコードを含むデータベースを事前に作成しました。
しかし、どうすればこのデータベースファイルをアプリケーションに「埋め込み」、それからアクセスできますか?データベースのファイルサイズは約500 KBです。リモートサーバーからのダウンロードも許可されていないため、これもオプションではありません。
ありがとう、ロバート
私はその問題を次のように解決しました:
追加file.db
をproject/assetsフォルダーに入れます。
次のクラスを書く:
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;
}
}
ReignDesignブログの素晴らしい記事 Android applications で独自のSQLiteデータベースを使用する。基本的には、データベースを事前に作成し、apkのアセットディレクトリに配置します。 「/ data/data/YOUR_PACKAGE/databases /」ディレクトリへのコピーを使用します。
これまでに、アプリケーションのres/raw
リソースにJSONファイルを格納し、最初のロード時にファイルをロードすることでこれを行いました。そこから、一括挿入モードを使用してエントリをバッチインポートできます。この手法の例として、 nitsのデータベースローダー を参照してください。 res/raw
スタイルの1つの利点は、Androidリソース選択システムを使用してデータを異なる地域にローカライズできるため、異なるデータベース(またはその一部)を使用できることです異なる言語または地域。
生のSQLダンプを同様のファイルに入れて、最初のロード時にロードすることもできます。 openRawResource(int) を使用して、リソースからファイルを取得できます。事前に作成されたsqliteデータベースファイルを保存する代わりにこれをお勧めします。これにより、sqliteのバージョン間の互換性が高まり、データベースの保守が容易になります(アプリ開発ライフサイクルのPOVから)。
一括でロードする場合は、トランザクションを使用してください。トランザクションを使用すると、処理が高速化され、ロードの信頼性が高まります。
この答え へのコメントで、CommonsWareは、@ eviloneが提案したのと同じ方法(つまり、自分でアセットからデータベースをコピーする)を推奨しません。代わりに、実証済みのテスト済み SQLiteAssetHelper
を使用する必要があります。私はこれをAndroid Studioで使用しましたが、うまく機能します。
directions はかなり明確です。主な抜粋をいくつか次に示します。
Gradleビルドシステムを使用している場合は、次の依存関係を_
build.gradle
_ファイルに追加するだけです。
_dependencies {
compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
}
_
SQLiteAssetHelper
をSQLiteOpenHelper
と同じように拡張し、データベース名とバージョン番号をコンストラクタに提供します。
_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()
が初めて呼び出されたときに使用可能になります。