FileDocCategorySizeDatePackage
NoteEditor.javaAPI DocGoogle Android v1.5 Example12699Sun Nov 11 13:01:04 GMT 2007com.google.android.notepad

NoteEditor

public class NoteEditor extends android.app.Activity
A generic activity for editing a note in a database. This can be used either to simply view a note (Intent.VIEW_ACTION), view and edit a note (Intent.EDIT_ACTION), or create a new note (Intent.INSERT_ACTION).

Fields Summary
private static final String
TAG
private static final int
NOTE_INDEX
private static final int
TITLE_INDEX
private static final int
MODIFIED_INDEX
private static final String[]
PROJECTION
Standard projection for the interesting columns of a normal note.
private static final String
ORIGINAL_CONTENT
private static final int
REVERT_ID
private static final int
DISCARD_ID
private static final int
DELETE_ID
private static final int
STATE_EDIT
private static final int
STATE_INSERT
private int
mState
private boolean
mNoteOnly
private android.net.ContentURI
mURI
private android.database.Cursor
mCursor
private android.widget.EditText
mText
private String
mOriginalContent
Constructors Summary
Methods Summary
private final voidcancelNote()
Take care of cancelling work on a note. Deletes the note if we had created it, otherwise reverts to the original text.

        if (mCursor != null) {
            if (mState == STATE_EDIT) {
                mCursor.updateString(NOTE_INDEX, mOriginalContent);
                mCursor.commitUpdates();
                mCursor.deactivate();
                mCursor = null;
            } else if (mState == STATE_INSERT) {
                deleteNote();
            }
        }
        setResult(RESULT_CANCELED);
        finish();
    
private final voiddeleteNote()
Take care of deleting a note. Simply deletes the entry.

        if (mCursor != null) {
            mText.setText("");
            mCursor.deleteRow();
            mCursor.deactivate();
            mCursor = null;
        }
    
protected voidonCreate(android.os.Bundle icicle)

        super.onCreate(icicle);

        final Intent intent = getIntent();
        final String type = intent.resolveType(this);

        // Do some setup based on the action being performed.

        final String action = intent.getAction();
        if (action.equals(Intent.EDIT_ACTION)) {
            // Requested to edit: set that state, and the data being edited.
            mState = STATE_EDIT;
            mURI = intent.getData();

        } else if (action.equals(Intent.INSERT_ACTION)) {
            // Requested to insert: set that state, and create a new entry
            // in the container.
            mState = STATE_INSERT;
            mURI = getContentResolver().insert(intent.getData(), null);

            // If we were unable to create a new note, then just finish
            // this activity.  A RESULT_CANCELED will be sent back to the
            // original activity if they requested a result.
            if (mURI == null) {
                Log.e("Notes", "Failed to insert new note into "
                        + getIntent().getData());
                finish();
                return;
            }

            // The new entry was created, so assume all will end well and
            // set the result to be returned.
            setResult(RESULT_OK, mURI.toString());

        } else {
            // Whoops, unknown action!  Bail.
            Log.e(TAG, "Unknown action, exiting");
            finish();
            return;
        }

        // Set the layout for this activity.  You can find it
        // in res/layout/hello_activity.xml
        setContentView(R.layout.note_editor);
        
        // The text view for our note, identified by its ID in the XML file.
        mText = (EditText) findViewById(R.id.note);

        // Get the note!
        mCursor = managedQuery(mURI, PROJECTION, null, null);

        // If an instance of this activity had previously stopped, we can
        // get the original text it started with.
        if (icicle != null) {
            mOriginalContent = icicle.getString(ORIGINAL_CONTENT);
        }
    
