8 つの子アクティビティを持つ「メイン」アクティビティを含むアプリがあります。メイン アクティビティでは、データベースから読み取り、(スピナーを介して) 選択された項目に関する基本情報をバンドルに読み込みます (この方法では、onCreate メソッドで DB にクエリを実行する必要がないため、各アクティビティをより高速に読み込むことができます)。ビューを作成するアクティビティ)。新しいアクティビティでビューが作成されたら、その特定のアクティビティに必要な残りのデータを DB に照会します。これまでは、databasehelper クラスがどのテーブルを参照してデータを取得するかを認識できるようにするパブリック変数を使用していました。それはあなたがプログラミングする方法ではないことを知っているので、アプリをバンドルを使用するように変換しています (それが最善の方法かどうかはわかりませんが、正しい方向への一歩だと信じています)。
現在、8 つの子アクティビティすべてでそのバンドルに保存されたデータにアクセスできますが、データベース ヘルパー クラスからはアクセスできません。
メインアクティビティで使用するバンドル:
bundle = new Bundle();
bundle.putString("KEY_tableName", tableName);
bundle.putInt("KEY_numOne", numOne);
bundle.putInt("KEY_numTwo", numTwo);
... and others
私のデータベースヘルパークラス:
package com.myName.myAPP;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DataBaseHelper extends SQLiteOpenHelper {
//The Android's default system path of your application database.
static String DB_PATH = "/data/data/com.myName.myApp/databases/";
static String DB_NAME = "databasefile";
public SQLiteDatabase myDataBase;
private final Context myContext;
//version of database
private static final int version = 1;
public static final String KEY_ROWID = "_id";
public static final String KEY_TITLE = "Title";
public static final String KEY_BODY = "Content";
public static final String KEY_DATE = "Date";
private static final String TAG = "NotesDbAdapter";
//private static final String DATABASE_CREATE = "create table notes (_id integer primary " +
// "key autoincrement, " + "title text not null, body text not null);";
//private static final String DATABASE_TABLE = "notes";
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* @param context
*/
DataBaseHelper(Context context) {
super(context, DB_NAME, null, version);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
} // end if
else {
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase(myContext);
} // end try
catch (IOException e) {
throw new Error("Error copying database");
} // end catch
} // end else
this.close();
} // end createDataBase()
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
//checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
//File dbFile = new File(DB_PATH + DB_NAME);
//return dbFile.exists();
}
catch(SQLiteException e) {
//database does't exist yet.
}
if(checkDB != null) {
checkDB.close();
}
return checkDB != null;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase(Context myContext) throws IOException {
File fileTest = myContext.getFileStreamPath(DB_NAME);
boolean exists = fileTest.exists();
if (!exists) {
// Open the empty db as the output stream
OutputStream databaseOutputStream = new FileOutputStream(DB_PATH + DB_NAME);
InputStream databaseInputStream;
databaseInputStream = myContext.getAssets().open(DB_NAME);
byte[] buffer = new byte[1024];
@SuppressWarnings("unused")
int length;
while ((length = databaseInputStream.read(buffer)) > 0) {
databaseOutputStream.write(buffer);
} // end while
databaseInputStream.close();
databaseInputStream = myContext.getAssets().open(DB_NAME);
while ((length = databaseInputStream.read(buffer)) > 0) {
databaseOutputStream.write(buffer);
} // end while
// Close the streams
databaseInputStream.close();
databaseOutputStream.flush();
databaseOutputStream.close();
} // end if
} // end copyDataBase
public void openDataBase() throws SQLException{
File f = new File(DB_PATH);
if (!f.exists()) {
f.mkdir();
}
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
} // end openDataBase
@Override
public void close() {
if(myDataBase != null) {
myDataBase.close();
}
super.close();
} // end close
@Override
public void onCreate(SQLiteDatabase db) {
} // end onCreate
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion
+ ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS notes");
onCreate(db);
} // end onUpgrade
さらに、データベースを読み取り/書き込み/更新する他の方法があります。
私の子アクティビティでは、次を呼び出してバンドルにアクセスします。
String tableName = getIntent().getExtras().getString("KEY_tableName");
int numOne = getIntent().getExtras().getString("KEY_numOne");
...
そのアクティビティの onCreate メソッドでデータを使用できるようにする
ただし、データベースヘルパークラスのメソッドでそのコードを使用すると、getIntent() でエラーが発生し、Android Studio でコンパイルされません。エラーは次のとおりです。
java: cannot find symbol
symbol: method getIntent()
location: class com.myName.myAPP.DataBaseHelper
助けてくれてありがとう。