1

解決策は私の投稿の下部にあります。

まず、この投稿の長さについてお詫び申し上げますが、私は何時間もコードを注いでいて、迷子になっています。また、dbアスペクトにかなり混乱しているため、アスペクトが非推奨であることがわかっている場合や、コードの長さを短縮する他の方法がある場合でも、コードは見つけた最も単純なチュートリアルのいくつかを複製します。何が必要かわからなかったので、以下の大量のコード。

目標:ユーザーが入力してDBテーブルに保存できるフォームがあります。次に、このデータを別のクラスでListViewに表示します(このクラスには、リストビューの上に追加の関数もあります)。リストビューアイテムの1つをクリックすると、元のフォームと同じように見える別のフォームが開き、データベース行からすべての情報がすでに入力されています。このフォームには保存と削除のボタンがあり、一部の入力フィールド(EditTextとSpinner)を変更して保存し、行を更新するか、[削除]を選択します。更新または削除後、アクティビティは終了し、リストビュークラスに戻ります。

正しく保存されていることがわかっているので、元のフォームデータをわざわざ追加することはありません。また、データがセカンダリ形式(変更/削除できる形式)に正しく転送されていることも知っていますが、更新または削除しようとすると、logcatに次のように表示されます。

07-29 04:18:25.771: E/AndroidRuntime(2116): FATAL EXCEPTION: main
07-29 04:18:25.771: E/AndroidRuntime(2116): java.lang.IllegalStateException: Could not execute method of the activity
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.view.View$1.onClick(View.java:3591)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.view.View.performClick(View.java:4084)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.view.View$PerformClick.run(View.java:16966)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.os.Handler.handleCallback(Handler.java:615)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.os.Looper.loop(Looper.java:137)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.app.ActivityThread.main(ActivityThread.java:4745)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at java.lang.reflect.Method.invokeNative(Native Method)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at java.lang.reflect.Method.invoke(Method.java:511)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at dalvik.system.NativeStart.main(Native Method)
07-29 04:18:25.771: E/AndroidRuntime(2116): Caused by: java.lang.reflect.InvocationTargetException
07-29 04:18:25.771: E/AndroidRuntime(2116):     at java.lang.reflect.Method.invokeNative(Native Method)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at java.lang.reflect.Method.invoke(Method.java:511)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at android.view.View$1.onClick(View.java:3586)
07-29 04:18:25.771: E/AndroidRuntime(2116):     ... 11 more
07-29 04:18:25.771: E/AndroidRuntime(2116): Caused by: java.lang.NullPointerException
07-29 04:18:25.771: E/AndroidRuntime(2116):     at com.rone.glucometer.AddDBHelper.updateDetails(AddDBHelper.java:119)
07-29 04:18:25.771: E/AndroidRuntime(2116):     at com.rone.glucometer.UpdateDBDetails.clickUpdateDelete(UpdateDBDetails.java:420)
07-29 04:18:25.771: E/AndroidRuntime(2116):     ... 14 more

私のAddDBHelperクラスは次のようになります。

public class AddDBHelper {

public static final String KEY_ROWID ="_id";
public static final String KEY_CATEG = "Category";
public static final String KEY_CATEGPOS = "Category_Pos";
public static final String KEY_BGL = "BGL";
public static final String KEY_CARBS = "Carbs";
public static final String DB_NAME = "Glucometer.db";
public static final String DB_TABLE = "Journal";
private static final int DB_VERSION = 1;

private DbHelper myDBHelper;
private final Context mContext;
private SQLiteDatabase glucoDB;

private static class DbHelper extends SQLiteOpenHelper {

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


    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + DB_TABLE + " (" +
            KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            KEY_CATEG + " TEXT NOT NULL, " +
            KEY_CATEGPOS + " TEXT NOT NULL, " +
            KEY_BGL + " TEXT NOT NULL, " +
            KEY_CARBS + " TEXT NOT NULL);"

);}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
        onCreate(db);
    }

}


public AddDBHelper(Context c) {
    mContext = c;
}

public AddDBHelper open() throws SQLException {
    myDBHelper = new DbHelper(mContext);
    glucoDB = myDBHelper.getWritableDatabase();
    return this;
}

public void close() {
    myDBHelper.close();
}

public long createEntry(String Category, String CategoryPos, String BGL, String Carbs) {
    ContentValues cv = new ContentValues();
    cv.put(KEY_CATEG, Category);
    cv.put(KEY_CATEGPOS, CategoryPos);
    cv.put(KEY_BGL, BGL);
    cv.put(KEY_CARBS, Carbs);
return glucoDB.insert(DB_TABLE, null, cv); }