public booleanonCreateOptionsMenu(android.view.Menu menu)

        super.onCreateOptionsMenu(menu);

        // Build the menus that are shown when editing.
        if (mState == STATE_EDIT) {
            menu.add(0, REVERT_ID, R.string.menu_revert).setShortcut(
                    KeyEvent.KEYCODE_0, 0, KeyEvent.KEYCODE_R);
            if (!mNoteOnly) {
                menu.add(0, DELETE_ID, R.string.menu_delete).setShortcut(
                        KeyEvent.KEYCODE_1, 0, KeyEvent.KEYCODE_D);
            }

        // Build the menus that are shown when inserting.
        } else {
            menu.add(0, DISCARD_ID, R.string.menu_discard).setShortcut(
                    KeyEvent.KEYCODE_0, 0, KeyEvent.KEYCODE_D);
        }

        // If we are working on a real honest-to-ghod note, then append to the
        // menu items for any other activities that can do stuff with it
        // as well.  This does a query on the system for any activities that
        // implement the ALTERNATIVE_ACTION for our data, adding a menu item
        // for each one that is found.
        if (!mNoteOnly) {
            Intent intent = new Intent(null, getIntent().getData());
            intent.addCategory(Intent.ALTERNATIVE_CATEGORY);
            menu.addIntentOptions(
                Menu.ALTERNATIVE, 0,
                new ComponentName(this, NoteEditor.class), null,
                intent, 0, null);
        }

        return true;
    
protected voidonFreeze(android.os.Bundle outState)

        // Save away the original text, so we still have it if the activity
        // needs to be killed while paused.
        outState.putString(ORIGINAL_CONTENT, mOriginalContent);
    
public booleanonOptionsItemSelected(Menu.Item item)

        // Handle all of the possible menu actions.
        switch (item.getId()) {
        case DELETE_ID:
            deleteNote();
            finish();
            break;
        case DISCARD_ID:
            cancelNote();
            break;
        case REVERT_ID:
            cancelNote();
            break;
        }
        return super.onOptionsItemSelected(item);
    
protected voidonPause()

        super.onPause();

        // The user is going somewhere else, so make sure their current
        // changes are safely saved away in the provider.  We don't need
        // to do this if only editing.
        if (mCursor != null) {
            String text = mText.getText().toString();
            int length = text.length();

            // If this activity is finished, and there is no text, then we
            // do something a little special: simply delete the note entry.
            // Note that we do this both for editing and inserting...  it
            // would be reasonable to only do it when inserting.
            if (isFinishing() && (length == 0) && !mNoteOnly) {
                setResult(RESULT_CANCELED);
                deleteNote();

            // Get out updates into the provider.
            } else {
                // This stuff is only done when working with a full-fledged note.
                if (!mNoteOnly) {
                    // Bump the modification time to now.
                    mCursor.updateLong(MODIFIED_INDEX, System.currentTimeMillis());

                    // If we are creating a new note, then we want to also create
                    // an initial title for it.
                    if (mState == STATE_INSERT) {
                        String title = text.substring(0, Math.min(30, length));
                        if (length > 30) {
                            int lastSpace = title.lastIndexOf(' ");
                            if (lastSpace > 0) {
                                title = title.substring(0, lastSpace);
                            }
                        }
                        mCursor.updateString(TITLE_INDEX, title);
                    }
                }

                // Write our text back into the provider.
                mCursor.updateString(NOTE_INDEX, text);

                // Commit all of our changes to persistent storage.  Note the
                // use of managedCommitUpdates() instead of
                // mCursor.commitUpdates() -- this lets Activity take care of
                // requerying the new data if needed.
                managedCommitUpdates(mCursor);
            }
        }
    
protected voidonResume()

        super.onResume();

        // If we didn't have any trouble retrieving the data, it is now
        // time to get at the stuff.
        if (mCursor != null) {
            // Make sure we are at the one and only row in the cursor.
            mCursor.first();

            // Modify our overall title depending on the mode we are running in.
            if (mState == STATE_EDIT) {
                setTitle(getText(R.string.title_edit));
            } else if (mState == STATE_INSERT) {
                setTitle(getText(R.string.title_create));
            }

            // This is a little nasty: we be resumed after previously being
            // paused/stopped.  We want to re-retrieve the data to make sure
            // we are still accurately showing what is in the cursor...  but
            // we don't want to lose any UI state like the current cursor
            // position.  This trick accomplishes that.  In the future we
            // should have a better API for doing this...
            Bundle curState = mText.saveState();
            String note = mCursor.getString(NOTE_INDEX);
            mText.setText(note);
            mText.restoreState(curState);
            
            // If we hadn't previously retrieved the original text, do so
            // now.  This allows the user to revert their changes.
            if (mOriginalContent == null) {
                mOriginalContent = note;
            }

        } else {
            setTitle(getText(R.string.error_title));
            mText.setText(getText(R.string.error_message));
        }