Terminplaner - keine Editierung möglich

T

Timber13

Neues Mitglied
1
Hallo zusammen,

ich arbeite momentan das Buch "Android Apps Entwicklung für Dummies" durch. Leider gibt es die Quelltexte nicht online, damit man seine eigenen abgleichen kann.

Nun bin ich dabei, das Projekt des Terminplaners zu realiseren. Ich kann auch Termine einfügen und löschen, allerdings nicht editieren/aktualisieren.

Ich rufe die ReminderEditActivity doch mit dem Paramter i auf, der alles nötige drin hat, aber in dem savedInstanceState finde ich das ganze nicht wieder. Ich hoffe, ihr versteht mich.

Ich weiß, dass es riesen Aufwand ist, das ganze von Außen zu debuggen,d ennoch wäre ich euch seeehr dankbar :thumbsup:

ReminderListActivity
Code:
package de.krauthoff.terminplaner;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

/**
 * 
 * @author Tobias *********
 * @version 1.0
 * 
 */

public class ReminderListActivity extends ListActivity {

    private static final int ACTIVITY_CREATE = 0;
    private static final int ACTIVITY_EDIT = 1;

    private RemindersDbAdapter mDbHelper;

    @Override
    /**
     * Wird beim ersten Mal ausgerufen
     */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.reminder_list);
        mDbHelper = new RemindersDbAdapter(this);
        mDbHelper.open();
        fillData();
        registerForContextMenu(getListView());
    }
    
    /**
     * Übernimmt alle Erinnerungstermine aus der DB, weißt sie einem
     * Curser mit eigenem Lebenszyklus zu, übernimmt alle TITLE
     * und übergibt sie der ListView
     */
    private void fillData() {
        Cursor remindersCursor = mDbHelper.fetchAllReminders();
        startManagingCursor(remindersCursor);

        // Einenen array mit den gewünschten Feledern erstellen (nut TITLE)
        String[] from = new String[] { RemindersDbAdapter.KEY_TITLE };
        // und einen Array der Felder, die in die View einbezogen werden sollen
        int[] to = new int[] { R.id.text1 };

        // Einfachen Cursor-Adapter erstellen und für Anezige setzen
        SimpleCursorAdapter reminders = new SimpleCursorAdapter(this,
                R.layout.reminder_row, remindersCursor, from, to);
        setListAdapter(reminders);
    }

    /**
     * Überträgt die ID des zu bearbeitenden Termins in einen Intent und versucht
     * die Bearbeitung zu ermöglichen.
     */
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Intent i = new Intent(this, ReminderEditActivity.class);
        i.putExtra(RemindersDbAdapter.KEY_ROWID, id);
Log.d("DEBUG","INTENT AUFRUF:"+RemindersDbAdapter.KEY_ROWID.toString() + " position:"+position+" id:"+id);
        startActivityForResult(i, ACTIVITY_EDIT);
    }

    /**
     * Löscht einen Eintrag aus der DB mithilfe der ID
     */
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_delete:
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
                    .getMenuInfo();
            mDbHelper.deleteReminder(info.id);
            fillData();
            return true;
        }
        return super.onContextItemSelected(item);
    }

    /**
     * Ruft ReminderEditActivity auf
     */
    private void createReminder() {
        Intent i = new Intent(this, ReminderEditActivity.class);
        startActivityForResult(i, ACTIVITY_CREATE);
    }

    /**
     * Wird aufgerufen, wenn der Benutzer einen Termin aktualisiert
     * oder hinzugefügt hat. Hier wird gewährleistet, dass alle
     * Termine in der ListView stehen
     */
    protected void onActivityResult(int requestCode, int resultCode,
            Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        fillData();
    }

    /*
     * MENÜ ERSTELLEN
     */
    // langes Klick-Event behandeln
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater mi = getMenuInflater();
        mi.inflate(R.menu.list_menu_item_longpressed, menu);
    }

    // erstellen des Kontextmenüs
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater mi = getMenuInflater();
        mi.inflate(R.menu.list_menu, menu);
        return true;
    }

    // Klick im Kontextmenü behandeln
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_insert:
            createReminder();
            return true;
        }
        return super.onMenuItemSelected(featureId, item);
    }

}
ReminderEditActivity
Code:
package de.*********.terminplaner;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TimePicker;
import android.widget.Toast;

