戌印-INUJIRUSHI- (Androidあれこれ)

Androidのプログラミングをメインにしてます。記事に貼られたソースコードはダブルクリックすることで行番号をはずしてコピーすることができます。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
08

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

SQLite データベースをSDカードに保存する

Android で SQLite データベースをSDカードに保存するには、各メソッドの引数で渡すデータベース名をフルパス指定することで作成することができます
(ファイル名だけの場合はシステムメモリの /data/data/[パッケージ名]/databases/ に作成されます)
なお、SDカードにファイルを保存するにはパーミッションを追加する必要があります。

※ Android 2.1 以前は Context でのデータベース作成(取得)でスラッシュは許可されていません。
  対処法は後述。

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.inujirushi.android.sample14"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="SampleActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

SampleSQLiteOpenHelper.java
package jp.inujirushi.android.sample.sql;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class SampleSQLiteOpenHelper extends SQLiteOpenHelper {

private static final int DB_VERSION = 1;
private static final String DB_NAME = Environment
.getExternalStorageDirectory() + "/sample.db";

public SampleSQLiteOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
----------------------------------------------------------------------
最初に書いたように、Android 2.1以前では Context でのデータベースの作成(取得)でスラッシュは許可されていません
SQLiteOpenHelper も Context を使用しています。

もしもスラッシュを含めた場合には、以下のようなエラーが発生します。

java.lang.IllegalArgumentException: File /sdcard/jp.inujirushi.android.sample/sample.db contains a path separator

エラーを出さずにデータベースを作成するには SQLiteDatabase#openOrCreateDatabase を使用します。
こちらのメソッドはスラッシュが許可されています。
ただしパーミッションが 644 (他アプリから読み書き可能)となるので注意してください


使い方のサンプルとして SQLiteOpenHelper の拡張クラスを作ってみました。
拡張クラスでは SQLiteOpenHelper#getWritableDatabase をオーバーライドしているだけです。
SQLiteOpenHelper#getReadableDatabase は内部で SQLiteOpenHelper#getWritableDatabase を呼び出しているため何もしていません。

なお、この拡張クラスではすでにデータベースが呼ばれていても新しいインスタンスを作成するので、使う場合には注意してください(Android 2.1 以前でパスを指定した場合のみ)
package jp.inujirushi.android.sample.sql;

import java.io.File;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;

/**
* SQLiteOpenHelper の Android 2.1 以前対応版。
*
* @author Inujirushi
*
*/
public abstract class MySQLiteOpenHelper extends SQLiteOpenHelper {

// Android 2.1 以前で使用する
private String mMyName;
private int mMyVersion;

/**
* コンストラクタ
*
* @param context
* @param name
* @param factory
* @param version
*/
public MySQLiteOpenHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
mMyName = name;
mMyVersion = version;
}

@Override
public SQLiteDatabase getWritableDatabase() {
// Android 2.1以前
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR_MR1)
return getWriteDatabasePreEclair();

// Android 2.2以降
return super.getWritableDatabase();
}

/**
* Android 2.1 以前のデータベース取得処理
*
* @return SQLiteDatabase
*/
private SQLiteDatabase getWriteDatabasePreEclair() {
// Android 2.2 のソースコードを参考にしています。
// データベース取得を context から SQLiteDatabase に変更。
boolean success = false;
SQLiteDatabase db = null;
try {
// データベースを取得する
if (mMyName == null) {
db = SQLiteDatabase.create(null);
} else {
// スラッシュが含まれていなければ本来のメソッドを呼び出す
if (mMyName.indexOf(File.separator) < 0) {
return super.getWritableDatabase();
}

// ディレクトリが無ければ作成する
File parent = new File(mMyName).getParentFile();
if (!parent.exists())
parent.mkdirs();
parent = null;

// データベースを取得 or 作成して開く
db = SQLiteDatabase.openOrCreateDatabase(mMyName, null);
}

// バージョンが違えば作成 or アップグレードする
int version = db.getVersion();
if (version != mMyVersion) {
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
onUpgrade(db, version, mMyVersion);
}
db.setVersion(mMyVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}

// データベースをオープンする
onOpen(db);
success = true;
return db;
} finally {
// 失敗したらデータベースを閉じる
if (!success && db != null) {
db.close();
}
}
}
}
スラッシュが含まれているときだけ処理が違う(パーミッションが変わる)のは嫌という方は63~66行目をコメントアウトするか、消してください。

【関連記事】
SQLite データベースを取得・作成する:openOrCreateDatabase
スポンサーサイト

Comments

Leave a Comment


Body
プロフィール

とむ・やむくん

Author:とむ・やむくん
管理人について

Windows 7 / 64bit
Eclipse 4.2 Juno (日本語パッチ済)

スポンサーサイト
最新トラックバック
検索フォーム
ブロとも申請フォーム
QRコード
QR
Twitter
2013/01/04 19:00 カウント開始

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。