public Cursor getEntries() {        
    return glucoDB.query(DB_TABLE, new String[] {
            KEY_ROWID,
            KEY_CATEG,
            KEY_CATEGPOS,
            KEY_BGL,
            KEY_CARBS}, null, null, null, null, null); }

public void updateDetails(DBDetails dbdetails) {
    SQLiteDatabase db = myDBHelper.getWritableDatabase();

    ContentValues cv = new ContentValues();
    cv.put(AddDBHelper.KEY_ROWID, UpdateDBDetails.newRow);
    cv.put(AddDBHelper.KEY_CATEG, UpdateDBDetails.newCateg);
    cv.put(AddDBHelper.KEY_CATEGPOS, UpdateDBDetails.newCategPos);
    cv.put(AddDBHelper.KEY_BGL, UpdateDBDetails.newBGL);
    cv.put(AddDBHelper.KEY_CARBS, UpdateDBDetails.newCarbs);

    db.update(DB_TABLE, cv, KEY_ROWID + "=?", new String[] {String.valueOf(UpdateDBDetails.newRow)});
}


public void deleteDetails(DBDetails dbdetails) {
    SQLiteDatabase db = myDBHelper.getWritableDatabase();
    db.delete(DB_TABLE, KEY_ROWID +"=?", 
            new String[] {String.valueOf(UpdateDBDetails.newRow)});
    db.close();
}}

私のListViewアクティビティは次のとおりです。

public class FuncLogbook extends DashMenuActivity implements OnItemClickListener {

private ListView list_LogbookResults;
private ListAdapter list_LogbookAdap;
private ArrayList<DBDetails> LogbookArrayList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView (R.layout.dash_logbook);

    list_LogbookResults = (ListView) findViewById(R.id.list_logbookResults);
    list_LogbookResults.setOnItemClickListener(this);

    LogbookArrayList = new ArrayList<DBDetails>();
    list_LogbookAdap = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
    list_LogbookResults.setAdapter(list_LogbookAdap); }

@SuppressWarnings("deprecation")
public List<String> populateList() {
    List<String> BGLResultsList = new ArrayList<String>();

    AddDBHelper logbook = new AddDBHelper(this);
    logbook.open();
    Cursor cur = logbook.getEntries();
    startManagingCursor(cur);

    while (cur.moveToNext()) {
        String RowID = cur.getString(0);
        String Category = cur.getString(1);
        String CategoryPos = cur.getString(2);
        String BGL = cur.getString(3);
        String Carbs = cur.getString(4);


        DBDetails detailsClass = new DBDetails();
        detailsClass.setuCateg(Category);
        detailsClass.setuCategPos(CategoryPos);
        detailsClass.setuBGL(BGL);
        detailsClass.setuCarbs(Carbs);


        LogbookArrayList.add(detailsClass);
        BGLResultsList.add("BGL: " + BGL + "\nRow ID: " + RowID);
    }

    return BGLResultsList;
}

@Override
protected void onResume() {
    super.onResume();
    LogbookArrayList = new ArrayList<DBDetails>();
    list_LogbookAdap = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
    list_LogbookResults.setAdapter(list_LogbookAdap);
}

@Override
protected void onStart() {
    super.onStart();
    LogbookArrayList = new ArrayList<DBDetails>();
    list_LogbookAdap = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
    list_LogbookResults.setAdapter(list_LogbookAdap);
}

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {      
    Intent UpdateDBDetails = new Intent(this, UpdateDBDetails.class);

    DBDetails clickedObject = LogbookArrayList.get(arg2);
    Bundle dataBundle =  new Bundle();
    dataBundle.putString("clickeduCateg", clickedObject.getuCateg());
    dataBundle.putString("clickeduCategPos", clickedObject.getuCategPos());
    dataBundle.putString("clickeduBGL", clickedObject.getuBGL());
    dataBundle.putString("clickeduCarbs", clickedObject.getuCarbs());


    UpdateDBDetails.putExtras(dataBundle);
    startActivity(UpdateDBDetails);
}}

データは私のDBDetailsクラスに収集されます。

