assetsにDBを置いてコピーしたい

このエントリーをはてなブックマークに追加

やりたいことはあらかじめ作成していおいたDBを使用したい。サンプルを作成してみた。
「MyDatabase.db」というDBを作成しておいて、プロジェクトの「assets」フォルダに置く。アプリインストール時にそれをコピーし、使用する。

1.DBを用意する。

今回は「MyDatabase.db」というDBを作成して、「assets」フォルダに置いた。
中身はこんな感じ。

_id Name
 1  田中
 2  高橋
 3  斉藤

2.「SQLiteOpenHelper」クラスを継承したクラスを作成する。

以下ソース

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {
    public static final String DATABASE_NAME = "MyDatabase.db";
    public static final int DATABASE_VERSION = 1;
    private Context context = null;

    public DatabaseHelper(Context context) {
    	super(context, DATABASE_NAME, null, DATABASE_VERSION);
    	this.context = context;

    	try {
    		if (! databaseExists()) {
				copyDb();
    		}
		} catch (IOException e) {
			e.printStackTrace();
		}
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    	try {
			copyDb();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }

    /**
   	 * dbファイルの存在チェック
   	 */
    private boolean databaseExists() {
    	File dbFile = new File(this.context.getFilesDir().getParent() + "/databases/" + DATABASE_NAME);

    	return dbFile.exists();
    }

    /**
	 * assetのdbファイルをコピーする
	 */
    private void copyDb() throws IOException {
    	// コピー先フォルダ
    	String copyFolder = this.context.getFilesDir().getParent() + "/databases/";

    	// フォルダがない場合は作成
    	File checkDirectory = new File(copyFolder);
    	if (! checkDirectory.exists()) {
    		checkDirectory.mkdir();
    	}

    	// ファイルのインプット、アウトプットのセット
    	InputStream in = this.context.getAssets().open(DATABASE_NAME);
    	OutputStream out = new FileOutputStream(copyFolder + DATABASE_NAME);

    	// ファイルのコピー
    	byte[] buf = new byte[1024];
    	int len = 0;
    	while ((len = in.read(buf)) > 0) {
    		out.write(buf, 0, len);
    	}

    	// インプット、アウトプットのクローズ
    	in.close();
    	out.close();
    }
}

3.メインのソース

2のクラスを使用し、DBを使用すればDBはコピーされて使用できるようになる。
以下ソース

import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Button button1 = (Button)this.findViewById(R.id.button1);
		button1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				DatabaseHelper dbHelper = new DatabaseHelper(MainActivity.this);
				SQLiteDatabase db = dbHelper.getReadableDatabase();
				Cursor c = db.rawQuery("SELECT * FROM Sample;", null);
				if (c.moveToFirst()) {
					do {
						Log.v("mytag", c.getString(c.getColumnIndex("Name")));
					} while (c.moveToNext());
				}
				c.close();
			}
		});
	}
}

4.実行

実行してみると、以下のログが出力されて、DBがコピーされているのがわかる。

03-02 20:31:32.098: V/mytag(7176): 田中
03-02 20:31:32.098: V/mytag(7176): 高橋
03-02 20:31:32.098: V/mytag(7176): 斉藤

5.DBのアップデート

DBをアップデートしたい場合は、2で作成したクラスの「DATABASE_VERSION 」を1上げて2にし、「assets」フォルダに新しいDBをコピーする。試しに、「MyDatabase.db」の項目を追加し実行してみる。以下DBの中身。

_id Name
 1  田中
 2  高橋
 3  斉藤
 4  白石

実行してみると、以下のログが出力され、アップデートされているのがわかる。

03-02 20:39:05.088: V/mytag(9921): 田中
03-02 20:39:05.088: V/mytag(9921): 高橋
03-02 20:39:05.088: V/mytag(9921): 斉藤
03-02 20:39:05.088: V/mytag(9921): 白石

正直このやり方でいいのかはわからない、あとアプリで静的でないDBを使用したい場合は、別途「SQLiteOpenHelper 」を継承するクラスを作成する必要がある。

サンプルファイル
SqLiteDbCopySample

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です