excludeFromSuggestions=true
page.title=Notepad Exercise 2
parent.title=Notepad Tutorial
parent.link=index.html
@jd:body


<p><em>In this exercise, you will add a second Activity to your notepad application, to let the user
create and edit notes. You will also allow the user to delete existing notes through a context menu.
The new Activity assumes responsibility for creating new notes by
collecting user input and packing it into a return Bundle provided by the intent. This exercise
demonstrates:</em></p>
<ul>
<li><em>Constructing a new Activity and adding it to the Android manifest</em></li>
<li><em>Invoking another Activity asynchronously using <code>startActivityForResult()</code></em></li>
<li><em>Passing data between Activity in Bundle objects</em></li>
<li><em>How to use a more advanced screen layout</em></li>
<li><em>How to create a context menu</em></li>
</ul>

<div style="float:right;white-space:nowrap">
	[<a href="notepad-ex1.html">Exercise 1</a>]
	<span style="color:#BBB;">
		[<a href="notepad-ex2.html" style="color:#DDD;">Exercise 2</a>]
	</span>
	[<a href="notepad-ex3.html">Exercise 3</a>]
	[<a href="notepad-extra-credit.html">Extra Credit</a>]
</div>

<h2>Step 1</h2>

<p>Create a new Android project using the sources from <code>Notepadv2</code> under the
<code>NotepadCodeLab</code> folder, just like you did for the first exercise. If you see an error about
<code>AndroidManifest.xml</code>, or some problems related to an
<code>android.zip</code> file, right click on the project and select <strong>Android
Tools</strong> &gt; <strong>Fix Project Properties</strong>.</p>

<p>Open the <code>Notepadv2</code> project and take a look around:</p>
<ul>
    <li>
      Open and look at the <code>strings.xml</code> file under
      <code>res/values</code> &mdash; there are several new strings which we will use
      for our new functionality
    </li>
    <li>
      Also, open and take a look at the top of the <code>Notepadv2</code> class,
      you will notice several new constants have been defined along with a new <code>mNotesCursor</code>
      field used to hold the cursor we are using.
    </li>
    <li>
      Note also that the <code>fillData()</code> method has a few more comments and now uses
      the new field to store the notes Cursor. The <code>onCreate()</code> method is
      unchanged from the first exercise. Also notice that the member field used to store the
      notes Cursor is now called <code>mNotesCursor</code>. The <code>m</code> denotes a member
      field and is part of the Android coding style standards.
    </li>
    <li>
      There are also a couple of new overridden methods
      (<code>onCreateContextMenu()</code>, <code>onContextItemSelected()</code>,
      <code>onListItemClick()</code> and <code>onActivityResult()</code>)
      which we will be filling in below.
    </li>
</ul>


<h2>Step 2</h2>
<div class="sidebox-wrapper">
<div class="sidebox">
<p>Context menus should always be used when performing actions upon specific elements in the UI.
When you register a View to a context menu, the context menu is revealed by performing a "long-click"
on the UI component (press and hold the touchscreen or highlight and hold down the selection key for about two seconds).</p>
</div>
</div>

<p>First, let's create the context menu that will allow users to delete individual notes.
Open the Notepadv2 class.</p>

<ol>
    <li>In order for each list item in the ListView to register for the context menu, we call
    <code>registerForContextMenu()</code> and pass it our ListView. So, at the very end of
    the <code>onCreate()</code> method add this line:
    <pre>registerForContextMenu(getListView());</pre>
    <p>Because our Activity extends the ListActivity class, <code>getListView()</code> will return us
    the local ListView object for the Activity. Now, each list item in this ListView will activate the
    context menu.
    <li>
      Now fill in the <code>onCreateContextMenu()</code> method. This callback is similar to the other
    menu callback used for the options menu. Here, we add just one line, which will add a menu item
    to delete a note. Call <code>menu.add()</code> like so:
      <pre>
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}</pre>
    <p>The <code>onCreateContextMenu()</code> callback passes some other information in addition to the Menu object,
    such as the View that has been triggered for the menu and
    an extra object that may contain additional information about the object selected. However, we don't care about
    these here, because we only have one kind of object in the Activity that uses context menus. In the next
    step, we'll handle the menu item selection.</p>
    </li>
</ol>

<h2>Step 3</h2>
  <p>Now that we've registered our ListView for a context menu and defined our context menu item, we need
  to handle the callback when it is selected. For this, we need to identify the list ID of the
  selected item, then delete it. So fill in the
  <code>onContextItemSelected()</code> method like this:</p>
