Rpage.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 boolean onCreateContextMenu(Menu 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 the 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">Declaring Layout</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>
      Find the edit and 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>


