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