<pre>
public boolean onContextItemSelected(MenuItem item) {
    switch(item.getItemId()) {
    case DELETE_ID:
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        mDbHelper.deleteNote(info.id);
        fillData();
        return true;
    }
    return super.onContextItemSelected(item);
}</pre>
<p>Here, we retrieve the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo}
with {@link android.view.MenuItem#getMenuInfo()}. The <var>id</var> field of this object tells us
the position of the item in the ListView. We then pass this to the <code>deleteNote()</code>
method of our NotesDbAdapter and the note is deleted. That's it for the context menu &mdash; notes
can now be deleted.</p>

<h2 style="clear:right;">Step 4</h2>
  <div class="sidebox-wrapper">
  <div class="sidebox">
    <h2>Starting Other Activities</h2>
    <p>In this example our Intent uses a class name specifically.
     As well as
     <a href="{@docRoot}resources/faq/commontasks.html#intentexamples">starting intents</a> in
    classes we already know about, be they in our own application or another
    application, we can also create Intents without knowing exactly which
    application will handle it.</p>
    <p>For example, we might want to open a page in a
    browser, and for this we still use
    an Intent. But instead of specifying a class to handle it, we use
    a predefined Intent constant, and a content URI that describes what we
    want to do. See {@link android.content.Intent
    android.content.Intent} for more information.</p>
  </div>
  </div>

	<p>Fill in the body of the <code>createNote()</code> method:
    <p>Create a new <code>Intent</code> to create a note
    (<code>ACTIVITY_CREATE</code>) using the <code>NoteEdit</code> class.
    Then fire the Intent using the <code>startActivityForResult()</code> method
    call:</p>
    <pre style="overflow:auto">
Intent i = new Intent(this, NoteEdit.class);
startActivityForResult(i, ACTIVITY_CREATE);</pre>
      <p>This form of the Intent call targets a specific class in our Activity, in this case
      <code>NoteEdit</code>. Since the Intent class will need to communicate with the Android
      operating system to route requests, we also have to provide a Context (<code>this</code>).</p>
      <p>The <code>startActivityForResult()</code> method fires the Intent in a way that causes a method
      in our Activity to be called when the new Activity is completed. The method in our Activity
      that receives the callback is called
      <code>onActivityResult()</code> and we will implement it in a later step. The other way
      to call an Activity is using <code>startActivity()</code> but this is a "fire-and-forget" way
      of calling it &mdash; in this manner, our Activity is not informed when the Activity is completed, and there is
      no way to return result information from the called Activity with <code>startActivity()</code>.
      <p>Don't worry about the fact that <code>NoteEdit</code> doesn't exist yet,
      we will fix that soon. </p>
  </li>


<h2>Step 5</h2>

	<p>Fill in the body of the <code>onListItemClick()</code> override.</p>
    <p><code>onListItemClick()</code> is a callback method that we'll override. It is called when
    the user selects an item from the list. It is passed four parameters: the
    <code>ListView</code> object it was invoked from, the <code>View</code>
    inside the <code>ListView</code> that was clicked on, the
    <code>position</code> in the list that was clicked, and the
    <code>mRowId</code> of the item that was clicked. In this instance we can
    ignore the first two parameters (we only have one <code>ListView</code> it
    could be), and we ignore the <code>mRowId</code> as well. All we are
    interested in is the <code>position</code> that the user selected. We use
    this to get the data from the correct row, and bundle it up to send to
    the <code>NoteEdit</code> Activity.</p>
   <p>In our implementation of the callback, the method creates an
    <code>Intent</code> to edit the note using
    the <code>NoteEdit</code> class. It then adds data into the extras Bundle of
    the Intent, which will be passed to the called Activity. We use it
    to pass in the title and body text, and the <code>mRowId</code> for the note we are
    editing. Finally, it will fire the Intent using the
    <code>startActivityForResult()</code> method call. Here's the code that
    belongs in <code>onListItemClick()</code>:</p>
    <pre>
super.onListItemClick(l, v, position, id);
Cursor c = mNotesCursor;
c.moveToPosition(position);
Intent i = new Intent(this, NoteEdit.class);
i.putExtra(NotesDbAdapter.KEY_ROWID, id);
i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString(
        c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(
        c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
startActivityForResult(i, ACTIVITY_EDIT);</pre>
  <ul>
    <li>
      <code>putExtra()</code> is the method to add items into the extras Bundle
      to pass in to intent invocations. Here, we are
      using the Bundle to pass in the title, body and mRowId of the note we want to edit.
    </li>
    <li>
      The details of the note are pulled out from our query Cursor, which we move to the
      proper position for the element that was selected in the list, with
      the <code>moveToPosition()</code> method.</li>
    <li>With the extras added to the Intent, we invoke the Intent on the
      <code>NoteEdit</code> class by passing <code>startActivityForResult()</code>
      the Intent and the request code. (The request code will be
      returned to <code>onActivityResult</code> as the <code>requestCode</code> parameter.)</li>
  </ul>
    <p class="note"><b>Note:</b> We assign the mNotesCursor field to a local variable at the
    start of the method. This is done as an optimization of the Android code. Accessing a local
    variable is much more efficient than accessing a field in the Dalvik VM, so by doing this
    we make only one access to the field, and five accesses to the local variable, making the
    routine much more efficient. It is recommended that you use this optimization when possible.</p>


<h2>Step 6</h2>

<p>The above <code>createNote()</code> and <code>onListItemClick()</code>
    methods use an asynchronous Intent invocation. We need a handler for the callback, so here we fill
    in the body of the <code>onActivityResult()</code>. </p>
<p><code>onActivityResult()</code> is the overridden method
    which will be called when an Activity returns with a result. (Remember, an Activity
    will only return a result if launched with <code>startActivityForResult</code>.) The parameters provided
    to the callback are: </p>
  <ul>
    <li><code>requestCode</code> &mdash; the original request code
    specified in the Intent invocation (either <code>ACTIVITY_CREATE</code> or
    <code>ACTIVITY_EDIT</code> for us).
    </li>
    <li><code>resultCode</code> &mdash; the result (or error code) of the call, this
    should be zero if everything was OK, but may have a non-zero code indicating
    that something failed. There are standard result codes available, and you
    can also create your own constants to indicate specific problems.
    </li>
    <li><code>intent</code> &mdash; this is an Intent created by the Activity returning
    results. It can be used to return data in the Intent "extras."
    </li>
  </ul>
  <p>The combination of <code>startActivityForResult()</code> and
  <code>onActivityResult()</code> can be thought of as an asynchronous RPC
  (remote procedure call) and forms the recommended way for an Activity to invoke
  another and share services.</p>
  <p>Here's the code that belongs in your <code>onActivityResult()</code>:</p>
    <pre>
super.onActivityResult(requestCode, resultCode, intent);
Bundle extras = intent.getExtras();

switch(requestCode) {
case ACTIVITY_CREATE:
    String title = extras.getString(NotesDbAdapter.KEY_TITLE);
    String body = extras.getString(NotesDbAdapter.KEY_BODY);
    mDbHelper.createNote(title, body);
    fillData();
    break;
case ACTIVITY_EDIT:
    Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
    if (mRowId != null) {
        String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);
        String editBody = extras.getString(NotesDbAdapter.KEY_BODY);
        mDbHelper.updateNote(mRowId, editTitle, editBody);
    }
    fillData();
    break;
}</pre>

  <ul>
    <li>
      We are handling both the <code>ACTIVITY_CREATE</code> and
      <code>ACTIVITY_EDIT</code> activity results in this method.
    </li>
    <li>
      In the case of a create, we pull the title and body from the extras (retrieved from the
      returned Intent) and use them to create a new note.
    </li>
    <li>
      In the case of an edit, we pull the mRowId as well, and use that to update
      the note in the database.
    </li>
    <li>
      <code>fillData()</code> at the end ensures everything is up to date .
    </li>
  </ul>


<h2>Step 7</h2>

  <div class="sidebox-wrapper">
  <div class="sidebox">
    <h2>The Art of Layout</h2>
    <p>The provided
    note_edit.xml layout file is the most sophisticated one in the application we will be building,
    but that doesn't mean it is even close to the kind of sophistication you will be likely to want
    in real Android applications.</p>
    <p>Creating a
    good UI is part art and part science, and the rest is work. Mastery of <a
    href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> is an essential part of
creating
    a good looking Android application.</p>
    <p>Take a look at the
    <a href="{@docRoot}resources/tutorials/views/index.html">Hello Views</a>
    for some example layouts and how to use them. The ApiDemos sample project is also a
    great resource from which to learn how to create different layouts.</p>
  </div>
  </div>

<p>Open the file <code>note_edit.xml</code> that has been provided and take a
    look at it. This is the UI code for the Note Editor.</p>
    <p>This is the most
    sophisticated UI we have dealt with yet. The file is given to you to avoid
    problems that may sneak in when typing the code. (The XML is very strict
    about case sensitivity and structure, mistakes in these are the usual cause
    of problems with layout.)</p>
    <p>There is a new parameter used
    here that we haven't seen before: <code>android:layout_weight</code> (in
    this case set to use the value 1 in each case).</p>
    <p><code>layout_weight</code> is used in LinearLayouts
    to assign "importance" to Views within the layout. All Views have a default
    <code>layout_weight</code> of zero, meaning they take up only as much room
    on the screen as they need to be displayed. Assigning a value higher than
    zero will split up the rest of the available space in the parent View, according
    to the value of each View's <code>layout_weight</code> and its ratio to the
    overall <code>layout_weight</code> specified in the current layout for this
    and other View elements.</p>
    <p>To give an example: let's say we have a text label
    and two text edit elements in a horizontal row. The label has no
    <code>layout_weight</code> specified, so it takes up the minimum space
    required to render. If the <code>layout_weight</code> of each of the two
    text edit elements is set to 1, the remaining width in the parent layout will
    be split equally between them (because we claim they are equally important).
    If the first one has a <code>layout_weight</code> of 1
    and the second has a <code>layout_weight</code> of 2, then one third of the
    remaining space will be given to the first, and two thirds to the
    second (because we claim the second one is more important).</p>
    <p>This layout also demonstrates how to nest multiple layouts
    inside each other to achieve a more complex and pleasant layout. In this
    example, a horizontal linear layout is nested inside the vertical one to
    allow the title label and text field to be alongside each other,
    horizontally.</p>


<h2 style="clear:right;">Step 8</h2>

	<p>Create a <code>NoteEdit</code> class that extends
    <code>android.app.Activity</code>.</p>
    <p>This is the first time we will have
    created an Activity without the Android Eclipse plugin doing it for us. When
    you do so, the <code>onCreate()</code> method is not automatically
    overridden for you. It is hard to imagine an Activity that doesn't override
    the <code>onCreate()</code> method, so this should be the first thing you do.</p>
  <ol>
    <li>Right click on the <code>com.android.demo.notepad2</code> package
    in the Package Explorer, and select <strong>New</strong> &gt; <strong>Class</strong> from the popup
    menu.</li>
    <li>Fill in <code>NoteEdit</code> for the <code>Name:</code> field in the
    dialog.</li>
    <li>In the <code>Superclass:</code> field, enter
    <code>android.app.Activity</code> (you can also just type Activity and hit
    Ctrl-Space on Windows and Linux or Cmd-Space on the Mac, to invoke code
    assist and find the right package and class).</li>
    <li>Click <strong>Finish</strong>.</li>
    <li>In the resulting <code>NoteEdit</code> class, right click in the editor
    window and select <strong>Source</strong> &gt; <strong>Override/Implement Methods...</strong></li>
    <li>Scroll down through the checklist in the dialog until you see
    <code>onCreate(Bundle)</code> &mdash; and check the box next to it.</li>
    <li>Click <strong>OK</strong>.<p>The method should now appear in your class.</p></li>
  </ol>

<h2>Step 9</h2>

<p>Fill in the body of the <code>onCreate()</code> method for <code>NoteEdit</code>.</p>

<p>This will set the title of our new Activity to say "Edit Note" (one
    of the strings defined in <code>strings.xml</code>). It will also set the
    content view to use our <code>note_edit.xml</code> layout file. We can then
    grab handles to the title and body text edit views, and the confirm button,
    so that our class can use them to set and get the note title and body,
    and attach an event to the confirm button for when it is pressed by the
    user.</p>
    <p>We can then unbundle the values that were passed in to the Activity
    with the extras Bundle attached to the calling Intent. We'll use them to pre-populate
    the title and body text edit views so that the user can edit them.
    Then we will grab and store the <code>mRowId</code> so we can keep
    track of what note the user is editing.</p>

  <ol>
    <li>
      Inside <code>onCreate()</code>, set up the layout:<br>
      <pre>setContentView(R.layout.note_edit);</pre>
    </li>
    <li>
      Change the Activity title to the "Edit Note" string:
      <pre>setTitle(R.string.edit_note);</pre>
    </li>
    <li>
      Find the {@link android.widget.EditText} and {@link android.widget.Button} components we need:
      <p>These are found by the
      IDs associated to them in the R class, and need to be cast to the right
      type of <code>View</code> (<code>EditText</code> for the two text views,
      and <code>Button</code> for the confirm button):</p>
      <pre>
mTitleText = (EditText) findViewById(R.id.title);
mBodyText = (EditText) findViewById(R.id.body);
Button confirmButton = (Button) findViewById(R.id.confirm);</pre>
      <p>Note that <code>mTitleText</code> and <code>mBodyText</code> are member
      fields (you need to declare them at the top of the class definition).</p>
    </li>
    <li>At the top of the class, declare a <code>Long mRowId</code> private field to store
      the current <code>mRowId</code> being edited (if any).
    </li>
    <li>Continuing inside <code>onCreate()</code>,
      add code to initialize the <code>title</code>, <code>body</code> and
      <code>mRowId</code> from the extras Bundle in
      the Intent (if it is present):<br>
      <pre>
mRowId = null;
Bundle extras = getIntent().getExtras();
if (extras != null) {
    String title = extras.getString(NotesDbAdapter.KEY_TITLE);
    String body = extras.getString(NotesDbAdapter.KEY_BODY);
    mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);

    if (title != null) {
        mTitleText.setText(title);
    }
    if (body != null) {
        mBodyText.setText(body);
    }
}</pre>
     <ul>
      <li>
        We are pulling the <code>title</code> and
        <code>body</code> out of the
        <code>extras</code> Bundle that was set from the
        Intent invocation.
      </li><li>
        We also null-protect the text field setting (i.e., we don't want to set
        the text fields to null accidentally).</li>
     </ul>
    </li>
    <li>
      Create an <code>onClickListener()</code> for the button:
      <p>Listeners can be one of the more confusing aspects of UI
      implementation, but
      what we are trying to achieve in this case is simple. We want an
      <code>onClick()</code> method to be called when the user presses the
      confirm button, and use that to do some work and return the values
      of the edited note to the Intent caller. We do this using something called
      an anonymous inner class. This is a bit confusing to look at unless you
      have seen them before, but all you really need to take away from this is
      that you can refer to this code in the future to see how to create a
      listener and attach it to a button. (Listeners are a common idiom
      in Java development, particularly for user interfaces.) Here's the empty listener:<br>
      <pre>