public class DBDetails {

private String uCateg;
private String uCategPos;
private String uBGL;
private String uCarbs;

public String getuCateg() {
    return uCateg;
}

public void setuCateg(String uCateg) {
    this.uCateg = uCateg;
}

public String getuCategPos() {
    return uCategPos;
}

public void setuCategPos(String uCategPos) {
    this.uCategPos = uCategPos;
}

public String getuBGL() {
    return uBGL;
}

public void setuBGL(String uBGL) {
    this.uBGL = uBGL;
}

public String getuCarbs() {
    return uCarbs;
}

public void setuCarbs(String uCarbs) {
    this.uCarbs = uCarbs;
}

そして最後に、データを表示する私のフォーム:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.updatedbdetails);

update_category_spinner = (Spinner) findViewById(R.id.update_category_spinner);
    ArrayAdapter<CharSequence> category_adapter = ArrayAdapter.createFromResource(
            this, R.array.category_array, android.R.layout.simple_spinner_item);

    category_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    update_category_spinner.setAdapter(category_adapter);

    update_category_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            newCat = update_category_spinner.getSelectedItem().toString();
            newCatPos = (update_category_spinner.getSelectedItemPosition() + " Position");
        }

        public void onNothingSelected(AdapterView<?> arg0) {

        }
    });

Bundle takeBundledData = getIntent().getExtras();

    bundleduRowId = takeBundledData.getString("clickeduRowId");
    bundleduCateg = takeBundledData.getString("clickeduCateg");
    bundleduCategPos = takeBundledData.getString("clickeduCategPos");
    bundleduBGL = takeBundledData.getString("clickeduBGL");
    bundleduCarbs = takeBundledData.getString("clickeduCarbs");

CategoryPosition = String.valueOf(bundleduCategPos.charAt(0));
    update_category_spinner.setSelection(Integer.parseInt(CategoryPosition), true);
update_edit_bgl.setText(bundleduBGL);
    update_edit_carbs.setText(bundleduCarbs); }

public static double round(double unrounded, int precision, int roundingMode) {
    BigDecimal bd = new BigDecimal(unrounded);
    BigDecimal rounded = bd.setScale(precision, roundingMode);
    return rounded.doubleValue();
}


public void checkNewBGL() {
    String checkBGL = update_edit_bgl.getText().toString();
    if (checkBGL.matches("")) {
        NewBGLValid = "";
    } else {
        float BGLUnRound = Float.parseFloat(update_edit_bgl.getText().toString());
         double BGLRound= round(BGLUnRound, 1, BigDecimal.ROUND_HALF_UP);
         NewBGLValid = String.valueOf(BGLRound);
    }
    return;
    }

    public void checkNewCarbs() {
    String checkCarbs = update_edit_carbs.getText().toString();
    if (checkCarbs.matches("")) {
        NewCarbsValid = "0";
    } else {        
        NewCarbsValid = update_edit_carbs.getText().toString();
    }
    return;
    }

public void clickUpdateDelete(View v) {

    checkNewBGL();
    checkNewCarbs();

    newCateg = newCat;
    newCategPos = newCatPos;
    newBGL = NewBGLValid;
    newCarbs = NewCarbsValid;

DBDetails dbdetails = new DBDetails();

    dbdetails.setuCateg(newCateg);
    dbdetails.setuCategPos(newCategPos);
    dbdetails.setuBGL(newBGL);
    dbdetails.setuCarbs(newCarbs);

if (v.getId() == R.id.update_button_delete) {
        AddDBHelper deleteEntry = new AddDBHelper(this);
        deleteEntry.deleteDetails(dbdetails);
    } else if (v.getId() == R.id.update_button_save) {
        AddDBHelper updateEntry = new AddDBHelper(this);
        updateEntry.updateDetails(dbdetails);
    }   
}}

に更新しました

public void updateDetails(DBDetails dbdetails) { 
SQLiteDatabase db = myDBHelper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(AddDBHelper.KEY_CATEG, UpdateDBDetails.newCateg); 
cv.put(AddDBHelper.KEY_CATEGPOS, UpdateDBDetails.newCategPos); 
cv.put(AddDBHelper.KEY_BGL, UpdateDBDetails.newBGL);
cv.put(AddDBHelper.KEY_CARBS, UpdateDBDetails.newCarbs);
db.update(DB_TABLE, cv, KEY_ROWID + "=?", new String[] {UpdateDBDetails.getRowId});}

そしてUpdateDBDetailsに追加されました:

getRowId = dbdetails.getuRow();