/**
 * 
 * @author Tobias *********
 * @version 1.0
 * 
 */

public class ReminderEditActivity extends Activity {

    // Elemente der GUI
    private Button mDateButton;
    private Button mTimeButton;
    private Button mConfirmButton;
    private Calendar mCalendar;
    private RemindersDbAdapter mDbHelper;
    private EditText mTitleText;
    private EditText mBodyText;

    // ID's
    private static final int DATE_PICKER_DIALOG = 0;
    private static final int TIME_PICKER_DIALOG = 1;
    private Long mRowId;
    
    // Format der Zeit- und Datumsanzeige
    private static final String DATE_FORMAT = "dd.MM.yyyy";
    private static final String TIME_FORMAT = "kk:mm";
    public static final String DATE_TIME_FORMAT = "dd.MM.yyyy kk:mm:ss";

    // wird beim Starten der Activity aufgerufen
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mDbHelper = new RemindersDbAdapter(this);
        //mDbHelper.open();
        
        setContentView(R.layout.reminder_edit);
        mTitleText = (EditText) findViewById(R.id.title);
        mBodyText = (EditText) findViewById(R.id.body);
        mCalendar = Calendar.getInstance();
        mDateButton = (Button) findViewById(R.id.reminder_date);
        mTimeButton = (Button) findViewById(R.id.reminder_time);
        mConfirmButton = (Button) findViewById(R.id.confirm);
        
        mRowId = savedInstanceState != null ? savedInstanceState.getLong(RemindersDbAdapter.KEY_ROWID) : null;
        populateFields();
        