confirmButton.setOnClickListener(new View.OnClickListener() {

    public void onClick(View view) {

    }

});</pre>
    </li>
  </ol>
<h2>Step 10</h2>

<p>Fill in the body of the <code>onClick()</code> method of the <code>OnClickListener</code> created in the last step.</p>

    <p>This is the code that will be run when the user clicks on the
    confirm button. We want this to grab the title and body text from the edit
    text fields, and put them into the return Bundle so that they can be passed
    back to the Activity that invoked this <code>NoteEdit</code> Activity. If the
    operation is an edit rather than a create, we also want to put the
    <code>mRowId</code> into the Bundle so that the
    <code>Notepadv2</code> class can save the changes back to the correct
    note.</p>
  <ol>
    <li>
      Create a <code>Bundle</code> and put the title and body text into it using the
      constants defined in Notepadv2 as keys:<br>
      <pre>
Bundle bundle = new Bundle();

bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
if (mRowId != null) {
    bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
}</pre>
    </li>
    <li>
      Set the result information (the Bundle) in a new Intent and finish the Activity:
      <pre>
Intent mIntent = new Intent();
mIntent.putExtras(bundle);
setResult(RESULT_OK, mIntent);
finish();</pre>
      <ul>
      <li>The Intent is simply our data carrier that carries our Bundle
      (with the title, body and mRowId).</li>
      <li>The <code>setResult()</code> method is used to set the result
      code and return Intent to be passed back to the
      Intent caller. In this case everything worked, so we return RESULT_OK for the
      result code.</li>
      <li>The <code>finish()</code> call is used to signal that the Activity
      is done (like a return call). Anything set in the Result will then be
      returned to the caller, along with execution control.</li>
      </ul>
    </li>
   </ol>
   <p>The full <code>onCreate()</code> method (plus supporting class fields) should
      now look like this:</p>
      <pre>