同じ問題が発生していますが。また、この段階では、保存または削除する代わりに「戻る」ボタンを押すとカーソルが閉じません。すでに閉じているカーソルを照会しようとするとクラッシュします。後でその問題に取り組むつもりだと思います。そうです、UpdateDBDetailsを定義するのを忘れていましたが、DBDetailsコンテキストをメソッドに渡したので、次のように変更しました。

public void updateDetails(DBDetails dbdetails) {
SQLiteDatabase db = myDBHelper.getWritableDatabase(); 
ContentValues cv = new ContentValues(); 
cv.put(AddDBHelper.KEY_CATEG, dbdetails.getuCateg()); 
cv.put(AddDBHelper.KEY_CATEGPOS, dbdetails.getuCategPos()); 
cv.put(AddDBHelper.KEY_BGL, dbdetails.getuBGL()); 
cv.put(AddDBHelper.KEY_CARBS, dbdetails.getuCarbs()); 
db.update(DB_TABLE, cv, KEY_ROWID + "=?", new String[] {dbdetails.getuRow()}); }

しかし、繰り返しますが、同じ問題です。

解決:

私のDBDetails.javaには、次の行が追加されています。

 public String getuRow() {
    return uRow;
}

public void setuRow(String uRow) {
    this.uRow = uRow;
}

私のリストビュー(FuncLogbook.Java)には、次の行が追加/変更されました。

public List<String> populateList() {
    List<String> BGLResultsList = new ArrayList<String>();

    AddDBHelper logbook = new AddDBHelper(this);
    logbook.open();
    Cursor cur = logbook.getEntries();
    startManagingCursor(cur);

    while (cur.moveToNext()) {
        String RowID = cur.getString(0);
        String Category = cur.getString(3);
        String CategoryPos = cur.getString(4);
        String BGL = cur.getString(5);
        String Carbs = cur.getString(6);

DBDetails detailsClass = new DBDetails();
        detailsClass.setuRow(RowID);
        detailsClass.setuCateg(Category);
        detailsClass.setuCategPos(CategoryPos);
        detailsClass.setuBGL(BGL);
        detailsClass.setuCarbs(Carbs);
LogbookArrayList.add(detailsClass);
}
return BGLResultsList; }

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {      
    Intent UpdateDBDetails = new Intent(this, UpdateDBDetails.class);

    DBDetails clickedObject = LogbookArrayList.get(arg2);
    Bundle dataBundle =  new Bundle();
    dataBundle.putString("clickeduRowId", clickedObject.getuRow());
    dataBundle.putString("clickeduCateg", clickedObject.getuCateg());
    dataBundle.putString("clickeduCategPos", clickedObject.getuCategPos());
    dataBundle.putString("clickeduBGL", clickedObject.getuBGL());
    dataBundle.putString("clickeduCarbs", clickedObject.getuCarbs());
        UpdateDBDetails.putExtras(dataBundle);
    startActivity(UpdateDBDetails);
}

MY DBヘルパークラス(AddDBHelper.java)は、次のように表示されます。

public void updateDetails(DBDetails dbdetails) {

    ContentValues cv = new ContentValues();
    cv.put(AddDBHelper.KEY_CATEG, dbdetails.getuCateg());
    cv.put(AddDBHelper.KEY_CATEGPOS, dbdetails.getuCategPos());
    cv.put(AddDBHelper.KEY_BGL, dbdetails.getuBGL());
    cv.put(AddDBHelper.KEY_CARBS, dbdetails.getuCarbs());
int count = glucoDB.update(DB_TABLE, cv, KEY_ROWID + "=?", new String[] {String.valueOf(dbdetails.getuRow())});
    Log.v("AddDbHelper", "Row " + dbdetails.getuRow() + " updated? " + count);
}

public void deleteDetails(DBDetails dbdetails) {

    int count = glucoDB.delete(DB_TABLE, KEY_ROWID +"=?", 
            new String[] {String.valueOf(dbdetails.getuRow())});
    Log.v("AddDbHelper", "Row " + dbdetails.getuRow() + " deleted? " + count);
}

そして最後に、私のUpdateDBDetails.java(変更または削除する情報を含むフォームが含まれています)は次のように表示されます。

onCreate...{
Bundle takeBundledData = getIntent().getExtras();

    bundleduRowId = takeBundledData.getString("clickeduRowId");
    bundleduCateg = takeBundledData.getString("clickeduCateg");
    bundleduCategPos = takeBundledData.getString("clickeduCategPos");
    bundleduBGL = takeBundledData.getString("clickeduBGL");
    bundleduCarbs = takeBundledData.getString("clickeduCarbs");
}

