Home | History | Annotate | Download | only in notepad
      1 Rpage.title=Notepad Exercise 2
      2 parent.title=Notepad Tutorial
      3 parent.link=index.html
      4 @jd:body
      5 
      6 
      7 <p><em>In this exercise, you will add a second Activity to your notepad application, to let the user
      8 create and edit notes. You will also allow the user to delete existing notes through a context menu.
      9 The new Activity assumes responsibility for creating new notes by
     10 collecting user input and packing it into a return Bundle provided by the intent. This exercise
     11 demonstrates:</em></p>
     12 <ul>
     13 <li><em>Constructing a new Activity and adding it to the Android manifest</em></li>
     14 <li><em>Invoking another Activity asynchronously using <code>startActivityForResult()</code></em></li>
     15 <li><em>Passing data between Activity in Bundle objects</em></li>
     16 <li><em>How to use a more advanced screen layout</em></li>
     17 <li><em>How to create a context menu</em></li>
     18 </ul>
     19 
     20 <div style="float:right;white-space:nowrap">
     21 	[<a href="notepad-ex1.html">Exercise 1</a>]
     22 	<span style="color:#BBB;">
     23 		[<a href="notepad-ex2.html" style="color:#DDD;">Exercise 2</a>]
     24 	</span>
     25 	[<a href="notepad-ex3.html">Exercise 3</a>]
     26 	[<a href="notepad-extra-credit.html">Extra Credit</a>]
     27 </div>
     28 
     29 <h2>Step 1</h2>
     30 
     31 <p>Create a new Android project using the sources from <code>Notepadv2</code> under the
     32 <code>NotepadCodeLab</code> folder, just like you did for the first exercise. If you see an error about
     33 <code>AndroidManifest.xml</code>, or some problems related to an
     34 <code>android.zip</code> file, right click on the project and select <strong>Android
     35 Tools</strong> &gt; <strong>Fix Project Properties</strong>.</p>
     36 
     37 <p>Open the <code>Notepadv2</code> project and take a look around:</p>
     38 <ul>
     39     <li>
     40       Open and look at the <code>strings.xml</code> file under
     41       <code>res/values</code> &mdash; there are several new strings which we will use
     42       for our new functionality
     43     </li>
     44     <li>
     45       Also, open and take a look at the top of the <code>Notepadv2</code> class,
     46       you will notice several new constants have been defined along with a new <code>mNotesCursor</code>
     47       field used to hold the cursor we are using.
     48     </li>
     49     <li>
     50       Note also that the <code>fillData()</code> method has a few more comments and now uses
     51       the new field to store the notes Cursor. The <code>onCreate()</code> method is
     52       unchanged from the first exercise. Also notice that the member field used to store the
     53       notes Cursor is now called <code>mNotesCursor</code>. The <code>m</code> denotes a member
     54       field and is part of the Android coding style standards.
     55     </li>
     56     <li>
     57       There are also a couple of new overridden methods
     58       (<code>onCreateContextMenu()</code>, <code>onContextItemSelected()</code>,
     59       <code>onListItemClick()</code> and <code>onActivityResult()</code>)
     60       which we will be filling in below.
     61     </li>
     62 </ul>
     63 
     64 
     65 <h2>Step 2</h2>
     66 <div class="sidebox-wrapper">
     67 <div class="sidebox">
     68 <p>Context menus should always be used when performing actions upon specific elements in the UI.
     69 When you register a View to a context menu, the context menu is revealed by performing a "long-click"
     70 on the UI component (press and hold the touchscreen or highlight and hold down the selection key for about two seconds).</p>
     71 </div>
     72 </div>
     73 
     74 <p>First, let's create the context menu that will allow users to delete individual notes.
     75 Open the Notepadv2 class.</p>
     76 
     77 <ol>
     78     <li>In order for each list item in the ListView to register for the context menu, we call
     79     <code>registerForContextMenu()</code> and pass it our ListView. So, at the very end of
     80     the <code>onCreate()</code> method add this line:
     81     <pre>registerForContextMenu(getListView());</pre>
     82     <p>Because our Activity extends the ListActivity class, <code>getListView()</code> will return us
     83     the local ListView object for the Activity. Now, each list item in this ListView will activate the
     84     context menu.
     85     <li>
     86       Now fill in the <code>onCreateContextMenu()</code> method. This callback is similar to the other
     87     menu callback used for the options menu. Here, we add just one line, which will add a menu item
     88     to delete a note. Call <code>menu.add()</code> like so:
     89       <pre>
     90 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
     91     super.onCreateContextMenu(menu, v, menuInfo);
     92     menu.add(0, DELETE_ID, 0, R.string.menu_delete);
     93 }</pre>
     94     <p>The <code>onCreateContextMenu()</code> callback passes some other information in addition to the Menu object,
     95     such as the View that has been triggered for the menu and
     96     an extra object that may contain additional information about the object selected. However, we don't care about
     97     these here, because we only have one kind of object in the Activity that uses context menus. In the next
     98     step, we'll handle the menu item selection.</p>
     99     </li>
    100 </ol>
    101 
    102 <h2>Step 3</h2>
    103   <p>Now that we've registered our ListView for a context menu and defined our context menu item, we need
    104   to handle the callback when it is selected. For this, we need to identify the list ID of the
    105   selected item, then delete it. So fill in the
    106   <code>onContextItemSelected()</code> method like this:</p>
    107 <pre>
    108 public boolean onContextItemSelected(MenuItem item) {
    109     switch(item.getItemId()) {
    110     case DELETE_ID:
    111         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    112         mDbHelper.deleteNote(info.id);
    113         fillData();
    114         return true;
    115     }
    116     return super.onContextItemSelected(item);
    117 }</pre>
    118 <p>Here, we retrieve the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo}
    119 with {@link android.view.MenuItem#getMenuInfo()}. The <var>id</var> field of this object tells us
    120 the position of the item in the ListView. We then pass this to the <code>deleteNote()</code>
    121 method of our NotesDbAdapter and the note is deleted. That's it for the context menu &mdash; notes
    122 can now be deleted.</p>
    123 
    124 <h2 style="clear:right;">Step 4</h2>
    125   <div class="sidebox-wrapper">
    126   <div class="sidebox">
    127     <h2>Starting Other Activities</h2>
    128     <p>In this example our Intent uses a class name specifically.
    129      As well as
    130      <a href="{@docRoot}resources/faq/commontasks.html#intentexamples">starting intents</a> in
    131     classes we already know about, be they in our own application or another
    132     application, we can also create Intents without knowing exactly which
    133     application will handle it.</p>
    134     <p>For example, we might want to open a page in a
    135     browser, and for this we still use
    136     an Intent. But instead of specifying a class to handle it, we use
    137     a predefined Intent constant, and a content URI that describes what we
    138     want to do. See {@link android.content.Intent
    139     android.content.Intent} for more information.</p>
    140   </div>
    141   </div>
    142 
    143 	<p>Fill in the body of the <code>createNote()</code> method:
    144     <p>Create a new <code>Intent</code> to create a note
    145     (<code>ACTIVITY_CREATE</code>) using the <code>NoteEdit</code> class.
    146     Then fire the Intent using the <code>startActivityForResult()</code> method
    147     call:</p>
    148     <pre style="overflow:auto">
    149 Intent i = new Intent(this, NoteEdit.class);
    150 startActivityForResult(i, ACTIVITY_CREATE);</pre>
    151       <p>This form of the Intent call targets a specific class in our Activity, in this case
    152       <code>NoteEdit</code>. Since the Intent class will need to communicate with the Android
    153       operating system to route requests, we also have to provide a Context (<code>this</code>).</p>
    154       <p>The <code>startActivityForResult()</code> method fires the Intent in a way that causes a method
    155       in our Activity to be called when the new Activity is completed. The method in our Activity
    156       that receives the callback is called
    157       <code>onActivityResult()</code> and we will implement it in a later step. The other way
    158       to call an Activity is using <code>startActivity()</code> but this is a "fire-and-forget" way
    159       of calling it &mdash; in this manner, our Activity is not informed when the Activity is completed, and there is
    160       no way to return result information from the called Activity with <code>startActivity()</code>.
    161       <p>Don't worry about the fact that <code>NoteEdit</code> doesn't exist yet,
    162       we will fix that soon. </p>
    163   </li>
    164 
    165 
    166 <h2>Step 5</h2>
    167 
    168 	<p>Fill in the body of the <code>onListItemClick()</code> override.</p>
    169     <p><code>onListItemClick()</code> is a callback method that we'll override. It is called when
    170     the user selects an item from the list. It is passed four parameters: the
    171     <code>ListView</code> object it was invoked from, the <code>View</code>
    172     inside the <code>ListView</code> that was clicked on, the
    173     <code>position</code> in the list that was clicked, and the
    174     <code>mRowId</code> of the item that was clicked. In this instance we can
    175     ignore the first two parameters (we only have one <code>ListView</code> it
    176     could be), and we ignore the <code>mRowId</code> as well. All we are
    177     interested in is the <code>position</code> that the user selected. We use
    178     this to get the data from the correct row, and bundle it up to send to
    179     the <code>NoteEdit</code> Activity.</p>
    180    <p>In our implementation of the callback, the method creates an
    181     <code>Intent</code> to edit the note using
    182     the <code>NoteEdit</code> class. It then adds data into the extras Bundle of
    183     the Intent, which will be passed to the called Activity. We use it
    184     to pass in the title and body text, and the <code>mRowId</code> for the note we are
    185     editing. Finally, it will fire the Intent using the
    186     <code>startActivityForResult()</code> method call. Here's the code that
    187     belongs in <code>onListItemClick()</code>:</p>
    188     <pre>
    189 super.onListItemClick(l, v, position, id);
    190 Cursor c = mNotesCursor;
    191 c.moveToPosition(position);
    192 Intent i = new Intent(this, NoteEdit.class);
    193 i.putExtra(NotesDbAdapter.KEY_ROWID, id);
    194 i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString(
    195         c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
    196 i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(
    197         c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
    198 startActivityForResult(i, ACTIVITY_EDIT);</pre>
    199   <ul>
    200     <li>
    201       <code>putExtra()</code> is the method to add items into the extras Bundle
    202       to pass in to intent invocations. Here, we are
    203       using the Bundle to pass in the title, body and mRowId of the note we want to edit.
    204     </li>
    205     <li>
    206       The details of the note are pulled out from our query Cursor, which we move to the
    207       proper position for the element that was selected in the list, with
    208       the <code>moveToPosition()</code> method.</li>
    209     <li>With the extras added to the Intent, we invoke the Intent on the
    210       <code>NoteEdit</code> class by passing <code>startActivityForResult()</code>
    211       the Intent and the request code. (The request code will be
    212       returned to <code>onActivityResult</code> as the <code>requestCode</code> parameter.)</li>
    213   </ul>
    214     <p class="note"><b>Note:</b> We assign the mNotesCursor field to a local variable at the
    215     start of the method. This is done as an optimization of the Android code. Accessing a local
    216     variable is much more efficient than accessing a field in the Dalvik VM, so by doing this
    217     we make only one access to the field, and five accesses to the local variable, making the
    218     routine much more efficient. It is recommended that you use this optimization when possible.</p>
    219 
    220 
    221 <h2>Step 6</h2>
    222 
    223 <p>The above <code>createNote()</code> and <code>onListItemClick()</code>
    224     methods use an asynchronous Intent invocation. We need a handler for the callback, so here we fill
    225     in the body of the <code>onActivityResult()</code>. </p>
    226 <p><code>onActivityResult()</code> is the overridden method
    227     which will be called when an Activity returns with a result. (Remember, an Activity
    228     will only return a result if launched with <code>startActivityForResult</code>.) The parameters provided
    229     to the callback are: </p>
    230   <ul>
    231     <li><code>requestCode</code> &mdash; the original request code
    232     specified in the Intent invocation (either <code>ACTIVITY_CREATE</code> or
    233     <code>ACTIVITY_EDIT</code> for us).
    234     </li>
    235     <li><code>resultCode</code> &mdash; the result (or error code) of the call, this
    236     should be zero if everything was OK, but may have a non-zero code indicating
    237     that something failed. There are standard result codes available, and you
    238     can also create your own constants to indicate specific problems.
    239     </li>
    240     <li><code>intent</code> &mdash; this is an Intent created by the Activity returning
    241     results. It can be used to return data in the Intent "extras."
    242     </li>
    243   </ul>
    244   <p>The combination of <code>startActivityForResult()</code> and
    245   <code>onActivityResult()</code> can be thought of as an asynchronous RPC
    246   (remote procedure call) and forms the recommended way for an Activity to invoke
    247   another and share services.</p>
    248   <p>Here's the code that belongs in your <code>onActivityResult()</code>:</p>
    249     <pre>
    250 super.onActivityResult(requestCode, resultCode, intent);
    251 Bundle extras = intent.getExtras();
    252 
    253 switch(requestCode) {
    254 case ACTIVITY_CREATE:
    255     String title = extras.getString(NotesDbAdapter.KEY_TITLE);
    256     String body = extras.getString(NotesDbAdapter.KEY_BODY);
    257     mDbHelper.createNote(title, body);
    258     fillData();
    259     break;
    260 case ACTIVITY_EDIT:
    261     Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
    262     if (mRowId != null) {
    263         String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);
    264         String editBody = extras.getString(NotesDbAdapter.KEY_BODY);
    265         mDbHelper.updateNote(mRowId, editTitle, editBody);
    266     }
    267     fillData();
    268     break;
    269 }</pre>
    270 
    271   <ul>
    272     <li>
    273       We are handling both the <code>ACTIVITY_CREATE</code> and
    274       <code>ACTIVITY_EDIT</code> activity results in this method.
    275     </li>
    276     <li>
    277       In the case of a create, we pull the title and body from the extras (retrieved from the
    278       returned Intent) and use them to create a new note.
    279     </li>
    280     <li>
    281       In the case of an edit, we pull the mRowId as well, and use that to update
    282       the note in the database.
    283     </li>
    284     <li>
    285       <code>fillData()</code> at the end ensures everything is up to date .
    286     </li>
    287   </ul>
    288 
    289 
    290 <h2>Step 7</h2>
    291 
    292   <div class="sidebox-wrapper">
    293   <div class="sidebox">
    294     <h2>The Art of Layout</h2>
    295     <p>The provided
    296     note_edit.xml layout file is the most sophisticated one in the application we will be building,
    297     but that doesn't mean it is even close to the kind of sophistication you will be likely to want
    298     in real Android applications.</p>
    299     <p>Creating a
    300     good UI is part art and part science, and the rest is work. Mastery of <a
    301     href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> is an essential part of
    302 creating
    303     a good looking Android application.</p>
    304     <p>Take a look at the
    305     <a href="{@docRoot}resources/tutorials/views/index.html">Hello Views</a>
    306     for some example layouts and how to use them. The ApiDemos sample project is also a
    307     great resource from which to learn how to create different layouts.</p>
    308   </div>
    309   </div>
    310 
    311 <p>Open the file <code>note_edit.xml</code> that has been provided and take a
    312     look at it. This is the UI code for the Note Editor.</p>
    313     <p>This is the most
    314     sophisticated UI we have dealt with yet. The file is given to you to avoid
    315     problems that may sneak in when typing the code. (The XML is very strict
    316     about case sensitivity and structure, mistakes in these are the usual cause
    317     of problems with layout.)</p>
    318     <p>There is a new parameter used
    319     here that we haven't seen before: <code>android:layout_weight</code> (in
    320     this case set to use the value 1 in each case).</p>
    321     <p><code>layout_weight</code> is used in LinearLayouts
    322     to assign "importance" to Views within the layout. All Views have a default
    323     <code>layout_weight</code> of zero, meaning they take up only as much room
    324     on the screen as they need to be displayed. Assigning a value higher than
    325     zero will split up the rest of the available space in the parent View, according
    326     to the value of each View's <code>layout_weight</code> and its ratio to the
    327     overall <code>layout_weight</code> specified in the current layout for this
    328     and other View elements.</p>
    329     <p>To give an example: let's say we have a text label
    330     and two text edit elements in a horizontal row. The label has no
    331     <code>layout_weight</code> specified, so it takes up the minimum space
    332     required to render. If the <code>layout_weight</code> of each of the two
    333     text edit elements is set to 1, the remaining width in the parent layout will
    334     be split equally between them (because we claim they are equally important).
    335     If the first one has a <code>layout_weight</code> of 1
    336     and the second has a <code>layout_weight</code> of 2, then one third of the
    337     remaining space will be given to the first, and two thirds to the
    338     second (because we claim the second one is more important).</p>
    339     <p>This layout also demonstrates how to nest multiple layouts
    340     inside each other to achieve a more complex and pleasant layout. In this
    341     example, a horizontal linear layout is nested inside the vertical one to
    342     allow the title label and text field to be alongside each other,
    343     horizontally.</p>
    344 
    345 
    346 <h2 style="clear:right;">Step 8</h2>
    347 
    348 	<p>Create a <code>NoteEdit</code> class that extends
    349     <code>android.app.Activity</code>.</p>
    350     <p>This is the first time we will have
    351     created an Activity without the Android Eclipse plugin doing it for us. When
    352     you do so, the <code>onCreate()</code> method is not automatically
    353     overridden for you. It is hard to imagine an Activity that doesn't override
    354     the <code>onCreate()</code> method, so this should be the first thing you do.</p>
    355   <ol>
    356     <li>Right click on the <code>com.android.demo.notepad2</code> package
    357     in the Package Explorer, and select <strong>New</strong> &gt; <strong>Class</strong> from the popup
    358     menu.</li>
    359     <li>Fill in <code>NoteEdit</code> for the <code>Name:</code> field in the
    360     dialog.</li>
    361     <li>In the <code>Superclass:</code> field, enter
    362     <code>android.app.Activity</code> (you can also just type Activity and hit
    363     Ctrl-Space on Windows and Linux or Cmd-Space on the Mac, to invoke code
    364     assist and find the right package and class).</li>
    365     <li>Click <strong>Finish</strong>.</li>
    366     <li>In the resulting <code>NoteEdit</code> class, right click in the editor
    367     window and select <strong>Source</strong> &gt; <strong>Override/Implement Methods...</strong></li>
    368     <li>Scroll down through the checklist in the dialog until you see
    369     <code>onCreate(Bundle)</code> &mdash; and check the box next to it.</li>
    370     <li>Click <strong>OK</strong>.<p>The method should now appear in your class.</p></li>
    371   </ol>
    372 
    373 <h2>Step 9</h2>
    374 
    375 <p>Fill in the body of the <code>onCreate()</code> method for <code>NoteEdit</code>.</p>
    376 
    377 <p>This will set the title of our new Activity to say "Edit Note" (one
    378     of the strings defined in <code>strings.xml</code>). It will also set the
    379     content view to use our <code>note_edit.xml</code> layout file. We can then
    380     grab handles to the title and body text edit views, and the confirm button,
    381     so that our class can use them to set and get the note title and body,
    382     and attach an event to the confirm button for when it is pressed by the
    383     user.</p>
    384     <p>We can then unbundle the values that were passed in to the Activity
    385     with the extras Bundle attached to the calling Intent. We'll use them to pre-populate
    386     the title and body text edit views so that the user can edit them.
    387     Then we will grab and store the <code>mRowId</code> so we can keep
    388     track of what note the user is editing.</p>
    389 
    390   <ol>
    391     <li>
    392       Inside <code>onCreate()</code>, set up the layout:<br>
    393       <pre>setContentView(R.layout.note_edit);</pre>
    394     </li>
    395     <li>
    396       Change the Activity title to the "Edit Note" string:
    397       <pre>setTitle(R.string.edit_note);</pre>
    398     </li>
    399     <li>
    400       Find the {@link android.widget.EditText} and {@link android.widget.Button} components we need:
    401       <p>These are found by the
    402       IDs associated to them in the R class, and need to be cast to the right
    403       type of <code>View</code> (<code>EditText</code> for the two text views,
    404       and <code>Button</code> for the confirm button):</p>
    405       <pre>
    406 mTitleText = (EditText) findViewById(R.id.title);
    407 mBodyText = (EditText) findViewById(R.id.body);
    408 Button confirmButton = (Button) findViewById(R.id.confirm);</pre>
    409       <p>Note that <code>mTitleText</code> and <code>mBodyText</code> are member
    410       fields (you need to declare them at the top of the class definition).</p>
    411     </li>
    412     <li>At the top of the class, declare a <code>Long mRowId</code> private field to store
    413       the current <code>mRowId</code> being edited (if any).
    414     </li>
    415     <li>Continuing inside <code>onCreate()</code>,
    416       add code to initialize the <code>title</code>, <code>body</code> and
    417       <code>mRowId</code> from the extras Bundle in
    418       the Intent (if it is present):<br>
    419       <pre>
    420 mRowId = null;
    421 Bundle extras = getIntent().getExtras();
    422 if (extras != null) {
    423     String title = extras.getString(NotesDbAdapter.KEY_TITLE);
    424     String body = extras.getString(NotesDbAdapter.KEY_BODY);
    425     mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
    426 
    427     if (title != null) {
    428         mTitleText.setText(title);
    429     }
    430     if (body != null) {
    431         mBodyText.setText(body);
    432     }
    433 }</pre>
    434      <ul>
    435       <li>
    436         We are pulling the <code>title</code> and
    437         <code>body</code> out of the
    438         <code>extras</code> Bundle that was set from the
    439         Intent invocation.
    440       </li><li>
    441         We also null-protect the text field setting (i.e., we don't want to set
    442         the text fields to null accidentally).</li>
    443      </ul>
    444     </li>
    445     <li>
    446       Create an <code>onClickListener()</code> for the button:
    447       <p>Listeners can be one of the more confusing aspects of UI
    448       implementation, but
    449       what we are trying to achieve in this case is simple. We want an
    450       <code>onClick()</code> method to be called when the user presses the
    451       confirm button, and use that to do some work and return the values
    452       of the edited note to the Intent caller. We do this using something called
    453       an anonymous inner class. This is a bit confusing to look at unless you
    454       have seen them before, but all you really need to take away from this is
    455       that you can refer to this code in the future to see how to create a
    456       listener and attach it to a button. (Listeners are a common idiom
    457       in Java development, particularly for user interfaces.) Here's the empty listener:<br>
    458       <pre>
    459 confirmButton.setOnClickListener(new View.OnClickListener() {
    460 
    461     public void onClick(View view) {
    462 
    463     }
    464 
    465 });</pre>
    466     </li>
    467   </ol>
    468 <h2>Step 10</h2>
    469 
    470 <p>Fill in the body of the <code>onClick()</code> method of the <code>OnClickListener</code> created in the last step.</p>
    471 
    472     <p>This is the code that will be run when the user clicks on the
    473     confirm button. We want this to grab the title and body text from the edit
    474     text fields, and put them into the return Bundle so that they can be passed
    475     back to the Activity that invoked this <code>NoteEdit</code> Activity. If the
    476     operation is an edit rather than a create, we also want to put the
    477     <code>mRowId</code> into the Bundle so that the
    478     <code>Notepadv2</code> class can save the changes back to the correct
    479     note.</p>
    480   <ol>
    481     <li>
    482       Create a <code>Bundle</code> and put the title and body text into it using the
    483       constants defined in Notepadv2 as keys:<br>
    484       <pre>
    485 Bundle bundle = new Bundle();
    486 
    487 bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
    488 bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
    489 if (mRowId != null) {
    490     bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
    491 }</pre>
    492     </li>
    493     <li>
    494       Set the result information (the Bundle) in a new Intent and finish the Activity:
    495       <pre>
    496 Intent mIntent = new Intent();
    497 mIntent.putExtras(bundle);
    498 setResult(RESULT_OK, mIntent);
    499 finish();</pre>
    500       <ul>
    501       <li>The Intent is simply our data carrier that carries our Bundle
    502       (with the title, body and mRowId).</li>
    503       <li>The <code>setResult()</code> method is used to set the result
    504       code and return Intent to be passed back to the
    505       Intent caller. In this case everything worked, so we return RESULT_OK for the
    506       result code.</li>
    507       <li>The <code>finish()</code> call is used to signal that the Activity
    508       is done (like a return call). Anything set in the Result will then be
    509       returned to the caller, along with execution control.</li>
    510       </ul>
    511     </li>
    512    </ol>
    513    <p>The full <code>onCreate()</code> method (plus supporting class fields) should
    514       now look like this:</p>
    515       <pre>
    516 private EditText mTitleText;
    517 private EditText mBodyText;
    518 private Long mRowId;
    519 
    520 &#64;Override
    521 protected void onCreate(Bundle savedInstanceState) {
    522     super.onCreate(savedInstanceState);
    523     setContentView(R.layout.note_edit);
    524 
    525     mTitleText = (EditText) findViewById(R.id.title);
    526     mBodyText = (EditText) findViewById(R.id.body);
    527 
    528     Button confirmButton = (Button) findViewById(R.id.confirm);
    529 
    530     mRowId = null;
    531     Bundle extras = getIntent().getExtras();
    532     if (extras != null) {
    533         String title = extras.getString(NotesDbAdapter.KEY_TITLE);
    534         String body = extras.getString(NotesDbAdapter.KEY_BODY);
    535         mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
    536 
    537         if (title != null) {
    538             mTitleText.setText(title);
    539         }
    540         if (body != null) {
    541             mBodyText.setText(body);
    542         }
    543     }
    544 
    545     confirmButton.setOnClickListener(new View.OnClickListener() {
    546 
    547         public void onClick(View view) {
    548             Bundle bundle = new Bundle();
    549 
    550             bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
    551             bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
    552             if (mRowId != null) {
    553                 bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
    554             }
    555 
    556             Intent mIntent = new Intent();
    557             mIntent.putExtras(bundle);
    558             setResult(RESULT_OK, mIntent);
    559             finish();
    560         }
    561     });
    562 }</pre>
    563     </li>
    564   </ol>
    565 
    566 <h2>Step 11</h2>
    567 
    568   <div class="sidebox-wrapper">
    569   <div class="sidebox">
    570     <h2>The All-Important Android Manifest File</h2>
    571   <p>The AndroidManifest.xml file is the way in which Android sees your
    572     application. This file defines the category of the application, where
    573     it shows up (or even if it shows up) in the launcher or settings, what
    574     activities, services, and content providers it defines, what intents it can
    575     receive, and more. </p>
    576     <p>For more information, see the reference document
    577     <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml
    578 File</a></p>
    579   </div>
    580   </div>
    581 
    582 <p>Finally, the new Activity has to be defined in the manifest file:</p>
    583     <p>Before the new Activity can be seen by Android, it needs its own
    584     Activity entry in the <code>AndroidManifest.xml</code> file. This is to let
    585     the system know that it is there and can be called. We could also specify
    586     which IntentFilters the activity implements here, but we are going to skip
    587     this for now and just let Android know that the Activity is
    588     defined.</p>
    589     <p>There is a Manifest editor included in the Eclipse plugin that makes it much easier
    590     to edit the AndroidManifest file, and we will use this. If you prefer to edit the file directly
    591     or are not using the Eclipse plugin, see the box at the end for information on how to do this
    592     without using the new Manifest editor.<p>
    593     <ol>
    594     <li>Double click on the <code>AndroidManifest.xml</code> file in the package explorer to open it.
    595     </li>
    596     <li>Click the <strong>Application</strong> tab at the bottom of the Manifest editor.</li>
    597     <li>Click <strong>Add...</strong> in the Application Nodes section.
    598       <p>If you see a dialog with radiobuttons at the top, select the top radio button:
    599       "Create a new element at the top level, in Application".</p></li>
    600     <li>Make sure "(A) Activity" is selected in the selection pane of the dialog, and click <strong>OK</strong>.</li>
    601     <li>Click on the new "Activity" node, in the Application Nodes section, then
    602     type <code>.NoteEdit</code> into the <em>Name*</em>
    603     field to the right. Press Return/Enter.</li>
    604     </ol>
    605     <p>The Android Manifest editor helps you add more complex entries into the AndroidManifest.xml
    606     file, have a look around at some of the other options available (but be careful not to select
    607     them otherwise they will be added to your Manifest). This editor should help you understand
    608     and alter the AndroidManifest.xml file as you move on to more advanced Android applications.</p>
    609 
    610     <p class="note">If you prefer to edit this file directly, simply open the
    611     <code>AndroidManifest.xml</code> file and look at the source (use the
    612     <code>AndroidManifest.xml</code> tab in the eclipse editor to see the source code directly).
    613     Then edit the file as follows:<br>
    614     <code>&lt;activity android:name=".NoteEdit" /&gt;</code><br><br>
    615     This should be placed just below the line that reads:<br>
    616     <code>&lt;/activity&gt;</code> for the <code>.Notepadv2</code> activity.</p>
    617 
    618 <h2 style="clear:right;">Step 12</h2>
    619 
    620 <p>Now Run it!</p>
    621 <p>You should now be able to add real notes from
    622 the menu, as well as delete an existing one. Notice that in order to delete, you must
    623 first use the directional controls on the device to highlight the note.
    624 Furthermore, selecting a note title from the list should bring up the note
    625 editor to let you edit it. Press confirm when finished to save the changes
    626 back to the database.
    627 
    628 <h2>Solution and Next Steps</h2>
    629 
    630 <p>You can see the solution to this exercise in  <code>Notepadv2Solution</code>
    631 from the zip file to compare with your own.</p>
    632 <p>Now try editing a note, and then hitting the back button on the emulator
    633 instead of the confirm button (the back button is below the menu button). You
    634 will see an error come up. Clearly our application still has some problems.
    635 Worse still, if you did make some changes and hit the back button, when you go
    636 back into the notepad to look at the note you changed, you will find that all
    637 your changes have been lost. In the next exercise we will fix these
    638 problems.</p>
    639 
    640 <p>
    641 Once you are ready, move on to <a href="notepad-ex3.html">Tutorial
    642 Exercise 3</a> where you will fix the problems with the back button and lost
    643 edits by introducing a proper life cycle into the NoteEdit Activity.</p>
    644 
    645 
    646