private EditText mTitleText;
private EditText mBodyText;
private Long mRowId;

&#64;Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.note_edit);

    mTitleText = (EditText) findViewById(R.id.title);
    mBodyText = (EditText) findViewById(R.id.body);

    Button confirmButton = (Button) findViewById(R.id.confirm);

    mRowId = null;
    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        String title = extras.getString(NotesDbAdapter.KEY_TITLE);
        String body = extras.getString(NotesDbAdapter.KEY_BODY);
        mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);

        if (title != null) {
            mTitleText.setText(title);
        }
        if (body != null) {
            mBodyText.setText(body);
        }
    }

    confirmButton.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            Bundle bundle = new Bundle();

            bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
            bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
            if (mRowId != null) {
                bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
            }

            Intent mIntent = new Intent();
            mIntent.putExtras(bundle);
            setResult(RESULT_OK, mIntent);
            finish();
        }
    });
}</pre>
    </li>
  </ol>

<h2>Step 11</h2>

  <div class="sidebox-wrapper">
  <div class="sidebox">
    <h2>The All-Important Android Manifest File</h2>
  <p>The AndroidManifest.xml file is the way in which Android sees your
    application. This file defines the category of the application, where
    it shows up (or even if it shows up) in the launcher or settings, what
    activities, services, and content providers it defines, what intents it can
    receive, and more. </p>
    <p>For more information, see the reference document
    <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml
File</a></p>
  </div>
  </div>

<p>Finally, the new Activity has to be defined in the manifest file:</p>
    <p>Before the new Activity can be seen by Android, it needs its own
    Activity entry in the <code>AndroidManifest.xml</code> file. This is to let
    the system know that it is there and can be called. We could also specify
    which IntentFilters the activity implements here, but we are going to skip
    this for now and just let Android know that the Activity is
    defined.</p>
    <p>There is a Manifest editor included in the Eclipse plugin that makes it much easier
    to edit the AndroidManifest file, and we will use this. If you prefer to edit the file directly
    or are not using the Eclipse plugin, see the box at the end for information on how to do this
    without using the new Manifest editor.<p>
    <ol>
    <li>Double click on the <code>AndroidManifest.xml</code> file in the package explorer to open it.
    </li>
    <li>Click the <strong>Application</strong> tab at the bottom of the Manifest editor.</li>
    <li>Click <strong>Add...</strong> in the Application Nodes section.
      <p>If you see a dialog with radiobuttons at the top, select the top radio button:
      "Create a new element at the top level, in Application".</p></li>
    <li>Make sure "(A) Activity" is selected in the selection pane of the dialog, and click <strong>OK</strong>.</li>
    <li>Click on the new "Activity" node, in the Application Nodes section, then
    type <code>.NoteEdit</code> into the <em>Name*</em>
    field to the right. Press Return/Enter.</li>
    </ol>
    <p>The Android Manifest editor helps you add more complex entries into the AndroidManifest.xml
    file, have a look around at some of the other options available (but be careful not to select
    them otherwise they will be added to your Manifest). This editor should help you understand
    and alter the AndroidManifest.xml file as you move on to more advanced Android applications.</p>

    <p class="note">If you prefer to edit this file directly, simply open the
    <code>AndroidManifest.xml</code> file and look at the source (use the
    <code>AndroidManifest.xml</code> tab in the eclipse editor to see the source code directly).
    Then edit the file as follows:<br>
    <code>&lt;activity android:name=".NoteEdit" /&gt;</code><br><br>
    This should be placed just below the line that reads:<br>
    <code>&lt;/activity&gt;</code> for the <code>.Notepadv2</code> activity.</p>

<h2 style="clear:right;">Step 12</h2>

<p>Now Run it!</p>
<p>You should now be able to add real notes from
the menu, as well as delete an existing one. Notice that in order to delete, you must
first use the directional controls on the device to highlight the note.
Furthermore, selecting a note title from the list should bring up the note
editor to let you edit it. Press confirm when finished to save the changes
back to the database.

<h2>Solution and Next Steps</h2>

<p>You can see the solution to this exercise in  <code>Notepadv2Solution</code>
from the zip file to compare with your own.</p>
<p>Now try editing a note, and then hitting the back button on the emulator
instead of the confirm button (the back button is below the menu button). You
will see an error come up. Clearly our application still has some problems.
Worse still, if you did make some changes and hit the back button, when you go
back into the notepad to look at the note you changed, you will find that all
your changes have been lost. In the next exercise we will fix these
problems.</p>

<p>
Once you are ready, move on to <a href="notepad-ex3.html">Tutorial
Exercise 3</a> where you will fix the problems with the back button and lost
edits by introducing a proper life cycle into the NoteEdit Activity.</p>