public void clickUpdateDelete(View v) {


    checkNewBGL();
    checkNewCarbs();

    newCateg = newCat;
    newCategPos = newCatPos;
    newBGL = NewBGLValid;
    newCarbs = NewCarbsValid;

AddDBHelper modifyEntry = new AddDBHelper(this);
    modifyEntry.open();

    DBDetails dbdetails = new DBDetails();

    dbdetails.setuRow(bundleduRowId);

    if (v.getId() == R.id.update_button_delete) {
        modifyEntry.deleteDetails(dbdetails);
    } else if (v.getId() == R.id.update_button_save) {
        dbdetails.setuCateg(newCateg);
        dbdetails.setuCategPos(newCategPos);
        dbdetails.setuBGL(newBGL);
        dbdetails.setuCarbs(newCarbs);
modifyEntry.updateDetails(dbdetails);
    }   
    modifyEntry.close();
    finish();
}
4

1 に答える 1

1

あなたが定義する場所がわかりませんUpdateDBDetails。しかし、SQLiteDatabase.update() に関していくつか提案があります。

最初に行 ID を UpdateDBDetails オブジェクトに追加し、get メソッドを提供します。

次に、次のように update メソッドを使用します。

public void updateDetails() {
    ContentValues cv = new ContentValues();
    cv.put(AddDBHelper.KEY_CATEG, UpdateDBDetails.newCateg);
    cv.put(AddDBHelper.KEY_CATEGPOS, UpdateDBDetails.newCategPos);
    cv.put(AddDBHelper.KEY_BGL, UpdateDBDetails.newBGL);
    cv.put(AddDBHelper.KEY_CARBS, UpdateDBDetails.newCarbs);

    db.update(DB_TABLE, cv, KEY_ROWID + "=?", new String[] {UpdateDBDetails.getuRow()});
}

行を更新しても、その ID は変更されません。そうしないと、新しい行を作成するか、別の行を更新することになりますAddDBHelper.KEY_ROWID。現在の行の ID が必要です。それが理にかなっていることを願っています。

またnew AddDBHelper、orを使用するときmyDBHelper.getWritableDatabase()(または Cursor を直接使用する場合) はいつでも、完了したらこれらのオブジェクトを閉じる必要があります。それ以外の場合は保持され、不必要にメモリを消費します。

LogCat からの追加

私はあなたの LogCat を見て、何か問題があると推測していUpdateDBDetailsますが、 updateDetails() を呼び出して推奨する場所に気付きました:

行 ID を DBDetails に追加して、これを行うことができます。

AddDBHelper helper = new AddDBHelper(this);
helper.open();

DBDetails dbdetails = new DBDetails();
dbdetails.setuRow(bundleduRowId);

if (v.getId() == R.id.update_button_delete) {
    helper.deleteDetails(dbdetails);
} else if (v.getId() == R.id.update_button_save) {
    dbdetails.setuCateg(newCateg);
    dbdetails.setuCategPos(newCategPos);
    dbdetails.setuBGL(newBGL);
    dbdetails.setuCarbs(newCarbs);
    helper.updateDetails(dbdetails);
}   

helper.close();

そして最後の AddDbHepler:

public void updateDetails(DBDetails dbdetails) {
    ContentValues cv = new ContentValues();
    cv.put(AddDBHelper.KEY_CATEG, dbdetails.newCateg);
    cv.put(AddDBHelper.KEY_CATEGPOS, dbdetails.newCategPos);
    cv.put(AddDBHelper.KEY_BGL, dbdetails.newBGL);
    cv.put(AddDBHelper.KEY_CARBS, dbdetails.newCarbs);

    glucoDB.update(DB_TABLE, cv, KEY_ROWID + "=?", new String[] {String.valueOf(dbdetails.getuRow())});
}

ログキャット

更新と削除の両方が、影響を受けた行数の整数を返します。次のように自分で確認できます。

int count = glucoDB.update(DB_TABLE, cv, KEY_ROWID + "=?", new String[] {String.valueOf(dbdetails.getuRow())});
Log.v("AddDbHelper", "Row " + dbdetails.getuRow() + " updated? " + count);

"...updated? 1" が表示された場合は正常に機能しましたが、それ以外の場合は DBDetails に格納されている ID がオフになっています。

于 2012-07-28T17:16:27.033 に答える