        registerButtonListenersAndSetDefaultText();
    }
    
    private void setRowIdFromIntent(){
        if (mRowId != null){
            Bundle extras = getIntent().getExtras();
            mRowId = extras != null ? extras.getLong(RemindersDbAdapter.KEY_ROWID) : null;
        }
    }
    
    @Override
    protected void onPause(){
        super.onPause();
        mDbHelper.close();
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        mDbHelper.open();
        setRowIdFromIntent();
        populateFields();
    }

    // referenziert ClickListener zu den Buttons
    private void registerButtonListenersAndSetDefaultText() {

        mDateButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                showDialog(DATE_PICKER_DIALOG);
            }
        });

        mTimeButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                showDialog(TIME_PICKER_DIALOG);
            }
        });

        mConfirmButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                if (((EditText) findViewById(R.id.title)).getText().length() == 0) {
                    Toast.makeText(ReminderEditActivity.this, "Bitte geben Sie einen Titel an", Toast.LENGTH_LONG).show();
                } else {
                    
                    AlertDialog.Builder mAlertDialog = new AlertDialog.Builder( ReminderEditActivity.this);
                    mAlertDialog.setMessage("Soll der Termin gespeichert werden?");
                    mAlertDialog.setTitle("Sind Sie sicher?");
                    mAlertDialog.setCancelable(false);
                    mAlertDialog.setPositiveButton("Ja",
                        new DialogInterface.OnClickListener() {
                            // Aktionen um den Termin zu speichern
                            public void onClick( DialogInterface dialog, int which) {
                                
                                saveState();
                                setResult(RESULT_OK);
                                Toast.makeText(ReminderEditActivity.this, getString(R.string.task_saved_message), Toast.LENGTH_SHORT).show();
                                finish();
                                
                            }
                        });
                    mAlertDialog.setNegativeButton("Nein", new DialogInterface.OnClickListener() {
                        public void onClick( DialogInterface dialog, int which) {
                            dialog.cancel();
                        };
                    });
                    mAlertDialog.create().show();
                }
                
            }
        });

        updateDateButtonText();
        updateTimeButtonText();
    }
    
    // ruft mit einer erstellen ID onCreateDialog auf
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case DATE_PICKER_DIALOG:
            return showDatePicker();
        case TIME_PICKER_DIALOG:
            return showTimePicker();
        }
        return super.onCreateDialog(id);
    }

    // erstellt einen neuen DatePicker mit dem Datum als Werten
    // angezeigt wird das aktuelle Datum
    private DatePickerDialog showDatePicker() {
        DatePickerDialog datePicker = new DatePickerDialog(
                ReminderEditActivity.this,
                new DatePickerDialog.OnDateSetListener() {
                    public void onDateSet(DatePicker view, int year,
                            int monthOfYear, int dayOfMonth) {
                        mCalendar.set(Calendar.YEAR, year);
                        mCalendar.set(Calendar.MONTH, monthOfYear);
                        mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                    }
                }, mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH),
                mCalendar.get(Calendar.DAY_OF_MONTH));
        return datePicker;
    }

    // erstellt einen neuen TimePicker mit der Zeit als Werten
    // angezeigt wird die aktueller Zeit
    private TimePickerDialog showTimePicker() {
        TimePickerDialog timePicker = new TimePickerDialog(this,
                new TimePickerDialog.OnTimeSetListener() {
                    public void onTimeSet(TimePicker view, int hourOfDay,
                            int minute) {
                        mCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
                        mCalendar.set(Calendar.MINUTE, minute);
                        updateTimeButtonText();
                    }
                }, mCalendar.get(Calendar.HOUR_OF_DAY),
                mCalendar.get(Calendar.MINUTE), true);
        return timePicker;
    }

    // aktualisiert den TimeButton mit der neu ausgewählten Zeit
    private void updateTimeButtonText() {
        SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_FORMAT);
        String timeForButton = timeFormat.format(mCalendar.getTime());
        mTimeButton.setText(timeForButton);
    }

    // aktualisiert den DateButton mit dem neu ausgewählten Datum
    private void updateDateButtonText() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
        String dateForButton = dateFormat.format(mCalendar.getTime());
        mDateButton.setText(dateForButton);
    }
    
    private void populateFields(){
        if (mRowId != null){
            Cursor reminder = mDbHelper.fetchReminder(mRowId);
            startManagingCursor(reminder);
            mTitleText.setText(reminder.getString(reminder.getColumnIndexOrThrow(RemindersDbAdapter.KEY_TITLE)));
            mBodyText.setText(reminder.getString(reminder.getColumnIndexOrThrow(RemindersDbAdapter.KEY_BODY)));
            SimpleDateFormat dateTimeFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
            Date date = null;
            try{
                String dateString = reminder.getString(reminder.getColumnIndexOrThrow(RemindersDbAdapter.KEY_DATE_TIME));
                date = dateTimeFormat.parse(dateString);
                mCalendar.setTime(date);
            } catch(ParseException e){
                Log.e("ReminderEditActivity", e.getMessage(), e);
            }
        }
        updateDateButtonText();
        updateTimeButtonText();
    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putLong(RemindersDbAdapter.KEY_ROWID, mRowId);
    }
    
    // kommunziziert mit RemindersDbAdapter
    private void saveState(){
        String title = mTitleText.getText().toString();
        String body = mBodyText.getText().toString();
        
        SimpleDateFormat dateTimeFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
        String reminderDateTime = dateTimeFormat.format(mCalendar.getTime());
        
        if (mRowId == null){
            long id = mDbHelper.createReminder(title, body, reminderDateTime);
            if (id>0){
                mRowId = id;
            }
        } else {
            mDbHelper.updateReminder(mRowId, title, body, reminderDateTime);
        }
        
    }
}
RemindersDbAdapter
Code:
package de.*********.terminplaner;

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.SQLiteOpenHelper;
import android.util.Log;

public class RemindersDbAdapter {

    // Name der Datenbankdatei, -tabelle und Wert der Version
    private static final String DATABASE_NAME = "data";
    private static final String DATABASE_TABLE = "reminders";
    private static final int DATABASE_VERSION = 1;
    
    // Definition der Spaltennamen der Tabelle
    public static final String KEY_TITLE = "title";
    public static final String KEY_BODY = "body";
    public static final String KEY_DATE_TIME = "reminder_date_time";
    public static final String KEY_ROWID = "_id";
    
    // Instanzvariable der Android-Klasse SQLiteOpenHelper zur Erstellung
    // und Versonsverwaltung der SQLite-Datenbank
    private DatabaseHelper mDbHelper;
    
    // Instanz des SQLite-Datenbankobjekts für CRUP-Operationen
    private SQLiteDatabase mDb;

