📄 index.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"><title>AddressBook Example</title><link href="style.css" rel="stylesheet" type="text/css"></head><table border="0" width="100%" height="8" bgcolor="#eeeeee"> <tr> <td width="100%" height="1"><b><font size="2" color="#000000" face="Arial, Helvetica, sans-serif"><strong><a name=Top></a> S60 3rd Edition SDK for Symbian OS </strong></font></b><br><i>Example Applications Guide</i></td></tr> </table><!-- Generated by Doxygen 1.4.5 --><h1>AddressBook Example</h1><p><a class="el" href="index.html#intro_sec">1. About this Example</a> <br><a class="el" href="index.html#Pre_sec">2. Prerequisites</a> <br><a class="el" href="index.html#Design_sec">3. Design and Implementation</a> <br><a class="el" href="index.html#Build_sec">4. Building and Running</a> <br><a class="el" href="index.html#Hierarchy_sec">4. Class Hierarchy</a><p><hr><h2><a class="anchor" name="intro_sec">1. About this Example</a></h2>The purpose of this application is to provide an example, including source code, of the use of the Nokia Web Services Framework so that developers can test and run the application against a live server. The server will be hosted by Forum Nokia and provide the interface specified later in this document.<p>The sample is a small address book application, which enables the user to find information such as name, address, phone number, job title, and so on about other users. The sample utilizes a Liberty-based address book web service hosted by Forum Nokia, which providers the interface specified in section <a class="el" href="index.html#Sub34">3.4 "AddressBookConstants.h" file</a>. The service will not be perfect address book service, as that is not needed to show the use of the Web Services framework. Those enhancements would make no difference on the use of the Web Services Framework and so would be just unnecessary work for this example.<p>The application will be used in S60 3.0 terminals. It is using Symbian native interfaces provided by native Nokia Web Services Framework. The latter framework takes care of tasks such as authentication, service discovery and connection management thus letting the application developer to focus on the application level logic.<p><div align="center"><img src="AddressBookIntroduction.jpg" alt="AddressBookIntroduction.jpg"></div> <b> <center> figure1: Environment overview </center></b><p><hr><h2><a class="anchor" name="Pre_sec">2. Prerequisites</a></h2>This example makes use of the standard Symbian OS application framework, comprising the Application, Document, UI, and View classes. The reader should be aware of this architecture before attempting to understand this example. It is also assumed that the reader is familiar with the concepts related to Web Services. Knowledge of Liberty Alliance specifications (<a href="http://www.projectliberty.org/">http://www.projectliberty.org/</a>) is an asset.<p>It's necessary to have LAN Connection support for an emulator and GPRS Connection support for a device.<h3><a class="anchor" name="Sub21">2.1 Emulator</a></h3>In emulator configure network settings from tools->Preferences-network.<p><hr><h2><a class="anchor" name="Design_sec">3. Design and Implementation</a></h2>This section starts with explaining the capabilities that the program can use. After that, the support using different screen modes are explained. And then in this section is detailed the design and implementation of each of the following four components required to get information about some employee used mechanism of Web Services:<p><ul><li>Connection</li><li>Searching</li><li>AddToContant</li><li>BrowseCard</li></ul><h3><a class="anchor" name="Sub31">3.1 Capabilities</a></h3>The program capabilities are defined in AddressBook.mmp file: CAPABILITY NetworkServices ReadUserData WriteUserData WriteDeviceData ReadDeviceData.<h3><a class="anchor" name="Sub32">3.2 ScalableUI</a></h3>The program takes screen parameters in the start of the application and works with all screen modes. The program supports changing the screen layout while the program is running.<h3><a class="anchor" name="Sub33">3.3 Connection</a></h3><div align="center"><img src="AddressBookConnection.jpg" alt="AddressBookConnection.jpg"></div> <b> <center> figure 2: Connection </center></b><p>Message Description<p>1: <a class="el" href="class_c_address_book_app_ui.html#a682d228622cea7790645ce10f591242">CAddressBookAppUi::HandleCommandL(TInt aCommand)</a> is called on the AppUi object whenever the user selects a menu option. The argument aCommand indicates the command the user selected. In case if the user chose "EaddressBookCmdAppConnect" to connect with a provider than function CAknWaitNoteWrapper::ExecuteL(R_CONNECTING_NOTE, *this, ETrue) runs the active scheduler, that calls CAknWaitNoteWrapper::RunL(), it checks:<p>3: Is process already done? - function <a class="el" href="class_c_address_book_app_ui.html#34fc7596f70aed6415e69cc09bec0968">CAddressBookAppUi::IsProcessDone()</a> (it is overridden from interface MAknBackgroundProcess).<p>4: If process is not done yet then CAknWaitNoteWrapper::RunL() calls <a class="el" href="class_c_address_book_app_ui.html#2b047861e8a98fc470be28703b1bd9d0">CAddressBookAppUi::StepL()</a> that does one step of processing (it is overridden from interface MAknBackgroundProcess). This step establishes connection.<p>5: <a class="el" href="class_c_address_book_engine.html#e8a170fa40d8d9d67f0cebf751b96e87">CAddressBookEngine::ConnectL()</a> is run from <a class="el" href="class_c_address_book_app_ui.html#2b047861e8a98fc470be28703b1bd9d0">CAddressBookAppUi::StepL()</a>. Makes a connection to an ID-WSF service. When <a class="el" href="class_c_address_book_engine.html#e8a170fa40d8d9d67f0cebf751b96e87">CAddressBookEngine::ConnectL()</a> is called the first time, authentication and discovery services are connected and the user is therefore authenticated and the service is connected. When <a class="el" href="class_c_address_book_engine.html#e8a170fa40d8d9d67f0cebf751b96e87">CAddressBookEngine::ConnectL()</a> is called again and the credentials received from authentication and discovery services are valid, there are no need to connect to them again. This means that <a class="el" href="class_c_address_book_engine.html#0faeae2b736ff345e0f3392bc5ade7e4">CAddressBookEngine::SetStatus(const TInt aStatus)</a> will be called almost immediately with value CONNECTED, but in device GPRS or data connection is not opened yet (but instead it is opened when search occurs).<p>6: <a class="el" href="class_c_address_book_engine.html#27169094a7dab01d3a23984924dc0819">CAddressBookEngine::RegisterIdentityProviderL()</a> is called from <a class="el" href="class_c_address_book_engine.html#e8a170fa40d8d9d67f0cebf751b96e87">CAddressBookEngine::ConnectL()</a>. It registers services. It creates the CSenServiceManager instance and uses it to register Identity Provider and Authentication Service (AS) Description. The AS is also associated with the registered IdentityProvider.<p>7: <a class="el" href="class_c_address_book_engine.html#0faeae2b736ff345e0f3392bc5ade7e4">CAddressBookEngine::SetStatus(const TInt aStatus)</a> gets status info about connection (STATUS_NEW, STATUS_READY or STATUS_EXIRED) to be initialized. It is called by CSenServiceConnectionImpl::RunL() that is called by active scheduler from <a class="el" href="class_c_address_book_app_ui.html#a682d228622cea7790645ce10f591242">CAddressBookAppUi::HandleCommandL(TInt aCommand)</a> in case "EAddressBookCmdAppConnect".<p>8: <a class="el" href="class_c_address_book_app_ui.html#0a22907cd96f62d44b6543dddf3704ee">CAddressBookAppUi::ConnectionReady()</a> calls when connection is done.<p>9-11: Checks Is process already done - function <a class="el" href="class_c_address_book_app_ui.html#34fc7596f70aed6415e69cc09bec0968">CAddressBookAppUi::IsProcessDone()</a>? If connection is established the active scheduler calls functions <a class="el" href="class_c_address_book_app_ui.html#9fadb422c50df5ad198f645d92cf408c">CAddressBookAppUi::ProcessFinished()</a> and <a class="el" href="class_c_address_book_app_ui.html#2220dbb6fc6782a5030c8164fcc2c231">CAddressBookAppUi::DialogDismissedL(TInt aButtonId)</a> which is overridden from interface MaknBackgroundProcess.<h3><a class="anchor" name="Sub34">3.4 "AddressBookConstants.h" file</a></h3>This file contains constants that describe Address Book service. This information is localized in the separate file specially that to avoid modifications inside the source code if will be some changes in the Address Book service (for example ProviderContract /EndPoint /testAuthentication ID /testPassword /Provider ID /WS Framework ID).<p>The service is hosted by Forum Nokia and its connection parameters are listed in the table below.<p><div align="center"><img src="AddressBookServiceParameters.jpg" alt="AddressBookServiceParameters.jpg"></div> <b> <center> figure 3: Address Book service connection parameters </center></b><h3><a class="anchor" name="Sub35">3.5 Searching</a></h3><div align="center"><img src="AddressBookSearching.jpg" alt="AddressBookSearching.jpg"></div> <b> <center> figure 4: Searching</center></b><p>Message Description<p>1: <a class="el" href="class_c_address_book_app_ui.html#a682d228622cea7790645ce10f591242">CAddressBookAppUi::HandleCommandL(TInt aCommand)</a> is called on the AppUi object whenever the user selects a menu option. The argument aCommand indicates the command the user selected. In case if the user chose "EAddressBookCmdAppSearch" to search contact information about an employee than function CAknWaitNoteWrapper::ExecuteL(R_SEARCHING_NOTE, *this) runs the active scheduler, that calls CSenServiceConnectionImpl::RunL() and it calls function <a class="el" href="class_c_address_book_engine.html#6f6aab8e9e405117f0c28455489d2b8a">CAddressBookEngine::HandleMessageL(const TDesC8& aMessage)</a> (it is overridden from interface MSenServiceConsumer) for receiving messages from the CSenServiceConnection::SendL() function.<p>2: <a class="el" href="class_c_address_book_view.html#67f946ca7848ec78de4961c5bcefdb72">CAddressBookView::Draw()</a> draws help information "How need to search".<p>3: <a class="el" href="class_c_address_book_view.html#67f946ca7848ec78de4961c5bcefdb72">CAddressBookView::Draw()</a> draws the window for typing query.<p>4-8: <a class="el" href="class_c_address_book_engine.html#747630896453ebd94401850077f9ce1e">CAddressBookEngine::SendSearchL(const TDesC& aSearchPattern)</a> sends query entered by user. Create a search pattern from the descriptor and send it to the WSP. The message from server is received through <a class="el" href="class_c_address_book_engine.html#6f6aab8e9e405117f0c28455489d2b8a">CAddressBookEngine::HandleMessageL(const TDesC8& aMessage)</a> or an error is received through <a class="el" href="class_c_address_book_engine.html#d19d90d4095917ffb09489ecd08cb5ad">CAddressBookEngine::HandleErrorL(const TInt aErrorCode, const TDesC8& aError)</a>.<p>12-38: Receiving and parsing message from server. Xmlparser calls <a class="el" href="class_c_address_book_engine.html#a575736176d644c609425a199cd04601">CAddressBookEngine::StartElementL(const TDesC8& aNsUri, const TDesC8& aLocalName, const TDesC8& aQName, const RAttributeArray& aAttrs)</a> every time a new element tag is found and <a class="el" href="class_c_address_book_engine.html#5c88d61ffcf6558d9df3aa9ec9b60a33">CAddressBookEngine::EndElementL(const TDesC8& aNsUri, const TDesC8& aLocalName, const TDesC8& aQName)</a> every time a closing element tag is found. In our case we are interested in the <Status> and <Card> elements. When Status is found, we compare if attribute 'Code' is OK or not. CSenXmlUtils::LocalName() only extracts out a possible XML prefix (i.e. 'ab:OK'). When local name is 'Card', we have encountered a contact-object. Then we make a new <a class="el" href="class_c_address_book_contact.html">CAddressBookContact</a> and delegate the parsing to it.<p>39-46: <a class="el" href="class_c_address_book_app_ui.html#cb5842c326a788fa5aaa4f00cc718c06">CAddressBookAppUi::SearchFinishedL(RPointerArray<CAddressBookContact>& aContactArray)</a> finishes searching and <a class="el" href="class_c_address_book_view.html#2f829fab6b84b31478f831680aa6cabb">CAddressBookView::UpdateL(RPointerArray<CAddressBookContact>& aContactArray)</a> parses information and creates received information in convenient for user view.<p>47,48: Checks Is process already done - function <a class="el" href="class_c_address_book_app_ui.html#34fc7596f70aed6415e69cc09bec0968">CAddressBookAppUi::IsProcessDone()</a>? If connection is established the active scheduler calls functions <a class="el" href="class_c_address_book_app_ui.html#9fadb422c50df5ad198f645d92cf408c">CAddressBookAppUi::ProcessFinished()</a> and <a class="el" href="class_c_address_book_app_ui.html#2220dbb6fc6782a5030c8164fcc2c231">CAddressBookAppUi::DialogDismissedL(TInt aButtonId)</a> which is overridden from interface MaknBackgroundProcess.<p>49: <a class="el" href="class_c_address_book_view.html#67f946ca7848ec78de4961c5bcefdb72">CAddressBookView::Draw()</a> draws the list of contacts matched under user's query.<h4><a class="anchor" name="Subsub351">3.5.1 Structure for address card</a></h4>Below is the structure for address cards presented in XML style to give an idea what data is supported for cards.<p><div align="center"><img src="AddressBookCard.jpg" alt="AddressBookCard.jpg"></div> <b> <center> </center></b><h4><a class="anchor" name="Subsub352">3.5.2 Message examples</a></h4>This section contains message examples. First there is a basic query to request address cards containing phone number 1234. The only changing parts are the <ResourceID> and <Select> parameters. The <Select> parameter defines, what is requested. See Sub353, for more details.<p><div align="center"><img src="AddressBookMessageExample1.jpg" alt="AddressBookMessageExample1.jpg"></div> <b> <center> </center></b><p>The response has two changing parts. Status code depends on the processing results on the service side. The <Data> element contains the returned data. It may include one or more <Card> elements. Each card element has those elements for which content/values are specified.<p><div align="center"><img src="AddressBookMessageExample2.jpg" alt="AddressBookMessageExample2.jpg"></div> <b> <center> </center></b><p><div align="center"><img src="AddressBookMessageExample3.jpg" alt="AddressBookMessageExample3.jpg"></div> <b> <center> </center></b><p><div align="center"><img src="AddressBookMessageExample4.jpg" alt="AddressBookMessageExample4.jpg"></div> <b> <center> </center></b><h4><a class="anchor" name="Subsub353">3.5.3 Select</a></h4>The Select parameter is a string containing an XPath expression based on XPath 1.0. Some examples on the expressions that can be used on the client side can be found below:<p><ul><li>Querying based on the phone number: /ab:Card[ab:TEL="1234"]</li><li>Querying based on the family name: /ab:Card[ab:N/ab:FAMILY="Smith"]</li><li>Querying based on the given name: /ab:Card[ab:N/ab:GIVEN="John"]</li><li>Querying based on the family and given name: /ab:Card[ab:N/ab:FAMILY="Smith" and ab:N/ab:GIVEN="John"]</li></ul><h3><a class="anchor" name="Sub36">3.6 AddToContact</a></h3><div align="center"><img src="AddressBookAddToContact.jpg" alt="AddressBookAddToContact.jpg"></div> <b> <center> figure5: Add to Contact</center></b><p>Message Description<p>1: <a class="el" href="class_c_address_book_app_ui.html#a682d228622cea7790645ce10f591242">CAddressBookAppUi::HandleCommandL(TInt aCommand)</a> is called on the AppUi object whenever the user selects a menu option. The argument aCommand indicates the command the user selected. In case if the user chose "EAddressBookCmdAppAdd" to add contact in phone book.<p>2,3: <a class="el" href="class_c_address_book_engine.html#c53d64c2194748449107eeb2403042dc">CAddressBookEngine::GetContact(TInt aPosition, CAddressBookContact*& aContact)</a> and <a class="el" href="class_c_address_book_view.html#3fca94e0717b8f64d65f54d582de140c">CAddressBookView::CurrentContact()</a> get information from current contact.<p>4: CPbkContactEngine::CreateEmptyContactL() creates an empty item for contact information.<p>5-10: <a class="el" href="class_c_address_book_contact.html#11bc9239e5e38f769c8746ed0ee905b8">CAddressBookContact::PhoneL()</a>, <a class="el" href="class_c_address_book_contact.html#6e69a9a71f021dae6d2dfae56693596b">CAddressBookContact::MobilePhoneL()</a>, <a class="el" href="class_c_address_book_contact.html#624abd04a3de415e4359a9d84cde81fd">CAddressBookContact::SelectedPhoneL(const TDesC8& aType)</a>, <a class="el" href="class_c_address_book_app_ui.html#35d06dd229187c83865b64b3641093a2">CAddressBookAppUi::UpdateFieldL(CPbkContactItem* modifiableItem, TPbkFieldId fieldId, const TDesC8& newValue)</a> add in this item information about the mobile and general phones.<p>11-13: <a class="el" href="class_c_address_book_contact.html#4b802aff47351035b51fb72861a29253">CAddressBookContact::FirstName()</a>, <a class="el" href="class_c_address_book_contact.html#f368973b66cad205e19433a8d92a8287">CAddressBookContact::ChildValue(const TDesC8& aFirstElement, const TDesC8& aSecondElement)</a>, <a class="el" href="class_c_address_book_app_ui.html#35d06dd229187c83865b64b3641093a2">CAddressBookAppUi::UpdateFieldL(CPbkContactItem* modifiableItem, TPbkFieldId fieldId, const TDesC8& newValue)</a> also add information about the first name. The same steps follow for adding information about last name/fax/email/organization/title and street.<p>14: CPbkContactEngine::AddNewContactL() adds new item about contact information in phonebook's database.<h3><a class="anchor" name="Sub37">3.7 BrowseCard</a></h3><div align="center"><img src="AddressBookBrowseCard.jpg" alt="AddressBookBrowseCard.jpg"></div> <b> <center> figure6: Browse Card</center></b><p>Message Description<p>1: <a class="el" href="class_c_address_book_view.html#28b4d6276c0cf24f7346e6e4b0bc36d3">CAddressBookView::HandleListBoxEventL(CEikListBox*, TListBoxEvent aEventType)</a> is called whenever the user presses "enter" button (EeventEnterKeyPressed) to browse full information about the employee.<p>2,3: <a class="el" href="class_c_address_book_view.html#701faad87d37369ca943be1b272f3615">CAddressBookView::OpenItemL()</a> and <a class="el" href="class_c_address_book_engine.html#c53d64c2194748449107eeb2403042dc">CAddressBookEngine::GetContact(TInt aPosition, CAddressBookContact*& aContact)</a> get information about current contact.<p>4-6: <a class="el" href="class_c_address_book_view.html#4aa2ddf5a7c1bfd948d2125c8f8ea40f">CAddressBookView::AppendRowL(TPtrC8 aValue, const TDesC8& aFieldName, CDesCArray& aArray)</a>, <a class="el" href="class_c_address_book_contact.html#33e7486e759bad0c39c5f72ac3e4bd89">CAddressBookContact::LastName()</a>, <a class="el" href="class_c_address_book_contact.html#624abd04a3de415e4359a9d84cde81fd">CAddressBookContact::SelectedPhoneL(const TDesC8& aType)</a> convert information about last name that to draw it as the separate row.<p>7-9: <a class="el" href="class_c_address_book_view.html#4aa2ddf5a7c1bfd948d2125c8f8ea40f">CAddressBookView::AppendRowL(TPtrC8 aValue, const TDesC8& aFieldName, CDesCArray& aArray)</a>, <a class="el" href="class_c_address_book_contact.html#11bc9239e5e38f769c8746ed0ee905b8">CAddressBookContact::PhoneL()</a>, <a class="el" href="class_c_address_book_contact.html#f368973b66cad205e19433a8d92a8287">CAddressBookContact::ChildValue(const TDesC8& aFirstElement, const TDesC8& aSecondElement)</a> convert information about phone that to draw it as the separate row. The same steps follow for first name/middle name/extra address/street/locality/region/post code/country/mobile phone/fax/email/title/organization/unit.<p>10: <a class="el" href="class_c_address_book_view.html#df3662103f51dd273915341322626ceb">CAddressBookView::ChangeCbaL(TInt aResourceId, TDrawNow aDrawNow)</a> sets aResourceId = R_AVKON_SOFTKEYS_OPTIONS_BACK and state = EdrawNow.<p>11: <a class="el" href="class_c_address_book_view.html#67f946ca7848ec78de4961c5bcefdb72">CAddressBookView::Draw()</a> draws full information about employee who was found as rows.<p><hr><h2><a class="anchor" name="Build_sec">4. Building and Running</a></h2>When the application starts up, the following screen appears:<p><div align="center"><img src="image001.jpg" alt="image001.jpg"></div> <b> <center> </center></b><p>Selecting the Options soft key displays the following 3 choices:<p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -