私は最初の SQLite データベース アプリに取り組んでおり、2 日間の苦労の末、ついにプロに助けを求めています。
getNurseData
テキスト ビュー (メソッド)でデータを表示しようとすると強制終了します。また、createEntry
そのメソッドが呼び出された後、呼び出しで EditText コントロールをクリアしようとしましたsetText("");
が、コントロールがクリアされていないため、メソッドも機能しているとは思いません。
DbCommunicator
クラスは次のとおりです。
package com.deadEddie.staffingmanagement;
import android.app.Dialog;
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.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.TextView;
public class DbCommunicator {
// create fields for nurses table
public static final String KEY_NURSE_ROWID = "_id";
public static final String KEY_LNAME = "_lName";
public static final String KEY_FNAME = "_fName";
public static final String KEY_EMAIL = "_eMail";
public static final String KEY_PHONE_PRIMARY = "_priPhone";
public static final String KEY_PHONE_SECONDARY = "_secPhone";
public static final String KEY_FTE = "_fte";
public static final String KEY_DUTY_STATUS = "Off Duty";
// create fields for rooms table
public static final String KEY_ROOM_ROWID = "_id";
public static final String KEY_TYPE_PATIENT = "_id";
public static final String KEY_OCCUPIED = "NO";
public static final String KEY_ROOM_NUMBER = "_id";
// database values
public static final String DATABASE_NAME = "Staffing_Assignments";
public static final String NURSE_TABLE = "Nurse_Table";
public static final String ROOM_TABLE = "Room_Table";
public static final int DATABASE_VERSION = 1;
private DbHelper databaseHelper;
private final Context dbContext;
private SQLiteDatabase sqldb;
private static class DbHelper extends SQLiteOpenHelper
{
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
// create database if it does not already exist
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + NURSE_TABLE + " (" + KEY_NURSE_ROWID
+ "INTEGER PRIMARY KEY AUTOINCREMENT " + KEY_LNAME
+ "TEXT NOT NULL" + KEY_FNAME + "TEXT NOT NULL" + KEY_EMAIL
+ "TEXT NOT NULL" + KEY_PHONE_PRIMARY + "TEXT NOT NULL"
+ KEY_PHONE_SECONDARY + "TEXT" + KEY_DUTY_STATUS
+ "TEXT NOT NULL);");
db.execSQL("CREATE TABLE " + ROOM_TABLE + " (" + KEY_ROOM_ROWID
+ " INTEGER PRIMARY KEY AUTOINCREMENT " + KEY_TYPE_PATIENT
+ " TEXT" + KEY_OCCUPIED + " TEXT NOT NULL" + KEY_ROOM_NUMBER
+ " TEXT NOT NULL);");
} // onCreate
// upgrade existing database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + NURSE_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + ROOM_TABLE);
onCreate(db);
}
} // DbHelper class
public DbCommunicator(Context c) {
dbContext = c;
}
public void close() {
databaseHelper.close();
}
public DbCommunicator open() throws SQLException {
databaseHelper = new DbHelper(dbContext);
sqldb = databaseHelper.getWritableDatabase();
return this;
}
public long createEntry(String nurseLname, String nurseFname,
String nurseEmail, String priPhone, String secPhone, String nurseFTE) {
// TODO Auto-generated method stub
ContentValues cvCreate = new ContentValues();
cvCreate.put(KEY_LNAME, nurseLname);
cvCreate.put(KEY_FNAME, nurseFname);
cvCreate.put(KEY_EMAIL, nurseEmail);
cvCreate.put(KEY_PHONE_PRIMARY, priPhone);
cvCreate.put(KEY_PHONE_SECONDARY, secPhone);
cvCreate.put(KEY_FTE, nurseFTE);
return sqldb.insert(NURSE_TABLE, null, cvCreate);
}
public String getNurseData() {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_NURSE_ROWID, KEY_LNAME, KEY_FNAME,
KEY_EMAIL, KEY_PHONE_PRIMARY, KEY_PHONE_SECONDARY };
Cursor c = sqldb.query(NURSE_TABLE, columns, null, null, null,
null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_NURSE_ROWID);
int iLname = c.getColumnIndex(KEY_LNAME);
int iFname = c.getColumnIndex(KEY_FNAME);
int iEmail = c.getColumnIndex(KEY_EMAIL);
int iPriPhone = c.getColumnIndex(KEY_PHONE_PRIMARY);
int iSecPhone = c.getColumnIndex(KEY_PHONE_SECONDARY);
int iDutyStatus = c.getColumnIndex(KEY_DUTY_STATUS);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
result = result + " " + c.getString(iRow) + " "
+ c.getString(iLname) + " "
+ c.getString(iFname) + " "
+ c.getString(iPriPhone) + " " + c.getString(iSecPhone) + " "
+ c.getString(iEmail) + " " + c.getString(iDutyStatus) + "\n";
}
c.deactivate();
c.close();
return result;
}
}// DbCommunicator class
メソッドNursingAssignments
から TextView を埋めようとするクラスは次のとおりです。getNurseData
package com.deadEddie.staffingmanagement;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class NursingAssignments extends Activity implements OnClickListener
{
Button addNurse;
Button removeNurse;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.nurse_assignments);
displayNursingData();
// set variable values and OnClickListeners
addNurse = (Button) findViewById(R.id.btnAddToRoster);
removeNurse = (Button) findViewById(R.id.btnRemoveFromRoster);
addNurse.setOnClickListener(this);
removeNurse.setOnClickListener(this);
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId())
{
case R.id.btnAddToRoster:
Intent add = new Intent("com.deadEddie.staffingmanagement.ADDNURSETOROSTER");
startActivity(add);
break;
case R.id.btnRemoveFromRoster:
break;
}
}
public void displayNursingData()
{
TextView nurseRoster = (TextView) findViewById(R.id.tvSQLInfo);
DbCommunicator info = new DbCommunicator(this);
info.open();
String data = info.getNurseData();
info.close();
nurseRoster.setText(data.toString());
}
}
AddNurseToRoster
次に、エントリを追加して EditText コントロールをクリアしようとするクラスを示します。
package com.deadEddie.staffingmanagement;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class AddNurseToRoster extends Activity implements OnClickListener {
Button add;
Button cancel;
EditText lastName;
EditText firstName;
EditText eMail;
EditText primaryPhone;
EditText secondaryPhone;
EditText fte;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.add_nurse_to_roster);
setControlValues();
}
private void setControlValues() {
add = (Button) findViewById(R.id.btnAdd);
cancel = (Button) findViewById(R.id.btnCancel);
lastName = (EditText) findViewById(R.id.etFname);
eMail = (EditText) findViewById(R.id.etEmail);
primaryPhone = (EditText) findViewById(R.id.etPrimaryPhone);
secondaryPhone = (EditText) findViewById(R.id.etSecondaryPhone);
fte = (EditText) findViewById(R.id.etFTE);
} // setVariableValues
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnAdd:
try {
String nurseLname = lastName.getText().toString();
String nurseFname = firstName.getText().toString();
String nurseEmail = eMail.getText().toString();
String priPhone = primaryPhone.getText().toString();
String secPhone = secondaryPhone.getText().toString();
String nurseFTE = fte.getText().toString();
DbCommunicator database = new DbCommunicator(this);
database.open();
database.createEntry(nurseLname, nurseFname, nurseEmail,
priPhone, secPhone, nurseFTE);
database.close();
lastName.setText("");
firstName.setText("");
eMail.setText("");
primaryPhone.setText("");
secondaryPhone.setText("");
fte.setText("");
} catch (Exception e) {
String error = e.toString();
Dialog d = new Dialog(this);
d.setTitle("An Error Has Occurred");
TextView tv = new TextView(this);
tv.setText(error);
d.setContentView(tv);
d.show();
}
break;
case R.id.btnCancel:
break;
}
} // onClickView
}
この Logcat エラーが発生しましたが、修正方法がわかりません。
08-23 14:31:25.156: E/AndroidRuntime(577): ERROR: thread attach failed
08-23 14:31:32.545: E/Database(583): Failure 1 (AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY) on 0x136ea8 when preparing 'CREATE TABLE Nurse_Table (_idINTEGER PRIMARY KEY AUTOINCREMENT, _lNameTEXT NOT NULL,_fNameTEXT NOT NULL_eMailTEXT NOT NULL,_priPhoneTEXT NOT NULL,_secPhoneTEXT,Off DutyTEXT NOT NULL);'.
08-23 14:31:32.555: E/AndroidRuntime(583): Uncaught handler: thread main exiting due to uncaught exception
08-23 14:31:32.565: E/AndroidRuntime(583): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.deadEddie.staffingmanagement/com.deadEddie.staffingmanagement.NursingAssignments}: android.database.sqlite.SQLiteException: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY: CREATE TABLE Nurse_Table (_idINTEGER PRIMARY KEY AUTOINCREMENT, _lNameTEXT NOT NULL,_fNameTEXT NOT NULL_eMailTEXT NOT NULL,_priPhoneTEXT NOT NULL,_secPhoneTEXT,Off DutyTEXT NOT NULL);
08-23 14:31:32.565: E/AndroidRuntime(583): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.os.Handler.dispatchMessage(Handler.java:99)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.os.Looper.loop(Looper.java:123)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.app.ActivityThread.main(ActivityThread.java:4363)
08-23 14:31:32.565: E/AndroidRuntime(583): at java.lang.reflect.Method.invokeNative(Native Method)
08-23 14:31:32.565: E/AndroidRuntime(583): at java.lang.reflect.Method.invoke(Method.java:521)
08-23 14:31:32.565: E/AndroidRuntime(583): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
08-23 14:31:32.565: E/AndroidRuntime(583): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
08-23 14:31:32.565: E/AndroidRuntime(583): at dalvik.system.NativeStart.main(Native Method)
08-23 14:31:32.565: E/AndroidRuntime(583): Caused by: android.database.sqlite.SQLiteException: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY: CREATE TABLE Nurse_Table (_idINTEGER PRIMARY KEY AUTOINCREMENT, _lNameTEXT NOT NULL,_fNameTEXT NOT NULL_eMailTEXT NOT NULL,_priPhoneTEXT NOT NULL,_secPhoneTEXT,Off DutyTEXT NOT NULL);
08-23 14:31:32.565: E/AndroidRuntime(583): at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1610)
08-23 14:31:32.565: E/AndroidRuntime(583): at com.deadEddie.staffingmanagement.DbCommunicator$DbHelper.onCreate(DbCommunicator.java:52)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:106)
08-23 14:31:32.565: E/AndroidRuntime(583): at com.deadEddie.staffingmanagement.DbCommunicator.open(DbCommunicator.java:87)
08-23 14:31:32.565: E/AndroidRuntime(583): at com.deadEddie.staffingmanagement.NursingAssignments.displayNursingData(NursingAssignments.java:52)
08-23 14:31:32.565: E/AndroidRuntime(583): at com.deadEddie.staffingmanagement.NursingAssignments.onCreate(NursingAssignments.java:21)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-23 14:31:32.565: E/AndroidRuntime(583): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
08-23 14:31:32.565: E/AndroidRuntime(583): ... 11 more
08-23 14:31:32.575: E/dalvikvm(583): Unable to open stack trace file '/data/anr/traces.txt': Permission denied
DDMS 出力:
[2012-08-23 09:04:17 - StaffingManagement] New emulator found: emulator-5556
[2012-08-23 09:04:17 - StaffingManagement] Waiting for HOME ('android.process.acore') to be launched...
[2012-08-23 09:05:14 - StaffingManagement] HOME is up on device 'emulator-5556'
[2012-08-23 09:05:14 - StaffingManagement] Uploading StaffingManagement.apk onto device 'emulator-5556'
[2012-08-23 09:05:14 - StaffingManagement] Installing StaffingManagement.apk...
[2012-08-23 09:05:24 - StaffingManagement] Success!
[2012-08-23 09:05:24 - StaffingManagement] Starting activity com.deadEddie.staffingmanagement.MainActivity on device emulator-5556
[2012-08-23 09:05:26 - StaffingManagement] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.deadEddie.staffingmanagement/.MainActivity }