    private static final String DATABASE_CREATE =
            "create table " + DATABASE_TABLE + " ("
            + KEY_ROWID + " integer primary key autoincrement,"
            + KEY_TITLE + " text not null, "
            + KEY_BODY +  " text not null, "
            + KEY_DATE_TIME +  " text not null);";
    
    private final Context mCtx;
    
    // Zuordnung des Context
    public RemindersDbAdapter(Context ctx){
        this.mCtx = ctx;
    }
    
    // Gibt eine Instanz von RemindersDbAdapter zurück
    public RemindersDbAdapter open() throws android.database.SQLException{
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }
    
    // Schließen der Datenbank
    public void close(){
        mDbHelper.close();
    }
    
    /**
     * Erstellt einen Termin mit den folgenden Schlüsseln
     * @param title Titel der Erinnerung
     * @param body Inhalt der Erinnerung
     * @param reminderDateTime Zeit/Datum der Erinnerung
     * @return Eindeutige ID des Termins
     */
    public long createReminder(String title, String body, String reminderDateTime){
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_TITLE, title);
        initialValues.put(KEY_BODY, body);
        initialValues.put(KEY_DATE_TIME, reminderDateTime);
        return mDb.insert(DATABASE_TABLE, null, initialValues);
    }
    
    /**
     * Löscht einen Termin mit den folgenden Schlüsseln
     * @param rowId Eindeutige ID des Termins
     * @return
     */
    public boolean deleteReminder(long rowId){
        return mDb.delete(DATABASE_TABLE, KEY_ROWID +"=" + rowId, null)>0;
    }
    
    /**
     * @return Gibt alle aktuellen Termine über einen Cursor zurück
     */
    public Cursor fetchAllReminders(){
        return mDb.query(DATABASE_TABLE, new String[]{KEY_ROWID, KEY_TITLE, KEY_BODY, KEY_DATE_TIME}, null, null, null, null, null);
    }
    
    /**
     * @param rowId Eindeutige ID des Termins
     * @return Gibt einen Termin über einen Cursor zurück
     * @throws SQLException
     */
    public Cursor fetchReminder (long rowId) throws SQLException{
        Cursor mCursor = mDb.query(true, DATABASE_TABLE, new String[]{KEY_ROWID, KEY_TITLE, KEY_BODY, KEY_DATE_TIME}, KEY_ROWID + "=" + rowId, null, null, null, null, null);
        if (mCursor != null){
            mCursor.moveToFirst();
        }
        return mCursor;
    }
    
    /**
     * Aktualisiert einen Termin mit den folgenen Schlüsseln
     * @param rowId Eindeutige ID des Termins
     * @param title Titel der Erinnerung
     * @param body Inhalt der Erinnerung
     * @param reminderDateTime Eindeutige ID des Termins
     * @return 
     */
    public boolean updateReminder(long rowId, String title, String body, String reminderDateTime){
        ContentValues args = new ContentValues();
        args.put(KEY_TITLE, title);
        args.put(KEY_BODY, body);
        args.put(KEY_DATE_TIME, reminderDateTime);
        
        return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null)>0;
    }
    
    
    
    //Erstellung der Datenkbanktabelle
    private static class DatabaseHelper extends SQLiteOpenHelper{
        DatabaseHelper (Context context){
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
        
        @Override
        public void onCreate(SQLiteDatabase db){
            db.execSQL(DATABASE_CREATE);
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
            //Nicht benutzt, kann aber mit ALTER aktualisiert werden
        }
    }
}
 
Zuletzt bearbeitet:
Problem gelöst :) Fehler steckt in der ReminderEditActivity.

Falsche Anfrage:
mRowId = savedInstanceState != null ? savedInstanceState.getLong(RemindersDbAdapter.KEY_ROWID) : null;

Richtige Anfrage:
mRowId = getIntent().getExtras() != null ? getIntent().getExtras().getLong(RemindersDbAdapter.KEY_ROWID) : null;
 

Ähnliche Themen

5
Antworten
22
Aufrufe
1.421
590239
5
G
Antworten
5
Aufrufe
871
jogimuc
J
A
Antworten
17
Aufrufe
1.852
starbright
S
Zurück
Oben Unten