Sup Devguide Android Object API Applications
Comments
Description
Developer Guide: Android Object API ApplicationsSybase Unwired Platform 2.2 SP01 DOCUMENT ID: DC01726-01-0221-01 LAST REVISED: November 2012 Copyright © 2012 by Sybase, Inc. All rights reserved. This publication pertains to Sybase software and to any subsequent release until otherwise indicated in new editions or technical notes. Information in this document is subject to change without notice. The software described herein is furnished under a license agreement, and it may be used or copied only in accordance with the terms of that agreement. Upgrades are provided only at regularly scheduled software release dates. No part of this publication may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without the prior written permission of Sybase, Inc. Sybase trademarks can be viewed at the Sybase trademarks page at http://www.sybase.com/detail?id=1011207. Sybase and the marks listed are trademarks of Sybase, Inc. ® indicates registration in the United States of America. SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and in several other countries all over the world. Java and all Java-based marks are trademarks or registered trademarks of Oracle and/or its affiliates in the U.S. and other countries. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. All other company and product names mentioned may be trademarks of the respective companies with which they are associated. Use, duplication, or disclosure by the government is subject to the restrictions set forth in subparagraph (c)(1)(ii) of DFARS 52.227-7013 for the DOD and as set forth in FAR 52.227-19(a)-(d) for civilian agencies. Sybase, Inc., One Sybase Drive, Dublin, CA 94568. Contents Getting Started with Android Development ........................1 Object API Applications ..................................................1 Best Uses for Object API Applications ............................2 Cache Synchronization ..........................................2 Client Runtime Architecture ...................................3 Documentation Roadmap for Unwired Platform .............4 Development Task Flow for Object API Applications .........5 Installing the Android Development Environment ...........6 Installing the Android SDK .....................................7 Installing ADT in Unwired WorkSpace ...................7 Installing X.509 Certificates on Android Devices and Emulators ..................................................7 Generating Java Object API Code ..................................8 Generating Java Object API Code Using Sybase Unwired WorkSpace ..........................................9 Generating Java Object API Code Using the Code Generation Utility ...................................13 Generated Code Location and Contents .............14 Validating Generated Code ..................................14 Creating a Project .........................................................15 Creating a Project in Unwired WorkSpace ..........15 Downloading the Latest Afaria Libraries ..............18 Importing Libraries and Code ..............................18 Development Task Flow for DOE-based Object API Applications .....................................................................19 Installing the Android Development Environment .........20 Installing the Android SDK ...................................20 Installing ADT in Unwired WorkSpace .................21 Installing X.509 Certificates on Android Devices and Emulators ................................................21 Generating Java Object API Code ................................22 Developer Guide: Android Object API Applications iii ................50 Shutting Down the Application ....................................52 Deleting the Database and Unregistering the Application .................51 Closing Connections ............................................................ and Deleting MBO Records .......29 Initially Starting an Application ..................53 Testing an Application Using a Emulator .....52 Testing Applications ..................................................................................61 Application APIs ......61 Client Object API Reference .......................................................................29 Initializing an Application ........................................................................................................................61 iv Sybase Unwired Platform .......................................................................55 Localizing Applications ..45 Object Queries ..............................................................................................................44 Accessing MBO Data ....23 Creating a Project ..................................................................................................................................................29 Subsequently Starting an Application ...........................................53 Server-Side Debugging .....................................................47 Relationships ...........51 Uninstalling the Application .47 Manipulating Data .........................................50 Using SubmitPending and SubmitPendingOperations ..................................59 Signing ....................48 Creating.....24 Downloading the Latest Afaria Libraries .....Contents Generated Code Location and Contents ..................................................53 Client-Side Debugging ...................................................................................................27 Importing Libraries and Code ....................57 Packaging Applications ... Updating.......27 Developing the Application Using the Object API .59 Client Object API Usage ...............................................................................49 Other Operations ...............................45 Dynamic Queries ..................................................................................46 MBOs with Complex Types ........24 Creating a Project in Unwired WorkSpace ................... ....................................................100 Sample Code ................................................91 Using Afaria to Provision Configuration Data .................................................................................................................99 Authentication APIs ................110 Retrieving Information about Synchronization Groups ........100 Logging In ..............................................................101 Personalization APIs ....................................................................... 97 Synchronization Profile ......111 Logger APIs .102 Type of Personalization Keys ................. 98 Asynchronous Operation Replay ...........................................................................................................................103 Synchronization APIs .......91 Using Certificates from Afaria for Authentication ............................................................81 ConnectionPropertyType .......................................73 ApplicationSettings .....112 Developer Guide: Android Object API Applications v ............................................................ 95 Set Database File Property ...........105 Push Synchronization Applications .....................111 LogRecord API .............................100 Single Sign-On With X...Contents Application ..................509 Certificate Related Object API ...........85 Afaria APIs .........95 ConnectionProfile ...........................................................104 Changing Synchronization Parameters ...............................................................................................................................................................104 Performing Mobile Business Object Synchronization .............93 Connection APIs ................................................................104 Message-Based Synchronization APIs .............................111 Log Record APIs .........................................................................................................................................................103 Getting and Setting Personalization Key Values .........61 ConnectionProperties ...............................97 Connect the Data Synchronization Channel Through a Relay Server .... ..............114 getSurrogateKey .........................113 getOperationType ............................157 Persistence APIs .................180 AttributeMetaData ......................................170 MetaData API .............................................................................................180 MetaData API ................................181 Exceptions .........147 Retrieving Data from Mobile Business Objects ...............................................................114 getRootSurrogateKey ...........................................115 Code Samples ................................................................................156 Back-end Search ................................................................................................................................................................................117 Security APIs .181 vi Sybase Unwired Platform ..................................138 ApplicationCallback API ...................................170 Large Attribute APIs ....................................................146 Query APIs ........................118 Connect Using a Certificate .........138 CallbackHandler API ..................................................119 Callback and Listener APIs .........181 Handling Exceptions .................................................180 ClassMetaData ....158 Object State APIs .................................................145 SyncStatusListener API .............................. 147 Retrieving Relationship Data ........................................180 EntityMetaData ............................................158 Operations APIs .................Contents Change Log API .....113 getRootEntityType ..............................................164 Generated Package Database APIs ........................................................................................118 Encrypt the Database .......................................................................113 getEntityType ...................................................................................118 DataVault ...........................................................................................................118 End to End Encryption and Compression Support APIs ...............180 DatabaseMetaData ........................115 Methods in the Generated Database Class ......... .......................183 ....................Contents Index Exception Classes ........185 Developer Guide: Android Object API Applications vii ........................................................................... Contents viii Sybase Unwired Platform . Object API Applications Object API applications are customized. The Object API application model enables developers to write custom code — C#. procedures for setting up the development environment.2 SP01 contains information for developers who are migrating device applications to a newer software version. or Objective-C. and Client Object API documentation. • Server-side components address the interaction between the enterprise information system (EIS) data source and the data cache. This guide describes requirements for developing a device application for the platform. even for minor changes or updates. and changes to MBOs. EIS data subsets and business logic are Developer Guide: Android Object API Applications 1 . and a description of how Sybase Unwired Platform implements the concepts in your enterprise. either using mobile business objects (MBOs) or Data Orchestration Engine. Unwired Server brokers data synchronization and transaction processing between the server and the client components. Development of Object API applications provides the most flexibility in terms of leveraging platform specific services. to facilitate connection with a variety of enterprise systems and leverage synchronization to support offline capabilities. full-featured mobile applications that use mobile data model packages. Development involves both server-side and client-side components. Also included are task flows for the development options. The audience is advanced developers who may be new to Sybase Unwired Platform.Getting Started with Android Development Getting Started with Android Development Use advanced Sybase® Unwired Platform features to create applications for Android devices. and how to customize the generated code using the Client Object API. depending on the target device platform — to create device applications. but each application must be provisioned individually after being compiled.Mobile Business Object Development Development Supported Hardware and Software Troubleshooting. A complete Client Object API reference is available in the Unwired Platform installation directory SUP_HOME\MobileSDK22\ObjectAPI\apidoc\android Fundamentals contains high-level mobile computing concepts. Companion guides include: • • • • • • Sybase Unwired WorkSpace . and the Unwired Server. projects. Java. Developer Guide: Migrating to Sybase Mobile SDK 2. how to generate application code. Build in more complex data handling and logic. Because of the direct nature of application parameter mapping and RBS protocol efficiencies. • These applications: • • • • Best Uses for Object API Applications Synchronization applications provide operation replay between the mobile device. This can include synchronizing data with the server. for example. called mobile business object packages. Normally. Custom native applications are designed and built to suit specific business scenarios from the ground up. or where service occurs in remote locations and workers might 2 Sybase Unwired Platform . the middleware. and data change notification.Getting Started with Android Development encapsulated in artifacts. Allow users to connect to data from a variety of EIS systems. can occur in task worker (service) applications that must access large product catalogs. offline data access capabilities. The mobile content model and the mapping to the back end are directly integrated. Cache Synchronization Cache synchronization allows mapping mobile data to SAP Remote Function Calls (RFCs) using Java Connector (JCO) and to other non-SAP data sources such as databases and Web services. including SAP® systems. or start with a bespoke application and be adapted with a large degree of customization. and the back-end system. that are deployed to Unwired Server. When Sybase Unwired Platform is used in a stand-alone manner for data synchronization (without Data Orchestation Engine). Client-side components are built into the mobile application and address the interaction between the data cache and the mobile device data store. the mobile application is designed such that the developer specifies how to load data from the back end into the cache and then filters and downloads cache data using device-supplied parameters. it utilizes an efficient bulk transfer and data insertion technology between the middleware cache and the device database. some mobile-specific adaptation is required within SAP Business Application Programming Interfaces (BAPI). Ensure secure and reliable transport of data. This style of coupling between device and back-end queries implies that the back end must be able to respond to requests from the middleware based on user-supplied parameters and serve up mobile data appropriately. Leverage data synchronization to optimize and balance device response time and need for real-time data. In an Unwired Platform standalone deployment. Sybase Unwired Platform cache synchronization deployment is ideal: • • • With large payloads to devices (may be due to mostly disconnected scenarios) Where ad hoc data downloads might be expected For SAP® or non-SAP back ends Large payloads. Mobile Channel Interfaces Two main channel interfaces provide notifications and data transport to and from remote devices. The messaging channel sends these types of communications: • Application registration . While Sybase Unwired Platform synchronization does benefit from middleware caching. The application must call another synchronize method to retrieve the result. The Unwired Server synchronizes data between the device and the back-end by maintaining records of device synchronization activity in its cache database along with any cached data that may have been retrieved from the back-end or pushed from the device.when the Unwired Server detects changes in the back-end EIS.the messaging channel is used for synchronization for DOE applications. • The messaging channel serves as the abstraction to all device-side notifications (BlackBerry Enterprise Service. the Unwired Server can send a notification to the device. • Mobile Middleware Services Mobile middleware services (MMS) arbitrate and manage communications between device requests from the mobile channel interfaces in the form that is suitable for transformation to a Developer Guide: Android Object API Applications 3 . The synchronization context in the callback has a status you can retrieve. The Unwired Server employs several components in the synchronization chain. • SAP Data Orchestration Engine (DOE) application synchronization . the enterprise system of record). you can register an onSynchronize callback. The synchronization channel sends data to keep the Unwired Server and client synchronized. direct coupling requires the back end to support an adaptation where mobile user data can be determined. sending change notifications is disabled. To capture change notifications.Getting Started with Android Development synchronize once a day. devices can be notified of changes relevant for their application and configuration. these records are sent to the Unwired Server and the messaging channel sends a notification of replayFinished. intermediate staging areas/caches and so on) are eventually synchronized to have the same data/state on that system. Apple Push Notification Service. and others) so that when changes to back-end data occur.the messaging channel is used for application registration before establishing a connection to the Unwired Server. The synchronization is bi-directional. The assumption is that if data changes on one tier (for example. • Change notifications . By default. Client Runtime Architecture The goal of synchronization is to keep views (that is. but you can enable sending change notifications per synchronization group. • Operation replay records .when synchronizing. the state) of data consistent among multiple tiers. all other tiers interested in that data (mobile devices. or those originating elsewhere.a=0&.com/sybooks/sybooks. See Documentation Roadmap in Fundamentals for document descriptions by user role. Documentation Roadmap for Unwired Platform Sybase® Unwired Platform documents are available for administrative and mobile development user roles.Getting Started with Android Development common MBO service request and a canonical form of enterprise data supplied by the data services. are replicated to the device database. some documents are used by all users. Some administrative documents are also used in the development and test environment. Check the Sybase Product Documentation Web site regularly for updates: http:// sybooks. Data services and mobile middleware services together manage the cache database (CDB) where data is cached as it is synchronized with client devices. Cache data and messages persist in the databases in the data tier. 4 Sybase Unwired Platform .sybase.xhtml? id=1289&. Data that changes on the EIS as a result of device changes. it can be deployed to the Unwired Server where it operates as part of a specialized container-managed package interfacing with the mobile middleware services and data services components. Once a mobile application model is designed.p=categories . Changes made on the device are passed to the mobile middleware services component as an operation replay and replayed against the data services interfaces with the EIS. then navigate to the most current version.c=firsttab&. Data Services Data services is the conduit to enterprise data and operations within the firewall or hosted in the cloud. The Callback Handler and Listener APIs. for individual MBOs. using the Object API and custom device application coding.Development Task Flow for Object API Applications Development Task Flow for Object API Applications Describes the overall development task flow for Object API applications. 1. business logic. validation. The Object API provides the core application services described in the diagram. or changes in data. and performance. or as a group. based on the group's synchronization policy. and developing device applications. With non-DOE-based applications. This is how you create device applications with sophisticated UI interaction. The Synchronization APIs allow you to synchronize mobile business objects (MBOs) based on synchronization parameters. This diagram illustrates how you can develop a device application directly from mobile business objects (MBOs). Installing the Android Development Environment Developer Guide: Android Object API Applications 5 . The Application and Connection APIs allow clients to register with and connect to the Unwired Server. and the Target Change Notification APIs provide notifications to the client on operation success or failure. connectivity uses the MobiLink™ channel and notifications use the Messaging channel. The Authentication APIs provide security by authenticating the client to the Unwired Server. and provides information and procedures for setting up the development environment. Installing the Android Development Environment Install the Android development environment. 3. Installing the Android SDK Install the Android SDK. and may be required by an organization's security policy. See also • Generating Java Object API Code on page 8 6 Sybase Unwired Platform .p12 certificate on the Android device or emulator for authentication. 5. Developing the Application Using the Object API Use the Object API to develop the application. Installing X. Creating a Project Build a device application project. and prepare Android devices for authentication. Localizing Applications Localize an Android application by creating default and alternate resources. Generating Java Object API Code Generate object API code containing mobile business object (MBO) references. Testing Applications Test native applications on a device or simulator.509 Certificates on Android Devices and Emulators Install the . 1. or by using a command line utility for generating code. An application consists of building blocks which the developer uses to start the application. 3. 4. which allows you to use APIs to develop device applications for Android devices. 2. Installing ADT in Unwired WorkSpace You can install the supported version of Android Development Tools (ADT) directly in the Unwired WorkSpace Eclipse environment. Packaging Applications Package applications according to your security or application distribution requirements.Development Task Flow for Object API Applications Install the Android development environment. perform functions needed for the application. 2. You can generate code either in Sybase Unwired WorkSpace. 7. and prepare Android devices for authentication. A certificate provides an additional level of secure access to an application. and shutdown and uninstall the application. 6. com/sybooks/ sybooks. 9. 1.Development Task Flow for Object API Applications Installing the Android SDK Install the Android SDK.509 Certificates on Android Devices and Emulators Install the . and may be required by an organization's security policy. Start Eclipse. a list of downloadable tools. in the top-right corner. In the Add Repository dialog. Select the ADT Plugin for Eclipse zip file. select Development Tools. and create an Android virtual device to use as your emulator. Download and install the supported version of the Android SDK starter package.zip.0.com/sdk/ requirements. 3. 3. Installing X. then click OK. then click Next. 2. 6.html. restart Unwired WorkSpace. Download the ADT Plugin for Eclipse at http://dl.google. In the Available Software dialog. 4. Enter a Name for the local update site. Launch the Android SDK Manager and install the Android tools (SDK Tools and SDK Platform-tools) and the Android API. 7. Note: If you get a security warning about the authenticity or validity of the software. 1.sybase. Confirm that your system meets the requirements at http://developer. click Next.xhtml.1. 8. Prerequisites • Java SE Development Kit (JDK) must be installed. Launch the Android Virtual Device Manager. In the next window. Developer Guide: Android Object API Applications 7 . Accept the license agreements. such as Android Plugin. then click Finish. click OK. See Google Android Versions for Object API at http://sybooks. When the installation completes. Click Add. Navigate to the appropriate version of Sybase Unwired Platform.com/android/ADT-16.p12 certificate on the Android device or emulator for authentication. 4. click Archive.android. A certificate provides an additional level of secure access to an application. 10. Installing ADT in Unwired WorkSpace You can install the supported version of Android Development Tools (ADT) directly in the Unwired WorkSpace Eclipse environment. 2. 5. then select Help > Install New Software. d) In the top right of the File Explorer view. for example. C:\Program Files\android-sdk-windows\tools. Task 1.Development Task Flow for Object API Applications • The Android SDK must be installed. From the menu bar. e) In the Put File on Device dialog. select the certificate and click Open. You can generate code either in Sybase Unwired WorkSpace. 4. To install using the Android Debug Bridge (adb): Note: USB debugging must be enabled. c) Click Device Storage. a) Open the Windows File Explorer view.exe file. a) Open Windows Explorer b) Under your computer. which allows you to use APIs to develop device applications for Android devices.p12 /sdcard/ MyCert. navigate to Window > Show View > Other. click Push a file onto the device. 3. To install using Windows Explorer: Note: USB debugging must be disabled. expand the Android folder and select File Explorer. click the Android device to expand the folder. or C:\Program Files \android-sdk-windows\platform-tools b) Run the command: adb push %PathToCert%\MyCert. c) Expand mnt > sdcard and select the sdcard folder. a) Open the command line directory to the adb. b) In the Show View dialog. To install using Eclipse with the ADT plugin: Note: USB debugging must be enabled.p12 Generating Java Object API Code Generate object API code containing mobile business object (MBO) references. 2. See also • Installing the Android Development Environment on page 6 • Creating a Project on page 15 8 Sybase Unwired Platform . or by using a command line utility for generating code. d) Import the certificate to the Device Storage folder. Connect the Android device to your computer with the USB cable. navigate to and select the certificate. You can enable USB debug mode from the device menu by selecting Settings > Application > USB Debugging. Task Unwired Platform provides the Code Generation wizard for generating object API code.Development Task Flow for Object API Applications Generating Java Object API Code Using Sybase Unwired WorkSpace Use Sybase Unwired WorkSpace to generate object API code containing mobile business object (MBO) references. Developer Guide: Android Object API Applications 9 . Enter the information for these options. If the most recent configuration used is a named configuration. Diagram WorkSpace Navigator Right-click the Mobile Application project folder that contains the mobile objects for which you are generating API code. 1. You can select any of these. click Next. Launch the Code Generation wizard. (Optional. Code generation creates the business logic. and select Generate Code. this page of the code generation wizard is seen only if you are using the Advanced developer profile). You must have an active connection to the datasources to which the MBOs are bound. You can also select Copy from to copy an existing configuration which can then be modified. Click Next. you can: • Create new configuration – click Add and enter the Name and optional Description of the new configuration and click OK to save the configuration for future sessions. 2. the configuration is saved and displays as the chosen configuration the next time you invoke the code generation wizard. then click Next: Option Code generation configuration Description A table lists all existing named configurations plus the most recently used configuration. and proceed. Additionally. A mobile application project must contain at least one non-online MBO. it is saved as the first item in the configuration table. and operations for your mobile business object. even though it is still listed as the original named configuration. From Action Mobile Application Right-click within the Mobile Application Diagram and select Generate Code. • Most recent configuration – if you click Next the first time you generate code without creating a configuration. and also "Most recent configuration". Prerequisites Develop the MBOs that will be referenced in the device applications you are developing. attributes. 3. Enter the information for these configuration options: Option Language Platform Description Select Java. whose references. If an MBO's accumulated attribute size is larger than the page size setting. If you specified an Unwired Server to which you previously connected successfully. Unwired WorkSpace automatically computes the default page size after you choose the MBOs based on total attribute size. the first domain in the list is chosen by default. Choose the domain to which the generated code will connect. • Java • Android Specify a default Unwired Server connection profile to which the generated code connects at runtime. metadata.Development Task Flow for Object API Applications 4. a warning displays. Dependent MBOs are automatically added (or removed) from the Dependencies section depending on your selections. In Select Mobile Objects. Unwired Server Server domain 10 Sybase Unwired Platform . 5. select all the MBOs in the mobile application project or select MBOs under a specific synchronization group. You can enter a different domain manually. and dependencies (referenced MBOs) are included in the generated device code. Note: This field is only enabled when an Unwired Server is selected. Select the platform ( target device) for which the device client code is intended. and therefore cannot be put into a WHERE clause. and is also not included). object queries that use string or binary attributes with a WHERE clause may fail. If an MBO attribute's length sum is greater than the page size. The page size should be larger than the sum of all attribute lengths for any MBO that is included with all the MBOs selected. The package name must follow Java naming conventions for packages. and must be valid for the database. and is not included in the sum. Note: This field is only enabled when an Unwired Server is selected. the default page size is 4KB at runtime. Package. Developer Guide: Android Object API Applications 11 . If the page size is changed.Development Task Flow for Object API Applications Option Page size Description (Optional) Select the page size for the generated client code. . The default is a proposed page size based on the selected MBO's attributes. some attributes automatically convert to BLOB or CLOB. A binary length greater than 32767 is converted to a binary large object (BLOB). no leading or trailing spaces and no special characters such as §&/. a string greater than 8191 is converted to a character large object (CLOB). but does not meet these guidelines. For example. If the page size is not set. or Name Prefix • Package – enter a package name for Java. except that the first letter may be upper-case. Namespace. Context' cannot be found displays. and parameters during runtime using the name instead of the object instance.api. For example. The check box for "Generate metadata classes" is automatically selected as read only for Android. and select Generated Code as the destination. net_rim_api. enter a project path.device. 12 Sybase Unwired Platform . The "Including object manager classes" option is unavailable and unsupported. or android.system. Enter (or Browse) to either a Project path (Mobile Application project) location or File system path location. and the "Including object manager classes" checkbox is de-selected. Note: If you select Java as the language.content. Select Clean up destination before code generation to clean up the destination folder before generating the device client files. The Including object manager classes option is enabled only for BlackBerry and C# if you select Generate metadata classes. Third-party jar file Enter or browse to the location of the third party jar file. JAR files are automatically added to the destination for the platform that supports compiling of the generated client code.jar for Android. the warning The depend- ent third-party class 'net. 6. MBOs. 7.jar for BlackBerry. attributes. Select Including object manager classes to generate both the metadata for the attributes and operations of each generated client object and an object manager for the generated metadata. Note: When generating code for Android. and if the BlackBerry or Android third-party JAR file has not been added. The object manager allows you to retrieve the metadata of packages.rim.ApplicationDescriptor' cannot be found or The dependent third-party class 'android. specify a mobile application project folder. "Generate metadata classes" is automatically selected and cannot be unselected. operations. If you select Java as the language.Development Task Flow for Object API Applications Option Destination Description Specify the destination of the generated device client files. See Sybase Unwired WorkSpace . For the SUP101 example.Development Task Flow for Object API Applications 8.bat utility. 2. • Task 1. From <UnwiredPlatform_InstallDir>\MobileSDK22\ObjectAPI \Utils\bin. assuming codegen. Deploy the package to the Unwired Server.profile \My_Unwired_server\default_package.xml [output <output_dir>] [-doc] • • The -output parameter allows you to specify an output directory. Generating Java Object API Code Using the Code Generation Utility Use the Code Generation Utility to generate object API code containing mobile business object (MBO) references.jar in your mobile project folder. and the deploy jar file is in the following location: SUP101\Deployment\. 4. Prerequisites • Use Unwired WorkSpace to develop and package your mobile business objects. Use a utility to extract the deployment_unit.bat is run from the <UnwiredPlatform_InstallDir> \MobileSDK22\ObjectAPI\Utils\genfiles directory. See Sybase Unwired WorkSpace . Click Finish. the output goes into the <UnwiredPlatform_InstallDir> \MobileSDK22\ObjectAPI\Utils\genfiles directory. for example through the use of scripts.Mobile Business Object Development > Develop > Developing a Mobile Business Object. run the codegen. Ignore these warnings: Developer Guide: Android Object API Applications 13 . Make sure that the JAR file contains this file: • deployment_unit.xml file to another location. Validate the generated code. If you omit this parameter. creating files required for code generation from the command line.xml 3.Mobile Business Object Development > Develop > Packaging and Deploying Mobile Business Objects >Automated Deployment of Unwired WorkSpace Projects. specifying the following parameters: codegen. Examine the generated code location and contents. Locate <domain name>_package. 10. This method of generating code allows you to automate the process of code generation.pkg. 9. the project is deployed to the default domain.jar.bat -java -client -android -ulj deployment_unit. The -doc parameter specifies that documentation is generated for the generated code. synchronization. Other than the known name conversion rules (converting '. removing white space from names. attribute. their attributes. Expand Sybase. Define prefix names in the Mobile Business Object Preferences page of the Code Generation wizard to correct validation errors. 3. Generated Code Location and Contents If you generated code in Unwired WorkSpace.. in a persistent table at runtime. The contents include generated class files that contain: • • • • • MBO – class which handles persistence and operation replay of your MBOs. If you generated code with the Code Generation Utility. and other operations for the package. for example. there is no other language-specific name conversion.. and so on). You can specify the prefix string for mobile business object. For example. generated object API code is stored by default in the "Destination" location you specified during code generation. The contents of the folder is determined by the options you selected in the Generate Code wizard in Unwired WorkSpace. or operation names from the Mobile Business Object Preferences page. Validating Generated Code Validation rules are enforced when generating client code. 1. Select Mobile Business Object. operation. log4j:WARN Please initialize the log4j system properly. Personalization parameters – personalization parameters used by the package. attribute. This allows you to decide what prefix to use to correct any errors generated from the name validation. 4. login. and parameter) whenever these are autogenerated. or specified in the Code Generation Utility. Select Window > Preferences. 14 Sybase Unwired Platform . The defined prefixes are added to the names (object. and operations. Sybase Unwired WorkSpace validates and enforces identifier rules and checks for keyword conflicts in generated code. parameter. cust_id is not changed to custId. 2. Inc > Mobile Development. for example.' to '_'. by displaying error messages in the Properties view or in the wizard. Synchronization parameters – any synchronization parameters for the MBOs. Add or modify the Naming Prefix settings as needed. generateed object API code is stored in the SUP_HOME \MobileSDK22\ObjectAPI\Utils\genfiles folder after you you generate code. Metadata – Metadata class that allow you to query meta data including MBOs. when you drag and drop a data source onto the Mobile Application Diagram.Development Task Flow for Object API Applications log4j:WARN No appenders could be found for logger . DatabaseClass – package level class that handles subscription. In Sybase Unwired WorkSpace. 1. Developer Guide: Android Object API Applications 15 . but may not be the latest software available. Creating a Project in Unwired WorkSpace Create a project for your Android device application in Sybase Unwired WorkSpace. Downloading the Latest Afaria Libraries Afaria provides provisioning of configuration data and certificates for your Sybase Unwired Platform client application.Development Task Flow for Object API Applications Creating a Project Build a device application project. 1. 2. 2. Select Android > Android Project. Afaria libraries are packaged with Sybase Unwired Platform. To ensure you have the latest Afaria libraries. containing the library resources needed to compile your Android client code. download Afaria software. select File > New > Project. 3. within your Eclipse project. Importing Libraries and Code Create a specific directory structure. See also • Generating Java Object API Code on page 8 • Developing the Application Using the Object API on page 29 Creating a Project in Unwired WorkSpace Create a project for your Android device application in Sybase Unwired WorkSpace. In the New Android Project wizard.Development Task Flow for Object API Applications 3. enter these values and click Finish: • Project name: – enter the name of the project • Package name: – enter the name of the package • Min SDK Version: – 8 16 Sybase Unwired Platform . ACCESS_WIFI_STATE"></uses- Developer Guide: Android Object API Applications 17 .permission.INTERNET"></ uses-permission> <uses-permission android:name="android.Development Task Flow for Object API Applications 4.permission.READ_PHONE_STATE"></usespermission> <uses-permission android:name="android.permission.xml: <uses-permission android:name="android. Add the following user permissions in AndroidManifest. but may not be the latest software available. 18 Sybase Unwired Platform . 3. Importing Libraries and Code Create a specific directory structure. If not registered. To ensure you have the latest Afaria libraries. Navigate to the Mobile Enterprise Technical Support website at http:// frontline. Extract the contents of the downloaded zip file.Development Task Flow for Object API Applications permission> <uses-permission android:name="android.jar ClientLib.com/support/downloads. 6.jar libmlcrsa12. In your Unwired WorkSpace project. Include the Afaria library into your project.permission. containing the library resources needed to compile your Android client code. On the Libraries tab. 7. Copy the following library and JAR files from SUP_HOME \MobileSDK22\ObjectAPI\Android into the libs directory within your project. Select Software Updates and download the latest Static Link Libraries.permission. 2. create a libs directory.jar UltraLiteJNI12. 1. download Afaria software.ACCESS_NETWORK_STATE"></usespermission> <uses-permission android:name="android. 5.so libultralitej12. register for an account. retaining the same structure: Location • Files • • • • • • SUP_HOME\MobileSDK22\ObjectAPI\Android AfariaSSL.WRITE_EXTERNAL_STORAGE"></usespermission> Downloading the Latest Afaria Libraries Afaria provides provisioning of configuration data and certificates for your Sybase Unwired Platform client application.sybase. Copy the Afaria library files into the Android development environment. 4.jar sup-client.aspx. add the libraries to the project. within your Eclipse project. 1.so • SUP_HOME\MobileSDK22\ObjectAPI\Android\armeabi 3. Select Project > Properties > Java Build Path. 2. Log into your account. Afaria libraries are packaged with Sybase Unwired Platform. The Application and Connection APIs allow clients to register with and connect to the Unwired Server. and provides information and procedures for setting up the development environment. and developing DOE-based device applications. based on the group's synchronization policy. 1. connectivity and notifications use the Messaging channel. for individual MBOs. and the Target Change Notification APIs provide notifications to the client on operation success or failure. Installing the Android Development Environment Developer Guide: Android Object API Applications 19 . The Callback Handler and Listener APIs. This is how you create device applications with sophisticated UI interaction. and performance. or changes in data. This diagram illustrates how you can develop a device application directly from mobile business objects (MBOs). or as a group. business logic.Development Task Flow for DOE-based Object API Applications Development Task Flow for DOE-based Object API Applications Describes the overall development task flow for DOE-based native applications. The Object API provides the core application services described in the diagram. The Authentication APIs provide security by authenticating the client to the Unwired Server. using the Object API and custom device application coding. The Synchronization APIs allow you to synchronize mobile business objects (MBOs) based on synchronization parameters. With DOE-based applications. validation. Installing the Android SDK Install the Android SDK. and may be required by an organization's security policy. A certificate provides an additional level of secure access to an application. 2. See also • Generating Java Object API Code on page 22 Installing the Android SDK Install the Android SDK. 6. and prepare Android devices for authentication. perform functions needed for the application. Generating Java Object API Code Use the Code Generation Utility to generate object API code.Development Task Flow for DOE-based Object API Applications Install the Android development environment. and shutdown and uninstall the application. 2. 3. 20 Sybase Unwired Platform . and prepare Android devices for authentication. Creating a Project Build a device application project. 5. An application consists of building blocks which the developer uses to start the application. 4. Localizing Applications Localize an Android application by creating default and alternate resources. 7. Installing ADT in Unwired WorkSpace You can install the supported version of Android Development Tools (ADT) directly in the Unwired WorkSpace Eclipse environment. Testing Applications Test native applications on a device or simulator. Installing X. 1.509 Certificates on Android Devices and Emulators Install the . 3.p12 certificate on the Android device or emulator for authentication. Developing the Application Using the Object API Use the Object API to develop the application. Packaging Applications Package applications according to your security or application distribution requirements. Installing the Android Development Environment Install the Android development environment. which allows you to use APIs to develop device applications for Android devices. Installing ADT in Unwired WorkSpace You can install the supported version of Android Development Tools (ADT) directly in the Unwired WorkSpace Eclipse environment. Select the ADT Plugin for Eclipse zip file.com/android/ADT-16. such as Android Plugin. Installing X. 1. and create an Android virtual device to use as your emulator. Download the ADT Plugin for Eclipse at http://dl. Navigate to the appropriate version of Sybase Unwired Platform. 2.509 Certificates on Android Devices and Emulators Install the . See Google Android Versions for Object API at http://sybooks.com/sybooks/ sybooks. 3. 6. 3. 4. then select Help > Install New Software.0. click OK. A certificate provides an additional level of secure access to an application. then click OK. 2. Prerequisites • • Java SE Development Kit (JDK) must be installed. click Next. then click Finish. 4. Accept the license agreements. 8. Launch the Android Virtual Device Manager. 7.zip. click Archive. a list of downloadable tools. Start Eclipse. 5. Launch the Android SDK Manager and install the Android tools (SDK Tools and SDK Platform-tools) and the Android API.html. restart Unwired WorkSpace.1. and may be required by an organization's security policy. Click Add.android. In the Add Repository dialog. The Android SDK must be installed. then click Next. Developer Guide: Android Object API Applications 21 . select Development Tools.com/sdk/ requirements.xhtml.Development Task Flow for DOE-based Object API Applications 1. Note: If you get a security warning about the authenticity or validity of the software. in the top-right corner.p12 certificate on the Android device or emulator for authentication. Enter a Name for the local update site. Download and install the supported version of the Android SDK starter package. In the next window. 9. In the Available Software dialog. 10.sybase.google. When the installation completes. Confirm that your system meets the requirements at http://developer. To install using Windows Explorer: Note: USB debugging must be disabled. select the certificate and click Open. e) In the Put File on Device dialog. Connect the Android device to your computer with the USB cable. a) Open Windows Explorer b) Under your computer. Prerequisites • • • Generate and download the ESDMA bundle for you application. a) Open the command line directory to the adb. 2. or C:\Program Files \android-sdk-windows\platform-tools b) Run the command: adb push %PathToCert%\MyCert. for example. Run the ESDMA Converter utility to turn your ESDMA into an Unwired Platform package. navigate to Window > Show View > Other. To install using the Android Debug Bridge (adb): Note: USB debugging must be enabled. 3.p12 /sdcard/ MyCert. which allows you to use APIs to develop device applications for Android devices. Deploy the package to the Unwired Server. To install using Eclipse with the ADT plugin: Note: USB debugging must be enabled.Development Task Flow for DOE-based Object API Applications Task 1. d) Import the certificate to the Device Storage folder. From the menu bar. b) In the Show View dialog. c) Click Device Storage. 22 Sybase Unwired Platform . c) Expand mnt > sdcard and select the sdcard folder.p12 Generating Java Object API Code Use the Code Generation Utility to generate object API code. click Push a file onto the device. a) Open the Windows File Explorer view. 4. expand the Android folder and select File Explorer. You can enable USB debug mode from the device menu by selecting Settings > Application > USB Debugging. d) In the top right of the File Explorer view. navigate to and select the certificate. click the Android device to expand the folder.exe file. C:\Program Files\android-sdk-windows\tools. profile \My_Unwired_server\default_package.bat utility. The -doc parameter specifies that documentation is generated for the generated code. specifying the following parameters: codegen -android -client -doe -java -ulj [-output <output_dir>] [-doc] <ESDMA_dir>\META-INF\sup-db.jar. synchronization. Ignore these warnings: log4j:WARN No appenders could be found for logger .jar in your mobile project folder.Development Task Flow for DOE-based Object API Applications See Create. For the SUP101 example.bat is run from the <UnwiredPlatform_InstallDir>\UnwiredPlatform \MobileSDK22\ObjectAPI\Utils\bin directory. and the deploy jar file is in the following location: SUP101\Deployment\. From <UnwiredPlatform_InstallDir>\UnwiredPlatform \MobileSDK22\ObjectAPI\Utils\bin. log4j:WARN Please initialize the log4j system properly..bat in the command line. Generate. login.. See also • Installing the Android Development Environment on page 20 • Creating a Project on page 24 Generated Code Location and Contents The location of the generated Object API code is the location you specified when you generated the code using codegen. Convert the ESDMA Bundle into an Unwired Platform Package. Locate <domain name>_package.xml 3. Developer Guide: Android Object API Applications 23 . and include generated class files that contain: • DatabaseClass – package level class that handles subscription. Make sure that the JAR file contains this file: • deployment_unit. The contents of the folder is determined by the parameters you pass to codegen. the output goes into the <UnwiredPlatform_InstallDir> \UnwiredPlatform\MobileSDK22\ObjectAPI\Utils\genfiles directory. assuming codegen. If you omit this parameter. 2. and Download the ESDMA Bundle. the project is deployed to the default domain.pkg. and other operations for the package.xml • • The -output parameter allows you to specify an output directory.bat at the command line. and Deploy the Unwired Platform Package in Mobile Data Models: Using Data Orchestration Engine. Task 1. run the codegen. Development Task Flow for DOE-based Object API Applications • • • MBO – class which handles persistence and operation replay of your MBOs. Personalization parameters – personalization parameters used by the package. Metadata – Metadata class that allows you to query meta data including MBOs, their attributes, and operations, in a persistent table at runtime. Creating a Project Build a device application project. 1. Creating a Project in Unwired WorkSpace Create a project for your Android device application in Sybase Unwired WorkSpace. 2. Downloading the Latest Afaria Libraries Afaria provides provisioning of configuration data and certificates for your Sybase Unwired Platform client application. Afaria libraries are packaged with Sybase Unwired Platform, but may not be the latest software available. To ensure you have the latest Afaria libraries, download Afaria software. 3. Importing Libraries and Code Create a specific directory structure, within your Eclipse project, containing the library resources needed to compile your Android client code. See also • Generating Java Object API Code on page 22 • Developing the Application Using the Object API on page 29 Creating a Project in Unwired WorkSpace Create a project for your Android device application in Sybase Unwired WorkSpace. 1. In Sybase Unwired WorkSpace, select File > New > Project. 2. Select Android > Android Project. 24 Sybase Unwired Platform Development Task Flow for DOE-based Object API Applications 3. In the New Android Project wizard, enter these values and click Finish: • Project name: – enter the name of the project • Package name: – enter the name of the package • Min SDK Version: – 8 Developer Guide: Android Object API Applications 25 Development Task Flow for DOE-based Object API Applications 4. Add the following user permissions in AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET"></ uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE"></usespermission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses- 26 Sybase Unwired Platform Copy the following library and JAR files from SUP_HOME \MobileSDK22\ObjectAPI\Android into the libs directory within your project. create a libs directory. 7.jar UltraLiteJNI12.sybase.com/support/downloads. 6. Navigate to the Mobile Enterprise Technical Support website at http:// frontline.jar libmlcrsa12. but may not be the latest software available.jar sup-client. Copy the Afaria library files into the Android development environment. within your Eclipse project.WRITE_EXTERNAL_STORAGE"></usespermission> Downloading the Latest Afaria Libraries Afaria provides provisioning of configuration data and certificates for your Sybase Unwired Platform client application.so • SUP_HOME\MobileSDK22\ObjectAPI\Android\armeabi 3. If not registered. On the Libraries tab. Extract the contents of the downloaded zip file. In your Sybase Unwired WorkSpace project.ACCESS_NETWORK_STATE"></usespermission> <uses-permission android:name="android. 2.so libultralitej12.permission. Importing Libraries and Code Create a specific directory structure.Development Task Flow for DOE-based Object API Applications permission> <uses-permission android:name="android.aspx. 4. add the libraries to the project. Include the Afaria library into your project.jar ClientLib. 5. Afaria libraries are packaged with Sybase Unwired Platform. To ensure you have the latest Afaria libraries. Developer Guide: Android Object API Applications 27 . Log into your account. containing the library resources needed to compile your Android client code. Select Project > Properties > Java Build Path. download Afaria software. 1. 2. 3. register for an account. Select Software Updates and download the latest Static Link Libraries.permission. 1. retaining the same structure: Location • Files • • • • • • SUP_HOME\MobileSDK22\ObjectAPI\Android AfariaSSL. Development Task Flow for DOE-based Object API Applications 4. so the recursive option is required. and modify the Header Search Path from Building Settings. 28 Sybase Unwired Platform . The header files in the client library are grouped into subdirectories public and internal. Click on the active target. Specify the path to the location where you copied the include files. and select the Recursive checkbox. including location and page size.Developing the Application Using the Object API Developing the Application Using the Object API Use the Object API to develop the application. A device local database is automatically created Developer Guide: Android Object API Applications 29 . 1. Subsequently Starting an Application Subsequent start-ups are different from the first start-up. See also • Creating a Project on page 15 • Testing Applications on page 53 • Creating a Project on page 24 Initializing an Application Initialize the application when it starts the first time and subsequently. 3. Registering an Application Each device must register with the server before establishing a connection. 2. 4. and shutdown and uninstall the application. Creating and Deleting a Device's Local Database There are methods in the generated package database class that allow programmers to delete or create a device's local database. An application consists of building blocks which the developer uses to start the application. Setting Up Application Properties The Application instance contains the information and authentication credentials needed to register and connect to the Unwired Server. Initially Starting an Application Starting an application the first time. Setting Up Connectivity Store connection information to the Unwired Server data synchronization channel. The connection profile also contains UltraLite®J runtime tuning values. • • Initially Starting an Application Starting an application the first time. perform functions needed for the application. Setting Up the Connection Profile The Connection Profile stores information detailing where and how the local database is stored. 5. // Set the android. turn off the API logger to improve performance.Developing the Application Using the Object API when needed by the Object API.setApplicationIdentifier("SUP101").content. See also • Application APIs on page 61 • Connection APIs on page 95 Setting Up Application Properties The Application instance contains the information and authentication credentials needed to register and connect to the Unwired Server. The device's local database should be deleted when uninstalling the application. Turn Off API Logger In production environments. The application can also create the database programatically by calling the createDatabase method. connections with back-end systems. The following code illustrates how to set up the minimum required fields: // Initialize Application settings Application app = Application. Logging In Use online authentication with the server. Specifying Personalization Parameters Use personalization parameters to provide default values used with synchronization. Modifying Synchronization Parameters If you want to replace the old values in the synchronization parameters with new values. Connecting to the Device Database Establish a connection to the database on the device. 9. MBO attributes.getInstance(). 6. 10. Synchronizing Applications Synchronize package data between the device and the server. 12. clear the previous synchronization parameter values before retrieving data from an MBO during a synchronization session. it can register database and MBO callback listeners. 7. Setting Up Callbacks When your application starts. 8. The PersonalizationParameters class is within the generated code for your project. as well as synchronization listeners.Context for the application 30 Sybase Unwired Platform . // The identifier has to match the application ID deployed to the SUP server app. Specifying Synchronization Parameters Use synchronization parameters within the mobile application to download filtered MBO data. 11. 13. or EIS arguments. Context // ConnectionProperties has the infomation needed to register // and connect to SUP server ConnectionProperties connProps = app.setPortNumber(5001). The following code shows how to register the application and device. You do not need to use the registerApplication method for subsequent application start-ups. // context is the android. // The identifier has to match the // application ID deployed to the SUP server app.getInstance().mycompany. use the Application.Application class. // Other connection properties need to be set when connecting through the Relay Server. // required Developer Guide: Android Object API Applications 31 .setApplicationCallback(appCallback).setApplicationContext(context). // provide user credentials LoginCredentials loginCred = new LoginCredentials("supAdmin". Call the generated database's setApplication method before starting the connection or registering the device.content. // Initialize Application settings Application app = Application.setApplication(app). // if you are using Relay Server. use the registerApplication method in the com. by default 5001.Developing the Application Using the Object API app.getConnectionProperties(). connProps. // Initialize generated package database class with this Application instance SUP101DB.setApplicationIdentifier("SUP101").setApplicationContext(myAndroidContext). connProps. then use the correct port number for the Relay Server // otherwise use the messaging administration port. See also • Application APIs on page 61 Registering an Application Each device must register with the server before establishing a connection.setServerName("supserver. ApplicationCallback appCallback = new MyApplicationCallback().To start the connection to complete the registration process.mobile. connProps. // optional app.sybase.setLoginCredentials(loginCred). "supPwd"). // MyApplicationCallback implements ApplicationCallback app.com"). Note: setApplicationIdentifier and setApplicationContext must be called in the user interface thread.startConnection method. To register the device with the server during the initial application startup. the better. // use 100K for cache size connProfile. SUP101DB. For example. // Initialize the device database connection profile (if needed) ConnectionProfile connProfile = SUP101DB.persistence.Developing the Application Using the Object API // use the android.content.ConnectionProfile class to set up the locally generated database.setCacheSize(102400). you can set the database to be stored in an SD card or set the encryption key of the database. android.setApplication(app).getRegistrationStatus() != RegistrationStatus. The connection profile also contains UltraLite®J runtime tuning values.setProperty("databaseFile".REGISTERED) { // If the application has not been registered to the server. 32 Sybase Unwired Platform . The generated database class automatically contains all the default settings for the connection profile.startConnection(<timeout_value>). // Store the database in an SD card connProfile. // register now app.Environment.setEncryptionKey("your encryption key"). and check if the database exists by calling the databaseExists method in the generated package database class. } etc See also • Application APIs on page 61 Setting Up the Connection Profile The Connection Profile stores information detailing where and how the local database is stored.. } else { // start the connection to server app. login credentials.getPath() + "/ SUP1011_0.ulj"). . Use the com.getExternalStorageDirectory(). Set up the connection profile before the first database access. //Encryption key can be of arbitary length. if (app.registerApplication(<timeout_value>).os.Context for the application // set connection properties. Any settings you establish after the connection has already been established will not go into effect. including location and page size.getConnectionProfile(). Retrieve the connection profile object using the Sybase Unwired Platform database's getConnectionProfile method.sybase. You may add other settings if necessary. // encrypt the database connProfile. but generally the longer.. When the client registers and starts the application. The values of the settings are inherited from the application connection template used for the registration of the application connection (automatic or manual). port. See also • Synchronization Profile on page 97 Developer Guide: Android Object API Applications 33 .getSynchronizationProfile(). Retrieve the synchronization profile object using the Sybase Unwired Platform database's getSynchronizationionProfile method. cp. using relay server. domain name.getStreamParams(). Typically. the application uses the settings as sent from the Unwired Server to connect to the Unwired Server for synchronization so that the administrator can set those at the application deployment time based on their deployment topology (for example. 1. See also • Creating and Deleting a Device's Local Database on page 34 Setting Up the Synchronization Profile You can set Unwired Server synchronization channel information by calling the synchronization profile's setter method. cp. cp. such as a Relay Server Web server). using e2ee security. By default. See the Applications and Application Connection Templates topics in System Administration. the certificate is downloaded to the client. You must make use of the connection and security settings that are automatically used by the Object API. ConnectionProfile cp = SUP101DB.setPortNumber(2481). Set the connection fields in the ConnectionProfile object.crt").setNetworkProtocol("https").setTrusted_Certificates(appname +"_trustedCertificates. this information includes the server host. certificate and public key that are pushed by the message channel during the registration process.setServerName("SUP_Host"). 2.Developing the Application Using the Object API You can also automatically generate a encryption key and store it inside a data vault. See also • ConnectionProfile on page 95 Setting Up Connectivity Store connection information to the Unwired Server data synchronization channel. or a certificate used for the intermediary. Settings are automatically provisioned from the Unwired Server. so that the client can be assigned the trusted certificate. cp. Set up a secured connection using the ConnectionProfile object. Connect to the generated database by calling the generated database instance's openConnection method.Developing the Application Using the Object API Creating and Deleting a Device's Local Database There are methods in the generated package database class that allow programmers to delete or create a device's local database.onlineLogin(). Optionally.openConnection(). syncProfile. See also • Setting Up Connectivity on page 33 Logging In Use online authentication with the server. 2.getSynchronizationProfile(). A device local database is automatically created when needed by the Object API. If the database does not already exist.createDatabase().databaseExists()) { SUP101DB. SUP101DB. Normally. The application can also create the database programatically by calling the createDatabase method. If an instance of the generated database does not exist. the user is authenticated through the registerApplication and startConnection methods in the Application class. However. if (!SUP101DB.setPassword("password").setUserName("user"). 34 Sybase Unwired Platform . The device's local database should be deleted when uninstalling the application. When the local database is no longer needed. SUP101DB. SUP101DB. the openConnection method creates it. 1. ConnectionProfile syncProfile = SUP101DB. Once this is done there is no need to authenticate again. delete it by calling the generated database instance's deleteDatabase method. you can include code in your application to check if an instance of the generated database exists by calling the generated database instance's databaseExists method. the user can authenticate directly with the server at any time during the application's execution by calling the generated database instance's onlineLogin method. Use the SynchronizationProfile to store the username and password. syncProfile.deleteDatabase(). call the generated database instance's createDatabase method. } 3. Developing the Application Using the Object API Turn Off API Logger In production environments, turn off the API logger to improve performance. SUP101DB.getLogger().setLogLevel(LogLevel.OFF); Setting Up Callbacks When your application starts, it can register database and MBO callback listeners, as well as synchronization listeners. Callback handler and listener interfaces are provided so your application can monitor changes and notifications from Sybase Unwired Platform: • The com.sybase.mobile.ApplicationCallback class is used for monitoring changes to application settings, messaging connection status, and application registration status. The com.sybase.persistence.CallbackHandler interface is used to monitor notifications and changes related to the database. To register callback handlers at the package level, use the registerCallbackHandler method in the generated database class. To register for a particular MBO, use the registerCallbackHandler method in the generated MBO class. The com.sybase.persistence.SyncStatusListener class is used for debugging and performance measures when monitoring stages of a synchronization session, and can be used in the user interface to indicate synchronization progress. • • See also • Connecting to the Device Database on page 40 • Callback and Listener APIs on page 138 Setting Up Callback Handlers Use the callback handlers for event notifications. Use the com.sybase.persistence.CallbackHandler API for event notifications including login for synchronization and replay. If you do not register your own implementation of the com.sybase.persistence.CallbackHandler interface, the generated code will register a new default callback handler. 1. The generated database class contains a method called registerCallbackHandler. Use this method to install your implementation of CallbackHandler. For example: SUP101DB.registerCallbackHandler(new MyCallbackHandler()); 2. Each generated MBO class also has the same method to register your implementation of the CallbackHandler for that particular type. For example, if Customer is a generated MBO class, you can use the following code: Developer Guide: Android Object API Applications 35 Developing the Application Using the Object API Customer.registerCallbackHandler(new MyCustomerMBOCallbackHandler()); Create a Custom Callback Handler If an application requires a callback (for example, to allow the client framework to provide notification of synchronization results) create a custom callback handler. import com.sybase.persistence.DefaultCallbackHandler; …… public class Test { public static void main(String[] args) { SUP101DB.registerCallbackHandler(new MyCallbackHandler()); GenericList<SynchronizationGroup> sgs = new GenericList<SynchronizationGroup>(); sgs.add(SUP101DB.getSynchronizationGroup("sg1")); sgs.add(SUP101DB.getSynchronizationGroup("sg2")); SUP101DB.beginSynchronize(sgs, "my test synchronization context"); } } class MyCallbackHandler extends DefaultCallbackHandler { //The onSynchronize method overrides the //onSynchronize method from DefaultCallbackHandler. public int onSynchronize(GenericList<SynchronizationGroup> groups, SynchronizationContext context) { if ( context == null ) { return SynchronizationAction.CANCEL; } if (!("my test synchronization context".equals((String) (context.getUserContext())))) { return super.onSynchronize(groups, context); } switch (context.getStatus()) // The application is waiting for input from the user. // This section demonstrates that you can stop the synchronization or // let it proceed depending on the status of the application. { case SynchronizationStatus.STARTING: if (waitForMoreChanges()) { return SynchronizationAction.CANCEL; } else { return SynchronizationAction.CONTINUE; 36 Sybase Unwired Platform Developing the Application Using the Object API } default: return SynchronizationAction.CONTINUE; } } } Asynchronous Operation Replay Upload operation replay records asynchronously. When an application calls submitPending on an MBO on which a create, update, or delete operation is performed, an operation replay record is created on the device local database. When synchronize is called, the operation replay records are uploaded to the server. The method returns without waiting for the backend to replay those records. The synchronize method downloads all the latest data changes and the results of the previously uploaded operation replay records that the backend has finished replaying in the background. If you choose to disable asynchronous operation replay, each synchronize call will wait for the backend to finish replaying all the current uploaded operation replay records. This feature is enabled by default. You can enable or disable the feature by setting the asyncReplay property in the synchronization profile. The following code shows how to disable asynchronous replay: SUP101DB.getSynchronizationProfile().setAsyncReplay(false); When the application is connected (by Application.startConnection() or Application.registerApplica tion), it may receive background notifications and trigger a synchronize or other database operation. If you try to delete the database, you may receive database exceptions. Before deleting the database, stop the application connection (Application.stopConnection()). You can specify an upload-only synchronization where the client sends its changes to the server, but does not download other changes from the server. This type of synchronization conserves device resources when receiving changes from the server. public static void beginSynchronize(com.sybase.collections.GenericList<com.sybase.pers istence.SynchronizationGroup> sgs,Object context, boolean uploadOnly) When asynchronous replay is enabled and the replay is finished, the onSynchronize callback method is invoked with a SynchronizationStatus value of SynchronizationStatus.ASYNC_REPLAY_COMPLETED. Use this callback method to invoke a synchronize call to pull in the results, as shown in the following callback handler. public class MyCallbackHandler extends DefaultCallbackHandler { public int onSynchronize(GenericList<SynchronizationGroup> groups, Developer Guide: Android Object API Applications 37 ObjectSyncStatusData. } Synchronize Status Listener Retrieve the synchronization status. start = now.ASYNC_REPLAY_COMPLETED: // operation replay finished.getSyncStatusState().sybase. It could also be used in UI for synchronization progress status. break.persistence.sybase.persistence. String infoMessage.start. } } return SynchronizationAction. case SynchronizationStatus.getStatus()) { case SynchronizationStatus. Below is a sample Synchronize Status Listener. long interval = now . import com. switch (syncState) { case SyncStatusState.currentTimeMillis().CONTINUE // will start a background synchronization to pull in the results. 38 Sybase Unwired Platform . public class MySyncStatusListener implements SyncStatusListener { long start. return SynchronizationAction.Developing the Application Using the Object API SynchronizationContext context) { switch(context. import com.SyncStatusListener. LogMessage("AsyncReplay Done"). break. default: break.CONTINUE.persistence.currentTimeMillis(). public MySyncStatusListener() { start = System.sybase.SYNC_STARTING: infoMessage = "START [" + interval + "]". import com.ASYNC_REPLAY_UPLOADED: LogMessage("AsyncReplay uploaded").SyncStatusState. int syncState = statusData. Synchronize Status Listener is mainly for debugging and performance measuring purposes to monitor stages of a synchronize session. } public boolean objectSyncStatus(ObjectSyncStatusData statusData) { long now = System. APPLICATION_SYNC_SENDING_SCHEMA: infoMessage = "SENDING SCHEMA [" + interval + "]".getSentRowCount() + " R<" + statusData. default: infoMessage = "STATE" + syncState + "[" + interval + "]".getSentRowCount() + " R<" + statusData. break. Developer Guide: Android Object API Applications 39 . case SyncStatusState.getSentRowCount() + " R<" + statusData.APPLICATION_SYNC_COMMITTING_DOWNLOAD: infoMessage = "COMMITTING DOWNLOAD [" + interval + "] " + statusData. break.getSentByteCount() + ":" + statusData. break. case SyncStatusState.getSentByteCount() + ":" + statusData.getSentByteCount() + ":" + statusData.getReceivedRowCount() + ")".APPLICATION_SYNC_DISCONNECTING: infoMessage = "DISCONNECTING [" + interval + "]".getCurrentMBO() + ": (S>" + statusData.APPLICATION_SYNC_CANCELLED: infoMessage = "SYNC CANCELED [" + interval + "]".SYNC_DONE: infoMessage = "DONE [" + interval + "]". case SyncStatusState.APPLICATION_DATA_UPLOADING: infoMessage = "DATA UPLOADING [" + interval + "] " + statusData.getReceivedByteCount() + ":" + statusData.getReceivedRowCount() + ")".getSentByteCount() + ":" + statusData.APPLICATION_DATA_DOWNLOADING_DONE: infoMessage = "DATA DOWNLOADING DONE [" + interval + "]". case SyncStatusState.getCurrentMBO() + ": (S>" + statusData. case SyncStatusState. case SyncStatusState.getReceivedByteCount() + ":" + statusData.getReceivedByteCount() + ":" + statusData.Developing the Application Using the Object API break.getCurrentMBO() + ": (S>" + statusData. break. case SyncStatusState.APPLICATION_DATA_UPLOADING_DONE: infoMessage = "UPLOAD DONE [" + interval + "] " + statusData.getReceivedRowCount() + ")".APPLICATION_SYNC_RECEIVING_UPLOAD_ACK: infoMessage = "RECEIVING UPLOAD ACK [" + interval + "]". break. break. case SyncStatusState. break. case SyncStatusState. break. case SyncStatusState.getReceivedByteCount() + ":" + statusData.getReceivedRowCount() + ")".getCurrentMBO() + ": (S>" + statusData. break.getSentRowCount() + " R<" + statusData.APPLICATION_SYNC_SENDING_HEADER: infoMessage = "SENDING HEADERS [" + interval + "]".APPLICATION_DATA_DOWNLOADING: infoMessage = "DATA DOWNLOADING[" + interval + "] " + statusData. break. break. case SyncStatusState. For information on synchronizing DOE-based applications. } LogMessage(infoMessage). 1. 4. See also • Setting Up Callbacks on page 35 Synchronizing Applications Synchronize package data between the device and the server.synchronize(new MySyncStatusListener()) Connecting to the Device Database Establish a connection to the database on the device. 3. expand the Servers node and click the server name. specify the security 40 Sybase Unwired Platform . SUP101DB. In the optional properties section. In the left navigation pane of Sybase Control Center for Unwired Platform. the openConnection method creates one. } } The application can pass an instance of an implementation of SyncStatusListener to the synchronize API of the generated package database class to monitor the synchronization status. The generated database provides you with synchronization methods that apply to either all synchronization groups in the package or a specified list of groups. See also • Specifying Personalization Parameters on page 42 • Synchronization APIs on page 104 • Specifying Synchronization Parameters on page 43 Configuring Data Synchronization Using SSL Encryption Enable SSL encryption by configuring the synchronization HTTPS port.Developing the Application Using the Object API break. After completing the device registration. Click Server Configuration. see Message-Based Synchronization APIs. click the Replication tab. return false. 2. and configure the certificate properties. call the generated database's openConnection method to connect to the UltraLite/UltraLiteJ database on the device. In the right administration pane. If no device database exists. Select Secure synchronization port 2481 as the protocol used for synchronization. specify the groups to be synchronized. cust. Subscribe to the package using synchronization APIs in the generated database class. GenericList<SynchronizationGroup> sgs = new GenericList<SynchronizationGroup>(). Customer cust = Customer. and save it to the local database.Developing the Application Using the Object API certificate file. Developer Guide: Android Object API Applications 41 . such as findAll. The changes are ready for upload. List all customer MBO instances from the local database using an object query.setYourParameters(.findByPrimaryKey(100).save(). "mycontext"). updating mobile business object (MBO) data.").add(SUP101DB. Set the synchronization parameters if there are any.size().submitPending(). CustomerSynchronizationParameters syncParameter = Customer. which is a predefined object query. SUP101DB.setPhone("9252360000"). but have not yet been uploaded to the Unwired Server.update(). Nonblocking Synchronization An example that illustrates the basic code requirements for connecting to Unwired Server. Make a blocking synchronize call to Unwired Server to pull in all MBO data: SUP101DB. and synchronizing the device application from a device application based on the Client Object API. The previous replay results and new changes are downloaded to the client device in the download phase of the synchronization session. 1. Find and update a particular MBO instance. the public security certificate file using the fully qualified path to the file. int n = customers. //Work on customer information } 5. If you have not yet synchronized with Unwired Server.getSynchronizationGroup("default")). cust.get(i). and invoke the asynchronous synchronization method (beginSynchronize). syncParameter. // Customer MBO is in "default" sync group SUP101DB.save().findAll(). Use non-blocking synchronize call to upload the pending changes to the Unwired Server. perform a synchronization.beginSynchronize(sgs.//or cust. sgs.. i < n. ++i ) { Customer customer = customers. cust. 6. 7.).setAddress("1 Sybase Dr. Submit the pending changes.synchronize("system") 2. for (int i = 0.getSynchronizationParameters(). 4.. cust. syncParameter. along with the password you entered during certificate creation. 3.synchronize(). GenericList<Customer> customers = Customer. save(). 4.getSynchronizationGroup("PushEnabled"). then call the SynchronizationGroup object's setEnableSIS method.setEnableSIS(true). 3.synchronize(). or EIS arguments.save(). sg. if (!sg. com.getPersonalizationParameters(). unless you call pp. Save the PersonalizationParameters value to the local database: pp. you must synchronize. Synchronize the PersonalizationParameters value to the Unwired Server: SUP101DB. 1.getEnableSIS()) { sg.SynchronizationGroup sg = SUP101DB.setInterval(2). By default. connections with back-end systems. 2. To enable change notifications. The PersonalizationParameters class is within the generated code for your project.sybase. MBO attributes.persistence. To instantiate a PersonalizationParameters object. SUP101DB. change notifications are disabled for synchronization groups. Note: If you define a default value for a personalization key that value will not take effect. Assign values to the PersonalizationParameters object: pp. call the generated database instance's getPersonalizationParameters method: PersonalizationParameters pp = SUP101DB.Developing the Application Using the Object API Enabling Change Notifications A synchronization group can enable or disable its change notifications.synchronize("PushEnabled").setPKCity( "New York" ). See also • Synchronizing Applications on page 40 • Personalization APIs on page 102 42 Sybase Unwired Platform . sg.save(). } Specifying Personalization Parameters Use personalization parameters to provide default values used with synchronization. save().synchronize().Developing the Application Using the Object API Specifying Synchronization Parameters Use synchronization parameters within the mobile application to download filtered MBO data. call another synchronize() to download the data. Call the save method for all SynchronizationParameters and for all MBOs when the application is first started. The next synchronize sends the updated synchronization parameters to the server. if the Customer MBO contains a parameter named cityname. then that value will not take effect unless you call sp. See also • Synchronizing Applications on page 40 • Synchronization APIs on page 104 Developer Guide: Android Object API Applications 43 . For DOE-based applications. Save your changes by calling the synchronization parameters object's save method: sp. you do not need to set them again in subsequent synchronizations. Assign the synchronization parameters of an MBO before a synchronization session. no data is downloaded to the device even if there are default values set for those SynchronizationParameters. if you have an MBO named Customer.getSynchronizationParameters(). call SUP101DB. Retrieve the synchronization parameters object from the MBO instance. For example. Note: If you do not save the SynchronizationParameters.beginSynchronize() to download the data.save(). SUP101DB. 1. For example. 3. Once you have set the synchronization parameters. The SynchronizationParameters class is within the generated code for your project. Note: If you defined a default value or bound a PersonalizationParameters in the SynchronizationParameters. 2. the synchronization parameters object is accessed as a public field and returned as a CustomerSynchronizationParameters object: CustomerSynchronizationParameters sp = Customer. Assign values to the synchronization parameter.setCityname("Kansas City"). Do this after application registration and the first synchronization. After you save the synchonization parameters. unless you want to change them. assign the value to the CustomerSynchronizationParameters object's Cityname field: sp. unregister the application. sp. Set up the connection profile properties if needed for database location and tuning parameters.//Must re-get synchronization parameter instance. 44 Sybase Unwired Platform . Get the application instance. sp. 3.getSynchronizationParameters(). // Calls non-blocking startConnection // This call will return immediately. then only perform the following steps: a.startConnection(). c. Set up the synchronization profile properties if needed for SSL or a relay server. sp. 5. 4.setCityname("New City"). Unregistering the application removes the user from the server. sp = Customer. Starting an application on subsequent occasions: 1. You can open the database connection in parallel with starting the application connection to the server. b.openConnection().delete(). Note: Once the application is registered. Open the database connection. Initialize the generated package database class with this application instance. clear the previous synchronization parameter values before retrieving data from an MBO during a synchronization session. Start the application connection to the server using the existing connection parameters and registration information. application. // Open the device database connection while establishing // the messaging channel connection in the background SUP101DB. Use the getRegistrationStatus API in the Application class to determine if the application has already been registered. 2. Subsequently Starting an Application Subsequent start-ups are different from the first start-up. if it has been registered. SUP101DB.synchronize().getSynchronizationParameters(). The applicationIdentifier must be the same as the one used for initial registration. changes to any of the application connection properties are not saved.save().Developing the Application Using the Object API Modifying Synchronization Parameters If you want to replace the old values in the synchronization parameters with new values. CustomerSynchronizationParameters sp = Customer. change the connection properties and then register again. To modify the connection properties. Set the applicationIdentifier. to use paging. invoke the static findAll method contained in that MBO. which returns a list of MBOs containing the specified city name: com. int take). int skip. if a Customer has the primary key "id" as int.. consider this method. or use dynamic queries that return results sets or object lists. which performs the equivalent of Select x.collections.. 1. the Customer MBO would contain the public static Customer findByPrimaryKey(int id) method. For example. an MBO named Customer contains a method such as public static com.GenericList<SUP101. To find all instances of an MBO.). invoke MBO.Customer> findByCity(String city. The skip parameter specifies the number of rows to skip.Developing the Application Using the Object API // Once the device database connection has been opened.findByPrimaryKey(.. check // whether the messaging channel is connected using the // ApplicationCallback interface or the Application.id = :id. 2.collections. If the return type is a list. for example. For example.* from Customer x where x.Customer> findAll().getConnectionStatus() API See also • Application APIs on page 61 Accessing MBO Data Use MBO object queries to retrieve lists of MBO instances. To find a particular instance of an MBO using the primary key.sybase. See also • Query APIs on page 147 • Object Queries on page 45 • Dynamic Queries on page 46 • MBOs with Complex Types on page 47 • Relationships on page 47 Object Queries Use the generated static methods in the MBO classes to retrieve MBO instances.GenericList<SUP101. Developer Guide: Android Object API Applications 45 . For example. additional methods are generated for you to further process the result.sybase. and the take parameter specifies the maximum number of rows to return. lname. query. ts. Query query = new Query(). query. aTest.println("Customer " + i + ": " + c.select("c. ++i) { Customer c = (Customer)customers. 2.join("Sales_order". AttributeTest aTest = new AttributeTest(). "s".add("fname".id"). int n = customers. Use the com. "c.setTestValue("NY"). query.c.setTestCriteria(ts). AttributeTest ts = new AttributeTest().println("order: " + 46 Sybase Unwired Platform . aTest. GenericList<Customer> customers = Customer.order_date.getFname()).findWithQuery(query).size().setTestValue("Smith").next()) { System.add("lname". Specify the where condition used in the dynamic query. "c"). "s.id"). 1.getLname() + ".out. ts.setTestType(AttributeTest. i < n.EQUAL). while(qrs.executeQuery(query).ASCENDING). SortOrderType.setAttribute("lname"). Use the findWithQuery method in the MBO to dynamically retrieve a list of MBOs acccording to the specified attributes.setAttribute("state"). } 3.from("Customer".persistence.sybase.setSortCriteria(sort). System.setTestCriteria(aTest).setOperator(AttributeTest. for (int i = 0. Use the generated database’s executeQuery method to query multiple MBOs through the use of joins.fname. sort.Query class to retrieve a list of MBOs. Query query = new Query().get(i).s. sort. ts. " + c. query. QueryResultSet qrs = SUP101DB. aTest.cust_id".ASCENDING).out.s.EQUAL). SortOrderType. query.Developing the Application Using the Object API See also • Accessing MBO Data on page 45 • Query APIs on page 147 Dynamic Queries Build queries based on user input. SortCriteria sort = new SortCriteria(). query. newCase. Instantiate the MBO object: SimpleCaseList newCase = new SimpleCaseList().Developing the Application Using the Object API qrs. Sybase Unwired Platform generates one class for each complex type. newCase.setUserName("Demo").getString(2) + // " " + qrs. You can develop complex types that support interactions with backend data sources such as SAP® and Web services. Navigate between MBOs using relationships. newCase. newCase.currentTimeMillis())).getInt(4) + // qrs.fname c. // 4 1 2 3 is is is is s. 1. Developer Guide: Android Object API Applications 47 .setCreate_Time(new java.setCase_Type("Incident"). one-to-many. When you define an MBO with complex types. Begin by creating the complex datatype: AuthenticationInfo authen = new AuthenticationInfo(). "Demo". "false". Suppose you have an MBO named SimpleCaseList and want to use a complex data type called AuthenticationInfo to its Create method's parameter. 3. "Other".submitPending(). Call the create method of the SimpleCaseList MBO with the complex type parameter as well as other parameters. " + qrs. and call submitPending() to submit the create operation to the operation replay record.lname s. authen. Subsequent synchronizations upload the operation replay record to the Unwired Server and get replayed.order_date } See also • Accessing MBO Data on page 45 • Query APIs on page 147 MBOs with Complex Types Mobile business objects are mapped to classes containing data and methods that support synchronization and data manipulation.getString(1) + // ".getDate(3)). newCase. See also • Accessing MBO Data on page 45 • Query APIs on page 147 Relationships The Object API supports one-to-one. "worklog").setCategory("Networking").sql. Using a complex type to create an MBO instance. "Other".Timestamp(System.id c.create(authen. and many-to-one relationships. 2. findById(101). query.where(at).getSalesOrders().setCustomer(cust).equal("theAttribute".setOrder_date(new Date(System.getSalesOrdersFilterBy(query). Suppose you have one MBO named Customer and another MBO named SalesOrder. order. If the primary key for a parent is assigned by the EIS. Sales_order order = new Sales_order(). it would not make any difference. 2. // or order. it is recommened to submit the parent MBO once. orders = cust. You can create a new instance of a generated MBO class.setSales_rep(101). order. you can use a multilevel insert cascade operation to create the parent and child objects in a single operation without synchronizing multiple times. cust. 48 Sybase Unwired Platform . For composite relationship.currentTimeMillis())). See also • Accessing MBO Data on page 45 • Query APIs on page 147 Manipulating Data Create. order.save(). instead of submitting every child). update. order. order.setId(1001). To filter the returned child MBO's list data. The following example illustrates how to submit the parent MBO which also submits the child's operation: Customer cust = Customer. order. Submitting the child MBO also submits the parent and the entire object tree. 3. The returned primary key for the parent's create operation populates the children prior to their own creation. and delete instances of generated MBO classes. To be efficient and get one transaction for all child operations. "theTestValue").Developing the Application Using the Object API 1. This code illustrates how to navigate from the Customer object to its child SalesOrder objects: Customer cust = Customer.setFin_code_id("r1").save(). AttributeTest at = AttributeTest.submitPending(). and call the create method for that MBO instance. cust. you can call the parent's SubmitPending method to submit the entire object tree of the parent and its children.create().findById(101). order. GenericList<Sales_order> orders = cust. use the Query class: Query query = new Query(). fill in the attributes.setRegion("Eastern"). (If you have only one child instance. // find by primary key customer. Updating. See MBOs with Complex Types. update its attributes. which causes the object to enter a pending state. Then call the MBO instance's submitPending method.synchronize. update. retrieve the object instance through a query and invoke its delete method. omit SUP101DB. You can load an MBO from the database and call the delete method for that instance. retrieve the object instance through a query. and delete methods for MBO instances. synchronize with the generated database: Customer customer = Customer. //Set the required fields for the customer // … newcustomer. Note: For MBOs with custom create or update operations with parameters. synchronize with the generated database: Customer customer = Customer.synchronize(). newcustomer. update.synchronize.create(). Finally. To delete an existing MBO instance. and delete operations on the MBO instances that you have created.findByPrimaryKey(myCustomerId).submitPending(). above. Suppose you have an MBO named Customer. Finally. To update an existing MBO instance. which causes the object to enter a pending state.submitPending(). 3. For DOE-based applications. and Deleting MBO Records Perform create. above. You can call the create. invoke its create method. SUP101DB.findByPrimaryKey(myCustomerId). Then call the MBO instance's submitPending method. rather than the default create and update operations. 1. SUP101DB. See also • Persistence APIs on page 158 Creating. customer.update().setCity("Dublin"). Then call the MBO instance's submitPending method. and invoke its update method. To create an instance within the database. For DOE-based applications. Finally. // find by primary key Developer Guide: Android Object API Applications 49 . synchronize with the generated database: Customer newcustomer = new Customer(). omit SUP101DB.synchronize(). 2. you should use the custom operations.Developing the Application Using the Object API You can modify an object loaded from the database by calling the update method for that MBO instance. //update any field to a new value customer. which causes the object to enter a pending state. omit SUP101DB. //Convension is <MBO Name>+<Operation Name>+"Operation" op.submitPending(). 1. all pending MBOs of a single type. Suppose you have an MBO that has an operator that generates a customized sum. 2. specifying the "Add" operation: SUP101AddOperation op = new SUP101AddOperation(). SUP101DB. SUP101DB.synchronize(). See also • Operations APIs on page 158 Other Operations Use operations other than create. update. op. a customized operator is used to perform a sum operation. op. the MBOs enter a replay pending state. For DOE-based applications. Call the MBO instance's submitPending method and synchronize with the generated database: op. The next synchronization will submit those changes to the EIS.Developing the Application Using the Object API customer. See also • Operations APIs on page 158 Using SubmitPending and SubmitPendingOperations You can submit a single pending MBO.submitPending(). Sybase recommends using the submitPending API with the MBO instance whenever possible.synchronize. and check if there are pending oprations for all entities in the package.setOperand1(12). above.setOperand2(23).synchronize(). Database Classes Submit pending operations for all entities in the package or synchronization group. 50 Sybase Unwired Platform . Begin by creating an object instance and assigning values to its attributes. cancel all pending operations that have not been submitted to the server.setOperator("Add"). Note that submitPendingOperations APIs are expensive. With DOE-based applications. above. op. customer. or delete. omit SUP101DB.Synchronize(). Once those pending changes are submitted. In this example.save(). or all pending MBOs in a package.delete(). 3. To submit pending operations for a single MBO instance. invoke the MBO class' static cancelPendingOperations method. // wait the timeout value for the connection to stop // if it is not stopped within the timeout value an exception will be thrown app. invoke the MBO object's cancelPending method. invoke the MBO object's submitPending method. To cancel all pending operations for a single MBO instance. To cancel all pending operations that have not been submitted to the server for the MBO type. Closing Connections Clean up connections from the generated database instance prior to application shutdown. 1.Developing the Application Using the Object API 1. and cancel all pending operations that have not been submitted to the server for the MBO type or a single entity. 4. Sybase recommends using the submitPending API with the MBO instance whenever possible. stop the messaging channel by invoking the application instance's stopConnection method. Sybase recommends using the submitPending API with the MBO instance whenever possible. invoke the generated database's submitPendingOperations (string synchronizationGroup) method. invoke the MBO class' static submitPendingOperations method. Generated MBOs Submit pending operations for all entities for a given MBO type or a single instance. To submit pending operations for all pending entities for a given MBO type.stopConnection(<timeout_value>). Note that submitPendingOperations APIs are expensive. To submit pending operations for all pending entities in the package. To release an opened application connection. Note that submitPendingOperations APIs are expensive. invoke the generated database's cancelPendingOperations method. 2. 3. Developer Guide: Android Object API Applications 51 . To cancel all pending operations that have not been submitted to the server. To submit pending operations for all pending entities in the specified synchronization group. invoke the generated database's submitPendingOperations method. 2. 1. Shutting Down the Application Shut down an application and clean up connections. 2. Unregister the application by invoking the Application instance's unregisterApplication method. This is recommended to be part of the application shutdown process. and unregister the application.and MBO-level data. 52 Sybase Unwired Platform . To delete the package database.Developing the Application Using the Object API 2. Uninstalling the Application Uninstall the application and clean up all package.unregisterApplication(<time out value>). 1. app. call the generated database's deleteDatabase method. Use the closeConnection method to close all database connections for this package and release all resources allocated for those connections. SUP101DB.deleteDatabase(). Deleting the Database and Unregistering the Application Delete the package database. starts the emulator automatically. In Sybase Control Center. Prerequisites You must have created an Android Virtual Device when you installed the Android SDK in your Android development environment. When the application has successfully registered. In the Eclipse Package Explorer. Client-Side Debugging Identify and resolve client-side issues while debugging the application. Test the functionality of the application. verify that the application connection was created in Applications > Application Connections. 2. and launches the application. The application will automatically register with the Unwired Server using the default application connection template. the application connection displays a value of zero in the Pending Items column. setting breakpoints at appropriate places in the application. 3. See also • Developing the Application Using the Object API on page 29 • Localizing Applications on page 57 Testing an Application Using a Emulator Run and test the application on an emulator and verify that the application automatically registers to the Unwired Server using the default application connection template. Problems on the device client side that may cause client application problems: Developer Guide: Android Object API Applications 53 . Task 1. Use debug tools as necessary. The ADT plugin for Eclipse installs your application. The Android Virtual Device (AVD) must use the same target as the test package. right-click the project and select Run As > Android Application.Testing Applications Testing Applications Test native applications on a device or simulator. onDeviceConditionChanged to be notified if device storage gets too low. This is the log format level.SecurityException:Authorization failed: Domain = default Package = end2end. message – the message content. • 500 – failure.code.'2010-05-11 14:45:59.use your device browser to check the connectivity of your device to the server. • Synchronization codes: • 200 – success.0 mboName = simpleCustomer action = delete'.'delete'.710' • • • • • • • level – the log level currently set.''.'simpleCustomer'. operation – operation name. If you are using queries. turn on debugging and review the debugging information. 2 = DEBUG.Testing Applications • • Unwired Server connection failed .Query) or Entity.getLogRecords() methods.sybase. 7 = OFF.operation.implement ApplicationCallback.rdb:1. See the API Reference information about using the Logger class to add logs to the client log record and synchronize them to the server (viewable in Sybase Control Center). 6 = FATAL.lang. If no mapping exists. eisCode – maps to HTTP error codes. 4 = WARN. check if your query conditions are correctly constructed and if the device data match your query conditions. used to identify and track MBO instances and data.entityKey.persistence. code – Unwired Server administration codes. Physical device problems.'100001'.getLogRecords (com.component. 5 = ERROR. 3 = INFO. component – MBO name.timestamp • This log format generates output similar to: level code eisCode message component entityKey operation requestId timestamp 5. Values include: 1 = TRACE.check if your synchronization and personalization parameters are set correctly.eisCode. Check the log record on the device. defaults to error code 500 (an unexpected server failure). Use the <PkgName>DB.'100014'. or recovers from an error. such as low memory .requestI d.message. 54 Sybase Unwired Platform . Data does not appear on the client device .500. • To find out more information on the device client side: • If you have implemented debugging in your generated or custom code (which Sybase recommends). entityKey – MBO surrogate key.'java. Back-end authentication failed. and connection error message are reported on the device: • 1 – current device connection status. device connection type. replication database back end.Testing Applications requestId – operation replay request ID or messaging-based synchronization message request ID. true). you can set the log level to DEBUG to obtain detailed information in the log files: 1. you can turn on SQLTrace trace on the device side to trace Client Object API activity. the connection status between the Unwired Server and the device is reported on the device. it is unavailable until enabled. Set the log level using Sybase Control Center. for example. An operation failed on the remote. or SAP® back end. a table or foreign key does not exist.getConnectionProfile(). • timestamp – message logged time. An operation failed on the Web Service. If you create a new domain. The operation role check failed for the synchronizing user. Problems on the Unwired Server side may cause device client problems: • • • • • • The domain or package does not exist. with a default status of disabled. See Sybase Control Center for Sybase Unwired Platform > Administer > Unwired Server > Server Log > Unwired Server Runtime Logging > Configuring Unwired Server Log Settings. Obtain DEBUG information for a specific device: • Developer Guide: Android Object API Applications 55 . To enable SQLTrace using the ConnectionProfile's enableTrace API: • // To enable SQL trace with values also displayed SUP101DB. For message-based synchronization mode. The device connection status. See the CallbackHandler API reference information. or operation execution time. since DEBUG mode can affect system performance. • 2 – current device connection type. REST. To find out more information on the Unwired Server side: • • Check the Unwired Server log files. For other issues.enableTrace(true. • 3 – connection error message. Note: Return to INFO mode as soon as possible. • • Server-Side Debugging Identify and resolve server-side issues while debugging the application.onConnectionStatusChanged for synchronization in the CallbackHandler. Authentication failed for the application user credentials. If you have implemented ApplicationCallback. . > Device Advanced. since DEBUG mode can affect system performance. Set the DEBUG level to a higher value for a specified device: a.. then select Properties. 3. select Application Connections. In SCC. Set the TRACE file size to be greater than 50KB. • Note: Return to INFO mode as soon as possible. 2. Check the <server_install_folder>\UnwiredPlatform\Servers \UnwiredServer\logs\ClientTrace directory to see the mobile device client log files for information about a specific device. 56 Sybase Unwired Platform . View the trace file through SCC.Testing Applications • In the SCC administration console: 1. b. Set the Debug Trace Level value. html See also • Testing Applications on page 53 Developer Guide: Android Object API Applications 57 .android.Localizing Applications Localizing Applications Localize an Android application by creating default and alternate resources. and tutorials on localizing Android applications. For information.com/guide/topics/resources/localization. see http:// developer. best practices. Localizing Applications 58 Sybase Unwired Platform . All applications must be signed. Once you build your application. For more information on publishing your Android application. This packaging method provide more security since packaging the entire application as one unit reduces the risk of tampering of individual libraries.com/guide/ publishing/publishing_overview. the build tools sign your application with a special debug key that is created by the Android SDK build tools. To test and debug your application. Developer Guide: Android Object API Applications 59 . Signing Code signing is required for applications to run on physical devices and emulators. The system will not install an application on an emulator or a device if it is not signed.html.android. see http://developer. You may package and install modules separately only if your application distribution strategy requires sharing libraries between Sybase Unwired Platform applications.Packaging Applications Packaging Applications Package applications according to your security or application distribution requirements. You can package all libraries into one package. deploy the Android package (APK) file. Packaging Applications 60 Sybase Unwired Platform . manages mobile application registrations. There is a subdirectory for android. located in the Unwired Platform installation directory SUP_HOME\MobileSDK22\ObjectAPI\apidoc.html file. The applicable documentation is available with each package.Client Object API Usage Client Object API Usage The Sybase Unwired Platform Client Object API consists of generated business object classes that represent mobile business objects (MBOs) that are designed and built in the Unwired WorkSpace development environment. From the index.mobile Java package. the top-left navigation pane lists all packages installed with Unwired Platform. in the com. Device applications use the Client Object API to retrieve data and invoke mobile business object operations. connections and context. Application APIs The Application class.sybase. Note: Sybase recommends that you use the Application API operations with no timeout parameter. and register an ApplicationCallback to handle completion of these operations. Client Object API Reference Use the Sybase Client Object API Javadocs as a Client Object API reference. Review the reference details in the Client Object API documentation. Click this link and navigate through the Javadoc. Refer to these sections for more information on using the APIs described in Developer Guide: Android Object API Applications > Developing the Application Using the Object API. Developer Guide: Android Object API Applications 61 . See also • Initially Starting an Application on page 29 • Setting Up Application Properties on page 30 • Registering an Application on page 31 • Subsequently Starting an Application on page 44 Application Methods or properties in the Application class. Note: The application identifier is case sensitive. Usage This method must be called in the user interface thread. Set the application identifer before calling startConnection or registerApplication.String value) Parameters • value – The identifier for the current application. Examples • Set the Application Identifier – Sets the application identifier to SUP101. // Initialize Application settings Application app = Application. setApplicationIdentifier Sets the identifier for the current application. Examples • Get the Application Instance Application app = Application.setApplicationIdentifier("SUP101"). // The identifier has to match the // application ID deployed to the SUP server app. Syntax public static Application getInstance() Returns getInstance returns a singleton Application object. Syntax public void setApplicationIdentifier(java.getInstance().Client Object API Usage getInstance Retrieves the Application instance for the current mobile application.getInstance().lang. 62 Sybase Unwired Platform . Examples • Get the Registration Status – Registers the application if it is not already registered. This method is equivalent to calling registerApplication(0). Syntax public void registerApplication() Parameters None.REGISTERED) { // If the application has not been registered to the server.registerApplication().Client Object API Usage getRegistrationStatus Retrieves the current status of the mobile application registration. REGISTRATION_ERROR = 201.getRegistrationStatus() != RegistrationStatus. REGISTERING = 202.startConnection(). Syntax public int getRegistrationStatus() Returns getRegistrationStatus returns one of the values defined in the RegistrationStatus class. // register now app. if (app. public class RegistrationStatus { public public public public public } static static static static static final final final final final int int int int int REGISTERED = 203. Developer Guide: Android Object API Applications 63 . } registerApplication Creates the registration for this application and starts the connection. } else { // start the connection to server app. UNREGISTERING = 204. UNREGISTERED = 205. getConnectionProperties(). if (app.CONNECTED. 0.getRegistrationStatus() != RegistrationStatus.setServerName("supserver. the application is now in a suitable state for database subscriptions and/or synchronization. 0.registerApplication(). the sequence of callbacks as a result of calling registerApplication is: onRegistrationStatusChanged(RegistrationStatus. If a callback handler is registered and network connectivity is unavailable.setApplication(app).REGISTERED. If a callback handler is registered and network connectivity is available. 0. LoginCredentials loginCred = new LoginCredentials("supAdmin". } registerApplication (int timeout) Creates the registration for this application and starts the connection.mycompany.setLoginCredentials(loginCred).REGISTERED) { app. SUP101DB. the sequence of callbacks as a result of calling registerApplication is: onRegistrationStatusChanged(RegistrationStatus. If a callback handler is registered and network connectivity is available for the 64 Sybase Unwired Platform .com").setApplicationCallback(new MyApplicationCallbackHandler()). "") onConnectionStatusChanged(ConnectionStatus. message) In such a case.registerApplication().setApplicationIdentifier("SUP101").CONNECTING. An ApplicationTimeoutException is thrown if the method does not succeed within the number of seconds specified by the timeout. the registration process has permanently failed and will not continue in the background. "") onConnectionStatusChanged(ConnectionStatus.REGISTERING. "") When the connectionStatus of CONNECTED has been reached and the application's applicationSettings have been received from the server.need to match as the server side Application ID app. "") onRegistrationStatusChanged(RegistrationStatus. // set Application ID . props. ConnectionProperties props = app. "") onRegistrationStatusChanged(RegistrationStatus.REGISTRATION_ERROR. Usage You must set up the ConnectionProperties and ApplicationIdentifier before you can invoke registerApplication. props. Application app = Application.REGISTERING. "supPwd"). code. 0. app.setPortNumber(5001). 0. props. app.getInstance().Client Object API Usage Examples • Register an Application – Start registering the application and return at once. app.REGISTERING. Syntax public void registerApplication(int timeout) Parameters • timeout – Number of seconds to wait until the registration is created. the registration process has temporarily failed and will continue in the background when network connectivity is restored.getConnectionProperties(). props.setServerName("supserver.registerApplication(60). an ApplicationTimeoutException is thrown (the operation might still be completing in a background thread). If the timeout value is less than or equal to 0. "") onConnectionStatusChanged(ConnectionStatus. If the timeout value is less than or equal to 0.getInstance(). then this method returns immediately without waiting for the registration to finish (a non-blocking call). 0. 0.CONNECTION_ERROR. app. // set Application ID .mycompany.setPortNumber(5001).REGISTERED) { Developer Guide: Android Object API Applications 65 . LoginCredentials loginCred = new LoginCredentials("supAdmin". "supPwd"). SUP101DB. then this method returns immediately without waiting for the registration to finish (a non-blocking call).setApplicationCallback(new MyApplicationCallbackHandler()).setApplication(app). if (app.need to match as the server side Application ID app. message) In such a case.setApplicationIdentifier("SUP101"). Examples • Register an Application – Registers the application with a one minute waiting period. props.com"). Usage You must set up the ConnectionProperties and ApplicationIdentifier before you can invoke registerApplication.CONNECTING. If the the timeout is greater than zero and the registration is not created within the timeout period. props. the sequence of callbacks as a result of calling registerApplication is: onRegistrationStatusChanged(RegistrationStatus.Client Object API Usage start of registration but becomes unavailable before the connection is established. "") onConnectionStatusChanged(ConnectionStatus. Application app = Application. code. ConnectionProperties props = app.setLoginCredentials(loginCred).getRegistrationStatus() != RegistrationStatus. but recommended.getInstance(). registration status. getApplicationCallback Get the current callback handler. 66 Sybase Unwired Platform .registerApplication(60). ApplicationCallback appCallback = new MyApplicationCallback(). Examples • Set the Application Callback // Initialize Application settings Application app = Application.Client Object API Usage app.getApplicationCallback(). and application settings. app. It is optional. Syntax public void setApplicationCallback(ApplicationCallback value) Parameters • value – The mobile application callback handler. } setApplicationCallback Sets the callback for the current application. Syntax public ApplicationCallback getApplicationCallback(). // The identifier has to match the // application ID deployed to the SUP server app. getApplicationContext Returns the Android application context which allows access to application-specific resources and classes. to register a callback so the application can respond to changes in connection status.setApplicationIdentifier("SUP101").setApplicationCallback(appCallback). Examples • Get the current ApplicationCallback handler ApplicationCallback currentCallback = application. This method is equivalent to calling startConnection(0).Context context) Returns None. which is required before calling thestartConnection.Client Object API Usage Syntax public android. registerApplication or unregisterApplication methods.Context getApplicationContext() Returns getApplicationContext returns a single Context object. not a background thread.Context context) startConnection Starts the connection for this application.content. Use getConnectionStatus or the ApplicationCallback to retrieve the connection status. This method must be called in an user interface thread.content. Examples • Get the Application Context getApplicationContext() setApplicationContext Sets the Android application context.content. Examples • Set the Application Context setApplicationContext(android. Developer Guide: Android Object API Applications 67 . but is a non-blocking call which returns immediately. Syntax public void startConnection() Returns None. Syntax public void setApplicationContext(android. Client Object API Usage Examples • Start the Application startConnection() startConnection (int timeout) Starts the connection for this application. If the connection was previously started, then this operation has no effect. You must set the appropriate connectionProperties before calling this operation. An ApplicationTimeoutException is thrown if the method does not succeed within the number of seconds specified by the timeout. If connection properties are improperly set, a ConnectionPropertyException is thrown. You can set the applicationCallback before calling this operation to receive asynchronous notification of connection status changes. If a callback handler is registered and network connectivity is available, the sequence of callbacks as a result of calling startConnection is: onConnectionStatusChanged(ConnectionStatus.CONNECTING, 0, "") onConnectionStatusChanged(ConnectionStatus.CONNECTED, 0, "") If a callback handler is registered and network connectivity is unavailable, the sequence of callbacks as a result of calling startConnection is: onConnectionStatusChanged(ConnectionStatus.CONNECTING, 0, null) onConnectionStatusChanged(ConnectionStatus.CONNECTION_ERROR, code, message) After a connection is successfully established, it can transition at any later time to CONNECTION_ERROR status or NOTIFICATION_WAIT status and subsequently back to CONNECTING and CONNECTED when connectivity resumes. Note: The application must have already been registered for the connection to be established. See registerApplication for details. Syntax public void startConnection(int timeout) Parameters • timeout – The number of seconds to wait until the connection is started. If the timeout is greater than zero and the connection is not started within the timeout period, an ApplicationTimeoutException is thrown (the operation may still be completing in a background thread). If the timeout value is less than or equal to 0, then this method returns immediately without waiting for the registration to finish (a non-blocking call). Returns None. 68 Sybase Unwired Platform Client Object API Usage Examples • Start the Application startConnection(timeout) getConnectionStatus Return current status of the mobile application connection. Syntax public int getConnectionStatus() Returns connectionStatus returns one of the ConnectionStatus class values. ConnectionStatus has the following possible values: • • • ConnectionStatus.CONNECTED – The connection has been successfully started. ConnectionStatus.CONNECTING – The connection is currently being started. ConnectionStatus.CONNECTION_ERROR – The connection could not be started, or was previously started and subsequently an error occurred. Use onConnectionStatusChanged to capture the associated errorCode and errorMessage. ConnectionStatus.DISCONNECTED – The connection been sucessfully stopped, or there was no previous connection. ConnectionStatus.DISCONNECTING – The connection is currently being stopped. ConnectionStatus.NOTIFICATION_WAIT – The connection has been suspended and is awaiting a notification from the server. This is a normal situation for those platforms which can keep connections closed when there is no activity, since the server can reawaken the connection as needed with a notification. • • • Examples • Get the Application Connection Status getConnectionStatus() getConnectionProperties Retrieves the connection parameters from the application's connection properties instance. You must set connection properties before calling startConnection, registerApplication or unregisterApplication. Syntax public ConnectionProperties getConnectionProperties() Developer Guide: Android Object API Applications 69 Client Object API Usage Parameters None. Returns Returns the connection properties instance. getApplicationSettings Return application settings that have been received from the Unwired Server after application registration and connection. Syntax public ApplicationSettings getApplicationSettings() Returns Application settings that have been received from the Unwired Server. Examples • Get the application settings ApplicationSettings applicationSettings = Application.getInstance().getApplicationSettings(); stopConnection Stops the connection for this application. This method is equivalent to calling stopConnection(0). Syntax public void stopConnection() Returns None. Examples • Stop the Connection for the Application stopConnection(); 70 Sybase Unwired Platform Syntax unregisterApplication() Developer Guide: Android Object API Applications 71 . If no connection was previously stopped. If no registration was previously created. then this operation has no effect. 0. "") onConnectionStatusChanged(ConnectionStatus. If a callback handler is registered. then this method returns immediately without waiting for the registration to finish (a non-blocking call).Client Object API Usage stopConnection (int timeout) Stop the connection for this application. You can set the applicationCallback before calling this operation to receive asynchronous notification of registration status changes. Examples • Stop the Application stopConnection(60) unregisterApplication Delete the registration for this application. "") Syntax public void stopConnection(int timeout) Parameters • timeout – The number of seconds to wait until the connection is stopped. but is a nonblocking call which returns immediately.DISCONNECTING. You can set the applicationCallback before calling this operation to receive asynchronous notification of connection status changes. and stop the connection. This method is equivalent to calling unregisterApplication(0).DISCONNECTED. If the timeout value is less than or equal to 0. the sequence of callbacks as a result of calling stopConnection is: • • onConnectionStatusChanged(ConnectionStatus. Make sure the synchronization process has ended before calling this method. An ApplicationTimeoutException is thrown if the method does not succeed within the number of seconds specified by the timeout. Returns None. 0. then this operation has no effect. or a previous registration was already deleted. If a callback handler is registered and network connectivity is available.DISCONNECTED.DISCONNECTING.UNREGISTERED. 72 Sybase Unwired Platform . then this method returns immediately without waiting for the registration to finish (a non-blocking call). and stop the connection. If the timeout value is less than or equal to 0. If no registration was previously created. 0. "") onRegistrationStatusChanged(RegistrationStatus.DISCONNECTING. "") onRegistrationStatusChanged(RegistrationStatus. message) Syntax unregisterApplication(int timeout) Parameters • timeout – Number of seconds to wait until the application is unregistered. then this operation has no effect. 0. the sequence of callbacks as a result of calling unregisterApplication should be: • • • • onConnectionStatusChanged(ConnectionStatus. "") onRegistrationStatusChanged(RegistrationStatus.unregisterApplication().Client Object API Usage Parameters None. app. or a previous registration was already deleted.UNREGISTERING.DISCONNECTED. Examples • Unregister an Application – Unregisters the application. 0. 0. You can set the applicationCallback before calling this operation to receive asynchronous notification of registration status changes. the sequence of callbacks as a result of calling unregisterApplication should be: • • • • onConnectionStatusChanged(ConnectionStatus. 0. "") onConnectionStatusChanged(ConnectionStatus.REGISTRATION_ERROR. "") onConnectionStatusChanged(ConnectionStatus.unregisterApplication(60). Examples • Unregister an Application – Unregisters the application with a one minute waiting period. code. 0. 0. unregisterApplication(int timeout) Delete the registration for this application. "") onRegistrationStatusChanged(RegistrationStatus. "") If a callback handler is registered and network connectivity is unavailable. app.UNREGISTERING. Syntax public String getActivationCode() Parameters None. Returns Returns the activation code. getNetworkProtocol Retrieves the network protocol for the server connection URL. you must set an activation code. Returns None. If you register an application manually. which is also known as the URL scheme. Syntax public void setActivationCode(String value) Parameters • value – The activation code.Client Object API Usage ConnectionProperties A class that supports the configuration of properties to enable application registrations and connections. setActivationCode Sets the activation code. Developer Guide: Android Object API Applications 73 . getActivationCode Retrieves the activation code. Syntax public String getNetworkProtocol() Parameters None. setNetworkProtocol Sets the network protocol for the server connection URL. Syntax public void setNetworkProtocol(String value) Parameters • value – The network protocol for the server connection URL. Returns Returns the login certificate. Syntax public void setLoginCertificate(LoginCertificate value) Parameters • value – The login certificate. 74 Sybase Unwired Platform . setLoginCertificate Sets the login certificate to enable authentication by a digital certificate. which is also known as the URL scheme. Defaults to HTTP.Client Object API Usage Returns Returns the network protocol for the server connection URL. Syntax public LoginCertificate getLoginCertificate() Parameters None. Returns None. which is also known as the URL scheme. getLoginCertificate Retrieves the login certificate. Returns None. Developer Guide: Android Object API Applications 75 .Client Object API Usage Returns None. Returns Returns the login credentials. setLoginCredentials Sets the login credentials to enable authentication by username and password. Syntax public void setLoginCredentials(LoginCredentials value) Parameters • value – The login credentials. getPortNumber Retrieves the port number for the server connection URL. getLoginCredentials Retrieves the login credentials. Syntax public LoginCredentials getLoginCredentials() Parameters None. Returns Returns the port number. Syntax public int getPortNumber() Parameters None. getServerName Retrieves the server name for the server connection URL. setServerName Sets the server name for the server connection URL. Returns Returns the server name. Syntax public String getServerName() Parameters None. Syntax public void setServerName(String value) Parameters • value – The server name for the server connection URL. Returns None. Syntax public void setPortNumber(int value) Parameters • value – The port number for the server connection URL.Client Object API Usage setPortNumber Sets the port number for the server connection URL. Returns None. 76 Sybase Unwired Platform . Client Object API Usage getSecurityConfiguration Retrieves the security configuration for the connection profile. Note: If an incorrect URL is configured. Syntax public void setSecurityConfiguration(String value) Parameters • value – The security configuration for the connection profile. Returns Returns the security configuration. Syntax public String getSecurityConfiguration() Parameters None. Returns None. then the client will attempt to discover the correct URL using default Relay Server URLs. If not specified. If a valid urlSuffix is discovered. the server selects the correct security configuration by matching an application connection template with the applicationIdentifier. getUrlSuffix Retrieves the URL suffix for the server connection URL. it must be cleared or corrected before the client is able to connect. the value will be saved and used exclusively. setSecurityConfiguration Sets the security configuration for the connection profile. Syntax public String getUrlSuffix() Developer Guide: Android Object API Applications 77 . If the URL Suffix is left blank. dll /ias_relay_server/client/rs_client.dll/XYX/tm getFarmId Retrieves the Farm ID for the server connection URL. Usage The suffix "/%cid%/tm" is appended if the URL does not already end in "/tm".dll/ /ias_relay_server/client/rs_client. Syntax public void setUrlSuffix(String value) Parameters • value – The URL suffix for the server connection URL. The farmId is substituted into the default URL templates for Relay Server on into a configured 78 Sybase Unwired Platform . You can optionally code a Content-ID (CID) into the URL. This optional property is used in the URL discovery process when connecting through a proxy server or Relay Server. Note: If you provide an incorrect URL suffix. Returns Returns the URL suffix. This optional property is only used when connecting through a proxy server or Relay Server.dll/%cid%/tm /ias_relay_server/client/rs_client. if the CID is "XYZ" then any of these URL suffixes: • • • • /ias_relay_server/client/rs_client. setUrlSuffix Sets the URL suffix for the server connection URL. then only "%cid%/tm" is appended. If the URL ends in "/". Returns None.Client Object API Usage Parameters None. the server uses the default URL suffix when registering. For example.dll/XYZ/tm result in the following URL suffix: • /ias_relay_server/client/rs_client. Returns None. This optional property is only used when connecting through a proxy server or Relay Server. Returns Returns the HTTP headers. Syntax public void setFarmId(String value) Parameters • value – The Farm ID for the server connection URL.Client Object API Usage urlSuffix. Developer Guide: Android Object API Applications 79 . setFarmId Sets the Farm ID for the server connection URL (the default is 0). The farmId is used only until a connection is successfully made and the permanent urlSuffix is stored. getHttpHeaders Retrieves any custom headers for HTTP network communications with a proxy server or Relay Server. Returns Returns the Farm ID. Syntax public StringProperties getHttpHeaders() Parameters None. Syntax public String getFarmId() Parameters None. Syntax public void setHttpCookies(StringProperties oCookies) Parameters • oCookies – Optional cookies for HTTP network communication with a proxy server or Relay Server. Syntax public void setHttpHeaders(StringProperties oHeaders) Parameters • oHeaders – Optional headers for HTTP network communication with a proxy server or Relay Server. Syntax public StringProperties getHttpCookies() Parameters None. getHttpCookies Retrieves any custom HTTP cookies for network communications with a proxy server or Relay Server. 80 Sybase Unwired Platform .Client Object API Usage setHttpHeaders Sets the HTTP headers for network communications through a proxy server or Relay Server. Returns None. Returns Returns the HTTP cookies. setHttpCookies Sets the HTTP cookies for network communications through a proxy server or Relay Server. Returns None. setHttpCredentials Sets the HTTP credentials for basic authentication through a proxy server or Relay Server. Syntax public boolean isApplicationSettingsAvailable() Parameters None. Returns Returns credentials for HTTP basic authentication with a proxy server or Relay Server. isApplicationSettingsAvailable Checks whether the application settings are available from the Unwired Server. Syntax public void setHttpCredentials(LoginCredentials httpCredentials) Parameters • httpCredentials – credentials for HTTP basic authentication with proxy/relay server. getHttpCredentials Retrieves the credentials for HTTP basic authentication with a proxy server or Relay Server. Syntax public LoginCredentials getHttpCredentials() Parameters None.Client Object API Usage Returns None. ApplicationSettings Methods or properties in the ApplicationSettings class. Developer Guide: Android Object API Applications 81 . getStringProperty Retrieves a string property from the applicationSettings.getStringProperty(ConnectionPropertyType. Syntax public String getStringProperty(ConnectionPropertyType type) Parameters • type – Type of ConnectionPropertyType.Client Object API Usage Returns Returns true if the application settings are available.isApplicationS ettingsAvailable(). Examples • Check if application settings are available boolean isSettingsAvailable = Application. 82 Sybase Unwired Platform . getIntegerProperty Retrieves an integer property from the applicationSettings.UserName). Syntax public Integer getIntegerProperty(ConnectionPropertyType type) Parameters • type – Type of ConnectionPropertyType. Returns Returns an integer property value.getApplicationSettings(). Examples • Get string property String user_name = appSettings. Returns Returns a string property value.getInstance(). PwdPolicy_E nabled). Syntax public Boolean getBooleanProperty(ConnectionPropertyType type) Parameters • type – Type of ConnectionPropertyType.Client Object API Usage Examples • Get integer property int min_length = appSettings. Returns Returns a boolean property value. getBooleanProperty Retrieves a boolean property from the applicationSettings.PwdPolicy_L ength). getCustom1 A custom application setting for use by the application code. Syntax public String getCustom1() Parameters None. Developer Guide: Android Object API Applications 83 . Examples • Get boolean property boolean pwdpolicy_enabled = appSettings.getIntegerProperty(ConnectionPropertyType. Returns Returns a custom application setting.getBooleanProperty(ConnectionPropertyType. getCustom4 A custom application setting for use by the application code. Returns Returns a custom application setting. 84 Sybase Unwired Platform . getCustom3 A custom application setting for use by the application code. Syntax public String getCustom3() Parameters None. Returns Returns a custom application setting. Syntax public String getCustom2() Parameters None. Returns Returns a custom application setting. Syntax public String getCustom4() Parameters None.Client Object API Usage getCustom2 A custom application setting for use by the application code. Returns Developer Guide: Android Object API Applications 85 . ConnectionPropertyType Methods or properties in the ConnectionPropertyType class. getConnectionId Syntax public String getConnectionId() Parameters None. PwdPolicy_Enabled Indicates whether the password policy is enabled. Returns Returns a Connection ID for this application setting. Syntax ConnectionPropertyType PwdPolicy_Enabled Parameters None.Client Object API Usage getDomainName Syntax public String getDomainName() Parameters None. Returns Returns the domain name. Syntax ConnectionPropertyType PwdPolicy_Default_Password_Allowed Parameters None. PwdPolicy_Default_Password_Allowed Indicates whether the client application is allowed to use the default password for the data vault. Syntax ConnectionPropertyType PwdPolicy_Length Parameters None. 86 Sybase Unwired Platform . PwdPolicy_Length Defines the minimum length for a password.getBooleanProperty(ConnectionPropertyType.PwdPolicy_E nabled).Client Object API Usage Examples • PwdPolicy_Enabled boolean pwdpolicy_enabled = appSettings. Returns Returns an integer value for the minimum length for a password.getBooleanProperty(ConnectionPropertyType. Returns None.PwdPolicy_D efault_Password_Allowed). Examples • PwdPolicy_Default_Password_Allowed boolean default_password_allowed = appSettings. Client Object API Usage Examples • PwdPolicy_Length int min_length = appSettings. PwdPolicy_Has_Digits Indicates if the password must contain digits.PwdPolicy_L ength). Syntax ConnectionPropertyType PwdPolicy_Has_Upper Parameters None. PwdPolicy_Has_Upper Indicates if the password must contain at least one upper case character.getBooleanProperty(ConnectionPropertyType. Developer Guide: Android Object API Applications 87 .PwdPolicy_H as_Digits). Returns Returns true if the password must contain digits. Syntax ConnectionPropertyType PwdPolicy_Has_Digits Parameters None.getIntegerProperty(ConnectionPropertyType. Examples • PwdPolicy_Has_Digits boolean has_digits = appSettings. Returns Returns true if the password must contain at least one upper case character. Syntax ConnectionPropertyType PwdPolicy_Has_Special Parameters None. Returns Returns true if the password contains at least one lower case character. PwdPolicy_Has_Lower Indicates if the password must contain at least one lower case character. Returns Returns true if the password must contain at least one special character.PwdPolicy_H as_Upper).getBooleanProperty(ConnectionPropertyType. Examples • PwdPolicy_Has_Lower boolean has_lower = appSettings. 88 Sybase Unwired Platform . PwdPolicy_Has_Special Indicates if the password must contain at least one special character.PwdPolicy_H as_Lower). A special character is a character in the set "~!@#$%^&*()-+".getBooleanProperty(ConnectionPropertyType.Client Object API Usage Examples • PwdPolicy_Has_Upper boolean has_upper = appSettings. Syntax ConnectionPropertyType PwdPolicy_Has_Lower Parameters None. Client Object API Usage Examples • PwdPolicy_Has_Special boolean has_special = appSettings. PwdPolicy_Min_Unique_Chars Specifies the minimum number of unique characters in the password.getIntegerProperty(ConnectionPropertyType. PwdPolicy_Expires_In_N_Days Specifies the number of days in which the password expires from the date of setting the password. Syntax ConnectionPropertyType PwdPolicy_Expires_In_N_Days Parameters None. Returns Returns an integer value for the number of days in which the password expires. Syntax ConnectionPropertyType PwdPolicy_Min_Unique_Chars Parameters None.PwdPolicy_E xpires_In_N_Days).PwdPolicy_H as_Special). Returns An integer specifying the minimum number of unique characters in the password.getBooleanProperty(ConnectionPropertyType. Examples • PwdPolicy_Expires_In_N_Days int expires_in_n_days = appSettings. Developer Guide: Android Object API Applications 89 . Returns An integer specifying the timeout value. PwdPolicy_Lock_Timeout Specifies the timeout value (in seconds) after which the vault is locked from the unlock time. Syntax ConnectionPropertyType PwdPolicy_Retry_Limit Parameters None. PwdPolicy_Retry_Limit Specifies the number of failed unlock attempts after which the data vault is deleted. 90 Sybase Unwired Platform .PwdPolicy_L ock_Timeout). Examples • PwdPolicy_Lock_Timeout int lock_timeout = appSettings. A value of 0 indicates no timeout.PwdPolicy_M in_Unique_Chars). Returns An integer specifying the number of failed unlock attempts after which the data vault is deleted.getIntegerProperty(ConnectionPropertyType.getIntegerProperty(ConnectionPropertyType. A value of 0 indicates no retry limit.Client Object API Usage Examples • PwdPolicy_Min_Unique_Characters int min_unique_characters = appSettings. Syntax ConnectionPropertyType PwdPolicy_Lock_Timeout Parameters None. The example shows plain text. and other parameters. You can obtain configuration data for your application using Afaria by calling the following API from the com. but it can also be provided as a text or binary file. To use these APIs you must provide the application to the device through an Afaria application policy. The following is an an example of the Afaria admin screen for an application policy that provides an application named "CertsOnBoard" to an enrolled device.PwdPolicy_R etry_Limit). Afaria APIs Use the Afaria APIs to provision your Sybase Unwired Platform application with configuration data for connecting to the Unwired Server and certificates.Client Object API Usage Examples • PwdPolicy_Retry_Limit int retry_limit = appSettings. Using Afaria to Provision Configuration Data You can use Afaria to provision configuration data for a Sybase Unwired Platform application. When setting up such an application policy. the Afaria admin interface provides an option to add configuration data to the policy as text or binary.SeedDataAPI class (in AfariaSSL. including the Unwired Server server name.afaria.sybase. but you can also provide the information as XML or JSON text for easier parsing by the application. the configuration information is added using the admin user interface. In this case.getIntegerProperty(ConnectionPropertyType. Developer Guide: Android Object API Applications 91 .jar). The "Configuration" tab shows the configuration data provided to the application. port number. appConnections.retrieveSeedData(SeedDataCredentials arg0) throws SeedDataAPIException To access this data.put(strs[0].append(“the seed data file: ” + result). } finally { if(reader != null) { reader. appConnections. appConnections. } } //set the download configuration to application connectionProperties Application app = Application.get("port") )).getConnectionProperties(). String result = SeedDataAPI. while ((line = reader. keyValues = new java.append(line + "\r\n").retrieveSeedData(sdc). Map<String.close(). String line = null. strs[1]). String[] strs = line.afaria.setServerName(keyValues. SeedDataCredentials sdc = new SeedDataCredentials(“supadmin”. try { reader = new BufferedReader(new FileReader(result)). } } } catch(Exception ex) { throw new RuntimeException(ex). appConnections. If the device is correctly enrolled to Afaria.setUrlSuffix(keyValues. the API returns a string which contains the full path to a file in the application's sandbox with the seed data. String> keyValues = null.split(":").get("Farm ID")). the application provides SeedDataCredentials to the retrieveSeedData API. if(strs.append("server port is set to: " + 92 Sybase Unwired Platform .SeedDataAPI. BufferedReader reader = null. resultText.getInstance().setFarmId(keyValues. resultText.getServerName() + "\r\n").sybase.”xnetqa”.”abc”).get("server")).HashMap<String. resultText.Client Object API Usage String com.get("URL Suffix")). String>().parseInt(keyValues.append("server name is set to: " + appConnections.setPortNumber(Integer.util.length == 2) { keyValues.readLine()) != null) { resultText. ConnectionProperties appConnections = app. sybase.sybase.sybase. RSAPrivateKey arg1. The Textview output is: the seed data file: data/data/com. an application using Afaria may obtain a signed certificate using this API: X509Certificate com.append("url suffix is set to: " + appConnections.txt server: relayserver. SeedDataCredentials arg4) throws SeedDataAPIException After this.getPortNumber() + "\r\n"). After calling the Afaria APIs to get initial settings and configuration data. the application will have an X509Certificate object.getUrlSuffix() + "\r\n").app/files/seedData/ SUPOnboardingSeedData. String arg2. resultText. Using Certificates from Afaria for Authentication One of the features of Afaria is the ability to provide a device with a signed certificate that could be used as an authentication credential for Sybase Unwired Platform.dl Farm ID: example. and attach it to a Sybase Unwired Platform synchronization profile. String arg3. a certificate can be used for authentication by creating a LoginCertificate object (the LoginCertificate class).exampleMBS For more information on the Afaria APIs and the meanings of return codes.getFarmId() + "\r\n").retrieveCertificate(RSAPublicKey arg0.exampleMBS server name is set to: relayserver.com port: 80 URL Suffix: /ias_relay_server/client/rs_client.dl farm id is set to: example.afaria. and setting that as the certificate property in the client's synchronization profile. In Sybase Unwired Platform. This note explains how to take a certificate provided by Afaria and convert it into a form suitable for use with Sybase Unwired Platform. Developer Guide: Android Object API Applications 93 .SeedDataAPI. resultText. The certificate data in the X509Certificate object cannot be used as a LoginCertificate.Client Object API Usage appConnections. see the Afaria documentation. This sample code shows how to get the Afaria certificate. create a LoginCertificate object. Prerequisites: • • The application has been built using the Sybase Unwired Platform generated code and framework headers and libraries. It must be converted into a LoginCertificate. The application has been registered with the Afaria server as an application policy and made available to the client device.append("farm id is set to: " + appConnections.com server port is set to: 80 url suffix is set to: /ias_relay_server/client/rs_client. connProperties. Certificate[] chain = {cer}. cer). //we need to wrap the X509Certificate and private key to a PKCS12 Certificate java. before synchronizing.security API KeyPairGenerator keyPairGen = KeyPairGenerator.setLoginCertificate(lc).toCharArray()). String commonName = "SUP-SSO". RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.KeyStore. initialize SeedDataAPI using current Android Activity context SeedDataAPI.security. 94 Sybase Unwired Platform . privateKey. ks.initialize(1024). String passWord = "sup".getPrivate(). chain). privateKey.security. as shown.getInstance().getDefault(). ks.getSignedCertificateFromFile(pkcsFile . keyPairGen.pfx".toCharArray(). commonName. passWord.initialize(this).getConnectionProperties().load(null. //get the X509Certificate object from Afaria server by Afaria API X509Certificate cer = SeedDataAPI.setKeyEntry(commonName. passWord.Client Object API Usage The part of the code from the top through the section which retrieves the LoginCertificate object is performed only once during application initialization where you are obtaining the certificate through Afaria. Each time the application runs thereafter.getInstance("PKCS12"). passWord. The LoginCertificate is next stored in the data vault. RSAPublicKey publicKey = (RSAPublicKey) keyPair. null). //call API to get LoginCertificate object from the PKCS12 certificate file LoginCertificate lc = CertificateStore.KeyStore ks = java.store(out. FileOutputStream out = new FileOutputStream(pkcsFile). ks. passWord).setLoginCertificate(lc). ks.getInstance("RSA").getPublic(). it retrieves the LoginCertificate from the data vault and sets it into the connProperties.generateKeyPair(). //first. ConnectionProperties connProperties = app. KeyPair keyPair = keyPairGen.toCharArray()). passWord.setCertificateEntry(commonName. //generate a key pair using java.retrieveCertificate(publicKey. String pkcsFile = "/mnt/sdcard/SUP-SSO. //use the loginCertificate to register Application Application app = Application. and establishes a connection to the database.Client Object API Usage Connection APIs The Connection APIs contain methods for managing local database information. establishing a connection with the Unwired Server. if the application starts up with a login screen and a background thread that performs the openConnection() method. including the encryption key. You can use the cacheSize API to control the size of the memory cache used by the database. profile.getConnectionProfile(). the database class name is generated as "packageName"+"DB". the connection is most likely already established and is immediately available to the user. and then store the key inside a DataVault object. By default. This method is useful when first starting the application: since it takes a few seconds to open the database when creating the first connection. during application initialization. after logging in. creates it if it does not. The openConnection() method checks that the package database exists. and before creating or accessing the local client database. public void setCacheSize(int cacheSize) See also • Setting Up the Connection Profile on page 32 Managing Device Database Connections Use the openConnection() and closeConnection() methods generated in the package database class to manage device database connections. The generateEncryptionKey method automatically sets the encryption key in the connection profile.setEncryptionKey("Your key of more than 16 characters"). and authenticating. Set its properties. Note: Any database operation triggers the establishment of the database connection. profile. Developer Guide: Android Object API Applications 95 . You can also generate an encryption key by calling the generated database's generateEncryptionKey method. ConnectionProfile profile = SUP101DB.setPageSize( 4*1024 ). You do not need to explicitly call the openConnection API. See also • Initially Starting an Application on page 29 ConnectionProfile The ConnectionProfile class manages local database information. This is recommended to be part of the application shutdown process. When pagination is used. That is. the loading of details for that entry must wait until the entire list is loaded. connectionProfile. the detail view of that entry appears. To allow 6 concurrent threads. Improving Device Application Performance with One Writer Thread and Multiple Database Access Threads The maxDbConnections property improves device application performance by allowing multiple threads to access data concurrently from the same local database. otherwise they will not take effect. update. Connection management allows you to have at most one writer thread concurrent with multiple reader threads. which can be a long while. The default value (maximum number of concurrent read threads) is 2. In the list view to detail view example. or delete (CRUD) operation waited for any previous operation to finish before the next was allowed to proceed. depending on the size of the list. which you set before performing any operation in the application. The ConnectionProfile class in the persistence package includes the maxDbConnections property. You can specify the number of total threads using maxDbConnections. Prior to the implementation of maxDbConnections. set the maxDbConnections property to 6 in ConnectionProfile before accessing the package database at the beginning of the application. The total number of threads are controlled by the maxDbConnections property. a list view lists all the entities of a selected type. In a typical device application such as Sybase Mobile CRM. create. The closeConnection() method closes all database connections for this package and releases all resources allocated for those connections. When the device application user selects an entry from the list. such as. ConnectionProfile connectionProfile = SUP101DB.Client Object API Usage All ConnectionProfile properties should be set before the first access to database. background threads load subsequent pages. and loads the details for that entry. There can be other reader threads at the same time that the writer thread is writing to the database. read. when the background thread is loading the entire list. access to the package on the local database was serialized.getConnectionProfile(). and a user selects the details of one entry for display. 96 Sybase Unwired Platform . an MBO database operation.setMaxDbConnections(6). ulj" Note: For the database file path and name. a specific directory path. port. domain name.ulj. this information includes the server host. By default.getAbsolutePath() + "/ mydb. cp. such as the directory of the running program. The database is UltraLiteJ™.sybase. If the device client user changes the file name. Not all SD cards perform equally.Client Object API Usage Set Database File Property You can use setProperty to specify the database file name on the device. he or she must make sure the input file name is a valid name and path on the client side. certificate and public key that are pushed by the message channel during the registration process.ulj"). Synchronization Profile The Synchronization Profile contains information for establishing a connection with the Unwired Server's data synchronization channel where the server package has been deployed.save(). The com. with no path. Settings are automatically provisioned from the Unwired Server. although they may be more limited in size and more expensive per unit of storage. the databaseFile is created in the path where the program is running: mydb. Note: Sybase recommends using industrial grade SD cards using Single Level Cell (SLC) technology. SD cards that use SLC technology are generally more reliable and faster than MLC cards. the forward slash (/) is required as the path delimiter.ulj.ulj To store the database on the SD card: Environment. for example /mnt/sdcard/sup101. Usage • • • Be sure to call this API before the database is created. ConnectionProfile cp = SUP101DB.persistence. use an absolute path to the database file name like / sdcard/mydb.setProperty("databaseFile". "SUP101. Examples If you specify the databaseFile name only.getConnectionProfile()..getExternalStorageDirectory(). and it is advised that customers evaluate the benchmarks available from different suppliers. The values of the settings are inherited from the application connection template used for the registration of the application Developer Guide: Android Object API Applications 97 . or a secure digital (SD) card.ConnectionProfile class manages that information. cp. using e2ee security.getSynchronizationProfile().Client Object API Usage connection (automatic or manual).com" ).setTrusted_Certificates( "rsa_public_cert . getSynchronizationProfile(). profile. profile. See also • Setting Up the Synchronization Profile on page 33 Connect the Data Synchronization Channel Through a Relay Server To enable your client application to connect through a Relay Server. See the Applications and Application Connection Templates topics in System Administration. Typically.crt" ).setPortNumber(80).setPortNumber( 2480 ). streamParams.setNetworkProtocol("http").getSynchronizationProfile(). getSynchronizationProfile().setNetworkProtocol("http"). To update properties for a Relay Server installed on Internet Information Services (IIS) on Microsoft Windows: getSynchronizationProfile().setServerName("examplexp-vm1"). or a certificate used for the intermediary.setPortNumber(80).getStreamParams(). profile.setZlibCompr ession(true).setServerName("examplexp-vm1"). profile. You can allow clients to compress traffic as they communicate with the Unwired Server by including "compression=zlib" into the sync parameters: SUP101DB.setUrl_Suffix("/cli/iarelayserver/<FarmName>"). profile.setDomainName("default"). you can enter the related configuration in the application connection template through Sybase Control Center. such as a Relay Server Web server). getSynchronizationProfile().sybase.getStreamParams(). ConnectionProfile profile = SUP101DB.setServerName( "sup. NetworkStreamParams streamParams = getSynchronizationProfile().setUrl_Suffix("/ias_relay_server/client/rs_client. getSynchronizationProfile().dll/ <FarmName>"). NetworkStreamParams streamParams = getSynchronizationProfile(). 98 Sybase Unwired Platform . using relay server. streamParams.setDomainName( "default" ). You must make use of the connection and security settings that are automatically used by the Object API. the application uses the settings as sent from the Unwired Server to connect to the Unwired Server for synchronization so that the administrator can set those at the application deployment time based on their deployment topology (for example. and/or setup the configuration properties in the synchronization profile using the object API.setDomainName("default").getStreamParams(). Edit SUP101DB by modifying the values of the Relay Server properties for your Relay Server environment. getSynchronizationProfile().setNetworkProtocol( "http" ).getStreamParams(). getSynchronizationProfile(). getSynchronizationProfile(). pers istence. You can specify an upload-only synchronization where the client sends its changes to the server. You can enable or disable the feature by setting the asyncReplay property in the synchronization profile.ASYNC_REPLAY_COMPLETED. SynchronizationContext context) { Developer Guide: Android Object API Applications 99 . the operation replay records are uploaded to the server. If you choose to disable asynchronous operation replay. an operation replay record is created on the device local database. If you try to delete the database. but does not download other changes from the server.getSynchronizationProfile(). or delete operation is performed. boolean uploadOnly) When asynchronous replay is enabled and the replay is finished. the onSynchronize callback method is invoked with a SynchronizationStatus value of SynchronizationStatus. Before deleting the database. The method returns without waiting for the backend to replay those records.stopConnection()). stop the application connection (Application.startConnection() or Application.setAsyncReplay(false). each synchronize call will wait for the backend to finish replaying all the current uploaded operation replay records.registerApplica tion). When the application is connected (by Application. update. This type of synchronization conserves device resources when receiving changes from the server. Asynchronous Operation Replay Upload operation replay records asynchronously. This feature is enabled by default. public static void beginSynchronize(com.SynchronizationGroup> sgs. it may receive background notifications and trigger a synchronize or other database operation. see System Administration and Sybase Control Center for Sybase Unwired Platform.collections. When an application calls submitPending on an MBO on which a create. When synchronize is called.sybase. public class MyCallbackHandler extends DefaultCallbackHandler { public int onSynchronize(GenericList<SynchronizationGroup> groups. The following code shows how to disable asynchronous replay: SUP101DB.Client Object API Usage For more information on relay server configuration.sybase. as shown in the following callback handler.GenericList<com. you may receive database exceptions. The synchronize method downloads all the latest data changes and the results of the previously uploaded operation replay records that the backend has finished replaying in the background. Use this callback method to invoke a synchronize call to pull in the results.Object context. The package database class provides methods for logging in to the Unwired Server: • onlineLogin() – authenticates credentials against the Unwired Server. default: break. 100 Sybase Unwired Platform . LogMessage("AsyncReplay Done"). Sample Code Illustrates importing the certificate and setting up login credentials. LoginCertificate lc = myStore.ASYNC_REPLAY_UPLOADED: LogMessage("AsyncReplay uploaded"). String certFile = "/mnt/sdcard/sybase101. for example "/mnt/sdcard/sybase101.p12".CONTINUE // will start a background synchronization to pull in the results.getDefault(). } } return SynchronizationAction. break. case SynchronizationStatus.getSignedCertificateFromFile(certFile.Client Object API Usage switch(context. String password = "my p12 password". } Authentication APIs You can log in to the Unwired Server with your user name and credentials and use the X. You can log in to the Unwired Server with your user name and credentials.p12" //Get certificate from certificate file CertificateStore myStore = certificateStore. return SynchronizationAction.getStatus()) { case SynchronizationStatus. Logging In The generated package database class provides a default synchronization connection profile according to the Unwired Server connection profile and server domain selected during code generation. break.CONTINUE.509 certificate you installed in the task flow for single sign-on. as well as other APIs related to certificate handling: /// SUP101DB is a generated database class ///First put the p12 certificate file on the SDCard of the device. password).ASYNC_REPLAY_COMPLETED: // operation replay finished. Importing a certificate from a system store is not supported on Android. } else { vault = DataVault. // Import a certificate from a file on SDCard String certFile = "/mnt/sdcard/mycert.getSynchronizationProfile().apk package must be installed on Android device String vaultName = "myVault". Importing a Certificate into the Data Vault Obtain a certificate reference and store it in a password-protected data vault to use for X.vaultExists(vaultName)) { vault = DataVault.Client Object API Usage // Save the login certificate to your synchronization profile SUP101DB.getVault(vaultName).wraps platform-specific key/certificate store class. LoginCertificate. • • • CertificateStore class .509 distinguished name and signed certificate ConnectionProfile class .509 certificate authentication.createVault(vaultName.509 Certificate Related Object API Use these classes and attributes when developing mobile applications that require X. vault).includes the certificate attribute used for Unwired Server synchronization. or file directory LoginCertificate class . "salt"). "password". // Save the login certificate to your data vault // The vault must be unlocked before saving // SybaseDataProvider. vault). "salt"). if(!DataVault. Single Sign-On With X.getDefault(). You can only import a certificate binary large object (BLOB).delete("myLabel".setCertificate(lc). from a file directory. String password = "my p12 password". Developer Guide: Android Object API Applications 101 .509 certificate authentication. // Obtain a reference to the certificate store CertificateStore certStore = CertificateStore. vault). //Load and delete certificate LoginCertificate newLc = LoginCertificate.load("myLabel".save("myLabel".wraps platform-specific X.unlock("password".p12". } vault. lc. which is a digitally signed copy of the public X.509 certificate. DataVault vault = null. Refer to the API Reference for implementation details. Selecting a Certificate for Unwired Server Connections Select the X.. Connecting to Unwired Server with a Certificate Once the certificate property is set.getSynchronizationProfile(). See also • Specifying Personalization Parameters on page 42 102 Sybase Unwired Platform .onlineLogin().getVault(vaultName). vault)..setCertificate(cert). vaultSalt). ConnectionProfile syncProfile = SUP101DB.load("myCert". try { vault = DataVault.CertificateVault" String vaultSalt = ". // ask user or from O/S protected storage String vaultName = ". LoginCertificate cert = LoginCertificate. Personalization parameters provide default values for synchronization parameters when the synchronization key of the object is mapped to the personalization key while developing a mobile business object.509 certificate from the data vault for Unwired Server authentication.. syncProfile.Client Object API Usage LoginCertificate cert = certStore. // for example. vault. SUP101DB. Do not use the onlineLogin() API with username and password.. // Lookup or create data vault String vaultPassword = . // for example.createVault(vaultName.".getSignedCertificateFromFile(certFile. a hard-coded random GUID DataVault vault.. "SAP. vaultSalt). and get and set personalization key values. Personalization APIs Personalization keys allow the application to define certain input parameter values that are personalized for each mobile user.. use the onlineLogin() API with no parameters. The Personalization APIs allow you to manage personalization keys.CRM. vaultPassword.".save("myCert".unlock(vaultPassword. } // Save certificate into data vault cert.. vault). password). } catch (DataVaultException ex) { vault = DataVault. save(). or ObjectList). il. When a personalization parameter value is changed. so that they can be propagated to the EIS. The developer can also define personalization keys for the application.add(10001). dl.setStringMember2( . pp.setMyIntPK(10002).. Developer Guide: Android Object API Applications 103 .. //MyData is a structure type defined in tooling MyData md = new MyData(). pp.save().add(md). IntList il = new IntList(2). and pass an array of values and an array of objects: PersonalizationParameters pp = SUP101DB. it must be mapped to a synchronization parameter. To use a personalization key for filtering. MyDataList dl = new MyDataList().setMyDataList( dl ).. Server personalization keys are persisted on the Unwired Server. StringList. and transient (or session).Client Object API Usage Type of Personalization Keys There are three types of personalization keys: client. pp. A personalization parameter can be a primitive or complex type. pp. pp. An operation can have a parameter that is one of the Sybase Unwired Platform list types (such as IntList. Getting and Setting Personalization Key Values The PersonalizationParameters class is generated automatically for managing personalization keys. md. as well as connecting to the back-end EIS using the same set of credentials. ).getPersonalizationParameters(). Two builtin (session) personalization keys — username and password — can be used to perform single sign-on from the device application to the Unwired Server. server.setMyIntListPK(il). This code shows how to set a personalization key. the server. pp.setIntMember( . or by session. A personalization key is metadata that enables users to store their search preferences on the client. Session personalization keys are not persisted and are lost when the device application terminates.save(). The password is never saved on the server. Often personalization keys are used to hold backend system credentials. md.add(10002). Client personalization keys are persisted in the local database. the call to save automatically propagates the change to the server. il.. and can use built-in personalization keys available in Unwired Server. authentication and authorization on Unwired Server. ). The preferences narrow the focus of data retrieved by the mobile device (also known as the filtering of data between client and Unwired Server). Performing Mobile Business Object Synchronization A synchronization group is a group of related MBOs. An implicit default synchronization group includes all the MBOs that are not in any other synchronization group. sp. and synchronization. After saving the synchronization parameters. you can overwrite the value of that parameter with the personalization value. or as a group.Client Object API Usage If a synchronization parameter is personalized. This code synchronizes an MBO package using a specified connection: SUP101DB. See also • Synchronizing Applications on page 40 • Specifying Synchronization Parameters on page 43 Changing Synchronization Parameters Synchronization parameters let an application change the parameters that retrieve data from an MBO during a synchronization session.getSynchronizationParameters(). The primary purpose of synchronization parameters is to partition data. When a synchronization parameter value is changed. for individual MBOs. Call synchronize or beginSynchronize before saving synchronization parameters. CustomerSynchronizationParameters sp = Customer. sp. The next synchronize call will retrieve data from the server.synchronize (string synchronizationGroup) 104 Sybase Unwired Platform .setMyid(10001). Change the synchronization parameters to affect the data you are working with (including searches). Note: The loginToSync API is now deprecated. Note: The Unwired Server will not send MBO data to a device if an MBO has synchronization parameters defined. the call to save automatically propagates the change to the Unwired Server. This is true even if default values are defined for its synchronization parameters. unless the application client code calls the save method.save(). call synchronize or beginSynchronize again to retrieve the new values filtered by those parameters. based on the group's synchronization policy. Synchronization APIs You can synchronize mobile business objects (MBOs) based on synchronization parameters. A mobile application can have predefined synchronization groups. synchronize("default"). The default synchronization group includes all MBOs except those already included by other synchronization groups.Client Object API Usage The package database class includes two synchronization methods. "upload OperationReplay objects"). sgs. and vacuumDatabase methods are for use with DOE-based applications only. call SUP101DB. Developer Guide: Android Object API Applications 105 . SUP101DB. update. When an application uses a create.getSynchronizationGroup("my-sync-group")).synchronize().synchronize(). or delete operation in an MBO and calls the submitPending metod. to remove an existing subscription from the Unwired Server. SUP101DB. To synchronize a synchronization group asynchronously: GenericList<SynchronizationGroup> syncGroups = new GenericList<SynchronizationGroup>().synchronize("my-sync-group"). Note: The beginOnlineLogin. } Message-Based Synchronization APIs The message-based synchronization APIs enable a user application to subscribe to a server package.add(SUP101DB.add(SUP101DB.beginSynchronize("default"). resumeSubscription.beginSynchronize(sgs. an OperationReplay object is created for that change.beginSynchronize(syncGroups. You can synchronize a specified group of MBOs using the synchronization group name: SUP101DB. syncGroups. If there is no other synchronization group. or SUP101DB. The isReplayQueueEmpty API is used to check if there are unsent operation replay objects and decide whether a synchronize call is needed. ""). you can synchronize all synchronization groups: SUP101DB.beginSynchronize(). Or.getSynchronizationGroup("system")). The application must invoke either the synchronize or beginSynchronize method to upload the OperationReplay object to the server to replay the change on the backend data source. suspendSubbscription. To synchronize a default synchronization group call: SUP101DB. There is a default synchronization group within every package. and to recover data related to the package from the server. if (!SUP101DB. or SUP101DB. to suspend or resume requests to the Unwired Server.isReplayQueueEmpty()) { // There are OperationReplay not uploaded to server GenericList<SynchronizationGroup> sgs = new GenericList<SynchronizationGroup>(). If the subscription succeeds. When the login succeeds. subscribe Subscribes to a server package. Typically. the onSubscribeSuccess method of the ICallbackHandler is invoked. Returns None. The Unwired Server responds with a message to the client with the login success or failure. the generated package database class already has a valid synchronization connection profile and you can log in to the Unwired Server with your username and credentials.Client Object API Usage beginOnlineLogin Sends a login message to the Unwired Server with the username and password.beginOnlineLogin("supAdminID". "supPwd"). beginOnlineLogin sends a message to the Unwired Server with the username and password. otherwise an exception may be thrown. the onLoginFailure method of the CallbackHandler is invoked. the onSubscribeFailure method of the ICallbackHandler is invoked. the onLoginSuccess method of the CallbackHandler is invoked. String password) Parameters • • userName – the user name. SUP101DB. When the login fails. Syntax public static void beginOnlineLogin(String userName. password – the password. Prerequisites for using subscribe: 106 Sybase Unwired Platform . Examples • Begin an Online Login – Start logging in with "supAdminID" for the user name and "supPass" for the password. If the subscription fails. Make sure the connection is active before calling beginOnlineLogin. A subscription message is sent to the Unwired Server and the application receives a subscription request result notification from the the Unwired Server. subscribe(). the onSubscribeFailure method of the CallbackHandler is invoked.Client Object API Usage • • • The mobile application is compiled with the client framework and deployed to a mobile device. The device application has already configured Unwired Server connection information. Returns None. Examples • Subscribe to a Sample Application – Subscribe to SUP101DB. An unsubscription message is sent to the Unwired Server and the application receives a subscription request result notification from the Unwired Server as a notification. Developer Guide: Android Object API Applications 107 . Syntax public static void unsubscribe() Parameters • None – unsubscribe has no parameters. The device application must already have a subscription with the server. Returns None. SUP101DB. If the unsubscribe succeeds. the onSubscribeSuccess method of the CallbackHandler is invoked. unsubscribe Removes an existing subscription to a server package. Examples • Unsubscribe from a Sample Application – Unsubscribe from SUP101DB. Authentication credentials must also be set. The data on the local database is cleaned. using either the beginOnlineLogin or offlineLogin APIs. together with the Sybase Unwired Platform client process. If it fails. Syntax public static void subscribe() Parameters • None – subscribe has no parameters. the onSuspendSubscriptionFailure method of the CallbackHandler is invoked. Returns None. Syntax public static void beginSynchronize public static void beginSynchronize(GenericList<SynchronizationGroup> sgs. The synchronization completes in the background through an asynchronous message exchange with the server. one with no parameters that synchronizes all the groups. Syntax public static void suspendScription() Parameters • None – suspendSubscription has no parameters. suspendSubscription Sends a suspend request to the Unwired Server to notify the server to stop delivering data changes.Client Object API Usage SUP101DB. a callback handler that implements the onSynchronize method must be registered with the database class. If the suspend succeeds. There are two different beginSynchronize APIs.unsubscribe(). Object context) 108 Sybase Unwired Platform .suspendScription(). If application code needs to know when the synchronization is complete. beginSynchronize Sends a message to the Unwired Server to synchronize data between the client and the server. A suspend subscription message is sent to the Unwired Server and the application receives a suspend subscription request result notification from the Unwired Server as a notification. If the suspend fails. Examples • Suspend a Subscription – Suspend the subscription to SUP101DB. the onSuspendSubscriptionSuccess method of the CallbackHandler is invoked. and one that takes a list of groups. SUP101DB. beginSynchronize(null. Developer Guide: Android Object API Applications 109 . SUP101DB. Note: This parameter is not relevant for DOE packages. For more information on the onSynchronize callback handler method. resumeSubscription Sends a resume request to the Unwired Server. • • Returns None. The resume request notifies the Unwired Server to resume sending data changes for the subscription that had been suspended. begin synchronizing data for all groups. see Callback Handlers in Developer Guide for Android. the synchronization both uploads and downloads data. onResumeSubscriptionFailure callback handler is called. otherwise. pass a null value to this parameter. uploadOnly – If true. On failure. Syntax public static void resumeSubscription() Parameters • None – resumeSubscription has no parameters.resumeScription(). If omitted. SUP101DB. the synchronization only uploads data. Examples • Resume a Subscription – Resume the subscription to SUP101DB. On success. Examples • Synchronize Data between Client and Server – Synchronize data for SUP101DB for all synchronization groups.Client Object API Usage Parameters • synchronizationGroups – specifies a list of a list of SynchronizationGroup objects representing the groups to be synchronized. onResumeSubscriptionSuccess callback handler method is called. Returns None. "my context"). context – a reference string used when the server responds to the synchronization request. setEnableSIS(true).save().STARTING_ON_NOTIFICATION) { // There is changes on the synchronization group if (busy) { return SynchronizationAction.synchronize("TCNEnabled"). change notification is disabled. } } // return CONTINUE for all other status return SynchronizationAction.CANCEL. then change detection is disabled. } If you see that setInterval is set to 0.getSynchronizationGroup("TCNEnabled"). see Configuring Synchronization Groups in Sybase Control Center for Sybase Unwired Platform. SUP101DB. public int onSynchronize(GenericList<SynchronizationGroup> groups. if (status == SynchronizationStatus.getEnableSIS()) { sg. When the server detects changes in an MBO affecting a client device. The application can implement the onSynchronize callback method to monitor this condition. By default.CONTINUE. and notifications will not be delivered. // 2 minutes sg. } 110 Sybase Unwired Platform . the server will send a notification to client device through messaging channel. Sybase Unwired Platform uses a messaging channel to send change notifications from the server to the client device. sg. and either allow or disallow background synchronization. You can enable the change notification of a synchronization group: SynchronizationGroup sg = SUP101DB. if (!sg. For recommendations. a background synchronization downloads the changes for that synchronization group. and the synchronization group of the MBO has change detection enabled. By default.getStatus().setInterval(2).CONTINUE. Enable change detection and notification delivery by setting an appropriate value.Client Object API Usage Push Synchronization Applications Clients receive device notifications when a data change is detected for any of the MBOs in the synchronization group to which they are subscribed. } else { return SynchronizationAction. SynchronizationContext context) { int status = context. Client logs.findById(id). Enabling the printing of server message headers and message contents. result. register a CallbackHandler and implement the CallbackHandler.save(). See Developer Guide: BlackBerry Object API Applications > Client Object API Usage > Callback and Listener APIs. result.onReplaySuccess method.Date getLastSynchronizationTime(java.submitPending(). result = Customer.synchronize(). These logs can be uploaded to the Unwired Server. If an operation replay succeeds. Viewing detailed trace information on database calls. This code executes an update operation and examines the log records for the Customer MBO: int id = 101. database exceptions. Log records are automatically created when an operation replay fails in the Unwired Server. To get the confirmation when an operation replay succeeds.String synchronizationGroup) /// Retrieves the last synchronization time of the synchronization group public static java.findById(id).setFname("newFname").sybase.Client Object API Usage Retrieving Information about Synchronization Groups The package database class provides the following two methods for querying the synchronized state and the last synchronization time of a certain synchronization group: /// Determines if the synchronization group was synchronized public static boolean isSynchronized(java. and LogRecord objects written for each import.LogRecord logRecord : result.persistence.lang. result. for(com.util.getLogRecords()) Developer Guide: Android Object API Applications 111 . • • • • Writing and retrieving log records (successful operations are not logged).String synchronizationGroup) Log Record APIs The Log Record APIs allow you to customize aspects of logging. SUP101DB.lang. These logs can be downloaded to the device. there is no LogRecord created by default (note that an SAP default result checker may write a log record even when the SAP operation succeeds). Customer result = Customer. LogRecord API LogRecord stores two types of logs. • • Operation logs on the Unwired Server. Configuring log levels for messages reported to the console. There is no logRecord generated for a successful operation replay.find(surrogateKey). Customer c = Customer. This sample code shows how to find the corresponding MBO with the LogRecord and to delete the log record when a record is processed.getComponent(). GenericList<LogRecord> logRecords = SUP101DB. // set log level to debug logger. Each package has a Logger. } // delete the LogRecord after it is processed log. } } Logger APIs Use the Logger API to set the log level and create log records on the client. log. callSync = true.warning("log " + log.submitPending().cancelPending(). boolean callSync = false. if (log.getEntityKey() + " code:" + log.getMessage()).setLogLevel(LogLevel.getComponent() + ":" + log. if (c.parseLong(log.Client Object API Usage { //Working with logRecord } The code in the log record is an HTTP status code. for(LogRecord log : logRecords) { // log warning message Log. private void processLogs() { Query query = new Query().getLogger(). The Unwired Server only creates a logRecord when an operation fails.isPending()) { c.DEBUG).delete().getLogRecords(query). 112 Sybase Unwired Platform .equals("Customer")) { long surrogateKey = Long. Logger logger = SUP101DB. See Developer Guide: Android Object API Applications>Client Object API Usage >Exceptions > Handling Exceptions > HTTP Error Codes.getCode() + " msg:" + log. use the getLogger method in the generated database class. To obtain the package logger.getEntityKey()). Developer Guide: Android Object API Applications 113 . A single ChangeLog is generated for each changed entity. Syntax public char getOperationType() Parameters None.java for the package. modify. it simply needs to add. Returns Returns the entity type. logger.error("Some error message"). If a client application already has a list view constructed. there is also a ChangeLog for its parent root entity. The entity type values are defined in the generated java class EntityType. Change Log API The change log allows a client to retrieve entity changes from the back end. Syntax public int getEntityType() Parameters None. getEntityType Returns the entity type. If the changed entity is a child of a composite relationship.Client Object API Usage // create a log record with ERROR level and the error message. or delete entries in the list according to the change logs. Examples • Get the Entity Type getEntityType() getOperationType Returns the operation type of the MBO. Returns Returns the root entity type which is the root of the object graph. Examples • Get the Root Entity Type getRootEntityType() getRootSurrogateKey Returns the surrogate key of the root parent entity. Examples • Get the Operation Type getOperationType() getRootEntityType Returns the name of the root parent entity type Syntax public int getRootEntityType() Parameters None.java for the package. 114 Sybase Unwired Platform . Possible values are 'U' for update and insert. The entity type values are defined in the generated java class EntityType. Returns The surrogateKey of the root entity. Syntax public long getRootSurrogateKey() Parameters None. and 'D' for delete.Client Object API Usage Returns The operation type of the MBO. including children of the object graph. invoke the enableChangeLog API in the generated database class. Syntax public long getSurrogateKey() Parameters None. Syntax enableChangeLog(). enableChangeLog By default.Client Object API Usage Examples • Get the Root Surrogate Key getRootSurrogateKey() getSurrogateKey Returns the surrogate key of the entity. Note that the change log contains all affected entities. Returns None. Change Log is disabled. Examples • Get the Surrogate Key getSurrogateKey() Methods in the Generated Database Class You can use generated methods in the package database class to manage change logs. Developer Guide: Android Object API Applications 115 . To enable the change log. Returns The surrogate key of the affected entity. The next synchronization will have change logs sent to the client. Returns Returns a GenericList of type <Change Log>. getChangeLogs Retrieve a list of change logs.ChangeLog> getChangeLogs(com. Usage Ensure that when calling deleteChangeLogs. Examples • Get Change Logs GenericList<com.Client Object API Usage Examples • Enable Change Log SUP101DB.sybase.deleteChangeLogs().persistence.getChangeLogs(query).sybase. deleteChangeLogs You are recommended to delete all change logs after the application has completed processing them. Syntax GenericList<com. Returns None.persistence.enableChangeLog(). Examples • Delete Change Logs SUP101DB. there are no change logs created from a background synchronization that are not part of the original change log list returned by a specific query: 116 Sybase Unwired Platform .sybase.ChangeLog> clog = SUP101DB. Use the deleteChangeLogs API in the generated database class to delete all change logs on the device.Query query).persistence. Syntax deleteChangeLogs(). EntityType. disableChangeLog Creating change logs consumes some processing time.println(log. SUP101DB. // Retrieve all change logs GenericList<ChangeLog> logs = SUP101DB. System.size() + " change logs"). The application may can disable the change log using the disableChangeLog API.out.println("There are " + logs.Customer).lang. for (ChangeLog log : logs) { System.Client Object API Usage GenericList<ChangeLog> changes = getChangeLogs(myQuery). AttributeTest at = new AttributeTest("entityType". Returns None.getOperationType()). } // Retrieve only the change logs for Customer: Query query = new Query().Integer(SUP101.setTestCriteria(at).println("There are " + logs.out. AttributeTest. You should only call deleteChangeLogs in the onSynchronize() callback where there are no multiple synchronizations occurring simultaneously. or only the change logs for a particular entity. which can impact application performance.getEntityType() + "(" + log. Code Samples Enable the change log and list all changes.getChangeLogs(query). query. Syntax disableChangeLog().getChangeLogs(new Query()). Examples • Disable Change Log SUP101DB.out. Customer.disableChangeLog().size() + " change logs for Customer").synchronize(). SUP101DB. logs = SUP101DB.getSurrogateKey() + "): " + log.enableChangeLog().EQUAL). new java. for (ChangeLog log : logs) { Developer Guide: Android Object API Applications 117 . System. setCertificate(lc). } Security APIs The security APIs allow you to customize some aspects of connection and database security. ConnectionProfile profile = SUP101DB. You can use the Client Object API to set up end to end encryption.getOperationType()). LoginCertificate lc = CertificateStore.p12".getSynchronizationProfile().sybase.getStreamParams 118 Sybase Unwired Platform .Client Object API Usage System. Refer to the following APIs when setting up end to end encryption and compression support: • com.cert.println(log.generateEncryptionKey(). and before creating or accessing the client database. profile.getDefault(). Encrypt the Database You can set the encryption key of a local database. . Connect Using a Certificate You can set certificate information in ConnectionProfile. String key = profile. Set the key during application initialization. profile.getSurrogateKey() + "): " + log. supported by Ultralite..getConnectionProfile().ConnectionProfile. The length of the encyption key cannot be fewer than 16 characters. // store the encryption key at somewhere for reuse later ConnectionProfile profile = SUP101DB. and HTTPS items in the synchronization profile. ConnectionProfile profile = SUP101DB. SUP101DB. "password").persistence. End to End Encryption and Compression Support APIs Use encryption communication parameters to ensure end to end encryption and eliminate any WAP gap security problems.setEncryptionKey("Your key of length 16 or more characters").getSignedCertificateFromFile("/mnt/ sdcard/johnsmith.getEntityType() + "(" + log..createDatabase().getEncryptionKey(). SUP101DB.out. You can use the generateEncryptionKey() method to encrypt the local database with a random encryption key.getConnectionProfile(). cp.sybase.setZlibCompression(true). cp.NetworkStreamParams.persistence.getStreamParams(). passwords.setPassword(password).setE2ee_Type("RSA").NetworkStreamParams.sybase. cp.persistence. you can use the DataVault class for on-device persistent storage of certificates. cp.Client Object API Usage • • • • • • • • • • • • com. Use this class to: Developer Guide: Android Object API Applications 119 .persistence. cp. and other sensitive items. database encryption keys.getZlib_Downloa d_Window_Size The following code example shows how to set SUP101: ConnectionProfile cp=SUP101DB.save().sybase. cp.getStreamParams(). All exceptions thrown by DataVault methods are of type DataVaultException.NetworkStreamParams. cp.getSynchronizationProfile().sybase.persistence.getStreamParams().NetworkStreamParams.getStreamParams().setPortNumber(2480).setE2ee_Public_Key(sdcard directory +ApplicationName+"_e2eeKey.getStreamParams().synchronize().NetworkStreamParams.persistence.sybase.NetworkStreamParams.setZlib_Upload_Window_Size(12). cp.setNetworkProtocol("HTTP").getZlib_Upload_ Window_Size com.getE2ee_Type com.persistence.setZlibCompress ion com.setE2ee_Type com.persistence.sybase.setTrusted_Cert ificates com.persistence.key").NetworkStreamParams.sybase.NetworkStreamParams. SUP101DB.setZlib_Upload_ Window_Size com.apk package.sybase.sybase.sybase.setUserName(userName).persistence.persistence.setZlib_Download_Window_Size(12). DataVault The DataVault class provides encrypted storage of occasionally used.getE2ee_Public_ Key com. cp.sybase.NetworkStreamParams.setE2ee_Public_ Key com.NetworkStreamParams.persistence.getZlibCompress ion com.NetworkStreamParams.getTrusted_Cert ificates com. If you have installed the SybaseDataProvider. small pieces of data.NetworkStreamParams. cp.setZlib_Downloa d_Window_Size com.persistence.sybase. the user is allowed into the rest of the application. If the user enters an incorrect password.Client Object API Usage • • • • • Create a vault Set a vault's properties Store objects in a vault Retrieve objects from a vault Change the password used to access a vault The contents of the data vault are strongly encrypted using AES-256. for example. The vault can also relock itself after a configurable amount of time. and specify a password and salt used to unlock it. In addition to saving the context for later use. Connect the Android device to your computer. Syntax public static void init(android. the contents are decrypted.exe file.Context oContext) Parameters • oContext – Valid application context. The password and salt together generate the AES key. or C:\Program Files\androidsdk-windows\platform-tools. . If the unlock attempt is successful. Open the command line directory to the adb. the user is prompted for a password. User credentials for synchronization can also be extracted from the vault so the user need not reenter passwords. The DataVault class allows you create a named vault.exe install <UnwiredPlatform_InstallDir> \UnwiredPlatform\MobileSDK\ObjectAPI\Android \SybaseDataProvider. 3. Upon application start. this method also initializes static member variables (such as encryption objects). exceptions occur. Run the command adb. Typical usage of the DataVault is to implement an application login screen. If the user enters an incorrect password a configurable number of times. 2. To install SybaseDataProvider. which unlocks the vault. The password can be of arbitrary length and can include any characters. If the user enters the same password when unlocking.apk on an Android device: 1. the vault is deleted and any data stored within it becomes unrecoverable.apk init Initialization function that you must call with the application's context before you call any of the other vault methods. 120 Sybase Unwired Platform . C:\Program Files\android-sdk-windows\tools.content. The name also cannot be empty or null. If it does. creates the actual encryption key that protects the data in the vault. this method throws an exception with error code INVALID_ARG. salt – the encryption salt value for this DataVault. you can immediately call the "set" methods for the values you want to change.init(oContext). This is the password needed for unlocking the vault. Developer Guide: Android Object API Applications 121 . and after creation. • • Returns Returns the newly created instance of the DataVault with the provided ID. This value. Syntax public static DataVault createVault( String name. this method throws an exception. Examples • Initialize DataVault. A newly created vault is in the unlocked state. The returned DataVault is in the unlocked state with default configuration values. String password.Client Object API Usage Returns None. If null is passed. This method also assigns a password and salt value to the vault. the vault is referenced and accessed by that name. a DataVaultException is thrown with the reason ALREADY_EXISTS. A unique name is assigned. combined with the password. This name is effectively the primary key for looking up DataVault instances on the device. createVault Creates a new secure store (a vault). so it cannot use the same name as any existing instance. To change the default configuration values. a default password is computed and used. If a vault already exists with the same name. String salt ) Parameters • name – an arbitrary name for a DataVault instance on this device. If null is passed. If a vault with the same name already exists. a default salt is computed and used. password – the initial encryption password for this DataVault. createVault("myVault".vaultExists("myVault")) { DataVault.deleteVault("myVault"). Returns Returns true if the vault exists. } getVault Retrieves a vault. if (!DataVault. DataVault vault = null. } vaultExists Tests whether the specified vault exists. if (DataVault. Syntax public static boolean vaultExists(String name) Parameters • name – the vault name. deletes it.vaultExists("myVault")) { vault = DataVault.Client Object API Usage Examples • Create a data vault – creates a new data vault called myVault. Syntax public static DataVault getVault(String name) Parameters • – the vault name. 122 Sybase Unwired Platform . "salt"). } else { vault = DataVault.getVault("myVault"). "password". Examples • Check if a data vault exists – checks if a data vault called myVault exists. and if so. otherwise returns false. Client Object API Usage Returns getVault returns a DataVault instance. If the vault does not exist, a DataVaultException is thrown. deleteVault Deletes the specified vault from on-device storage. If the vault does not exist, this method throws an exception. The vault need not be in the unlocked state, and can be deleted even if the password is unknown. Syntax public static void deleteVault(String name) Parameters • name – the vault name. Examples • Delete a data vault – deletes a data vault called myVault. if (DataVault.vaultExists("myVault")) { DataVault.deleteVault("myVault"); } getDataNames Retrieves information about the data names stored in the vault. The application can pass the data names to getValue or getString to retrieve the data values. Syntax public abstract DataVault.DVDataName[] getDataNames() Parameters None. Returns Returns a DVPasswordPolicy object, as an array of DVDataName structure objects. Examples • Get data names // Call getDataNames to retrieve all stored element names from our data vault. Developer Guide: Android Object API Applications 123 Client Object API Usage DataVault.DVDataName[] dataNameArray = oDataVault.getDataNames(); for ( int i = 0; i < dataNameArray.length; i++ ) { if ( dataNameArray[i].iType == DataVault.DV_DATA_TYPE_STRING ) { String thisStringValue = oDataVault.getString( dataNameArray[i].sName ); } else { byte[] thisBinaryValue = oDataVault.getValue( dataNameArray[i].sName ); } } setPasswordPolicy Stores the password policy and applies it when changePassword is called, or when validating the password in the unlock method. If the application has not set a password policy using this method, the data vault does not validate the password in the createVault or changePassword methods. An exception is thrown if there is any invalid (negative) value in the passwordPolicy object. Syntax public abstract void setPasswordPolicy(DataVault.DVPasswordPolicy oPasswordPolicy) Parameters • oPasswordPolicy – the password policy constraints. Examples • Set a password policy // SetPasswordPolicy() locks the vault to ensure the old password // conforms to the new password policy settings. oDataVault.setPasswordPolicy( oPasswordPolicy ); 124 Sybase Unwired Platform Client Object API Usage Password Policy Structure A structure defines the policy used to generate the password. Table 1. Password Policy Structure Name defaultPasswordAllowed Type Boolean Description Indicates if client application is allowed to use default password for the data Vault. If this is set to TRUE and if client application uses default password then minLength, hasDigits, hasUpper, hasLower and hasSpecial parameters in the policy are ignored. The minimum length of the password. Indicates if the password must contain digits. Indicates if the password must contain uppercase characters. Indicates if the password must contain lowercase characters. Indicates if the password must contain special characters. The set of special characters is: “~! @#$%^&*()-+”. Specifies password expiry days from the date of setting the password. 0 indicates no expiry. The minimum number of unique characters in the password. For example, if length is 5 and minUniqueChars is 4 then “aaate” or “ababa” would be invalid passwords. Instead, “aaord” would be a valid password. minimumLength Integer hasDigits Boolean hasUpper Boolean hasLower Boolean hasSpecial Boolean expirationDays Integer minUniqueChars Integer Developer Guide: Android Object API Applications 125 PROP_DEF_PWDPOLICY_DEFAULT_PASSWORD_ALLOWED – Boolean property with a default value of false. Indicates if a password policy is enabled by the administrator. • • PROP_DEF_PWDPOLICY_ENABLED – Boolean property with a default value of false. PROP_DEF_PWDPOLICY_HAS_DIGITS – Boolean property with a default value of false. 0 indicates no timeout. PROP_DEF_PWDPOLICY_HAS_LOWER – Boolean property with a default value of false. The default values are used by the data vault when no policy is configured. The application must set the password policy for the data vault with the administrative (or alternative) settings.Client Object API Usage Name lockTimeout Type Integer Description The timeout value (in seconds) after which the vault will be locked from the unlock time. • • • • • 126 Sybase Unwired Platform . The defaults are also used in Sybase Control Center in the default template. PROP_DEF_PWDPOLICY_MIN_LENGTH – Integer property with a default value of 0. Indicates if the password must contain at least one lowercase character. This value overrides the value set by setLockTimeout method. PROP_DEF_PWDPOLICY_HAS_UPPER – Boolean property with a default value of false. This value overrides the value set by the setRetryLimit method. A special character is a character in this set “~!@#$%^&*()-+”. retryLimit Integer Settings for Password Policy The client applications uses these settings to fill the PasswordPolicy structure. Defines the minimum length for the password. Note: Setting the password policy locks the vault. 0 indicates no retry limit. Indicates if the password must contain at least one special character. The number of failed unlock attempts after which data vault is deleted. The Sybase Unwired Platform administrator can modify these settings through Sybase Control Center. Indicates if the password must contain digits. The password policy is enforced when unlock is called (because the password is not saved. Indicates if the client application is allowed to use the default password for the data vault. Indicates if the password must contain at least one uppercase character. calling unlock is the only time that the policy can be evaluated). PROP_DEF_PWDPOLICY_HAS_SPECIAL – Boolean property with a default value of false. Specifies the number of days in which password will expire from the date of setting the password. Password Errors Name PASSWORD_REQUIRED Value 50 Description Indicates that a blank or null password was used when the password policy does not allow default password. Indicates that the password length is less than the required minimum. if minimum length is 5 and minUniqueChars is 4 then “aaate” or “ababa” would be invalid passwords. Specifies the number of failed unlock attempts after which data vault is deleted. 0 indicates no retry limit. PASSWORD_UNDER_MIN_LENGTH 51 PASSWORD_REQUIRES_DIGIT PASSWORD_REQUIRES_UPPER 52 53 PASSWORD_REQUIRES_LOWER 54 PASSWORD_REQUIRES_SPECIAL 55 Developer Guide: Android Object API Applications 127 . 0 indicates no timeout. For example. • • • Password Errors Password policy violations cause exceptions to be thrown. Indicates that the password does not contain lower case characters. Indicates that the password does not contain one of these special characters: ~!@#$%^&*()-+. “aaord” would be a valid password. Specifies minimum number of unique characters in the password. Indicates that the password does not contain upper case characters. PROP_DEF_PWDPOLICY_RETRY_LIMIT – Integer property with a default value of 0. Table 2. Password expiration is checked only when the vault is unlocked. PROP_DEF_PWDPOLICY_MIN_UNIQUE_CHARS – Integer property with a default value of 0.Client Object API Usage • PROP_DEF_PWDPOLICY_EXPIRATION_DAYS – Integer property with a default value of 0. PROP_DEF_PWDPOLICY_LOCK_TIMEOUT – Integer property with a default value of 0. Indicates that the password does not contain digits. Instead. Specifies timeout value (in seconds) after which the vault is locked from the unlock time. Indicates that the password has been in use longer than the number of configured expiration days. PASSWORD_EXPIRED 57 getPasswordPolicy Retrieves the password policy set by setPasswordPolicy. isDefaultPasswordUsed Checks whether the default password is used by the vault.DVPasswordPolicy oCurrentPolicy = oDataVault.DVPasswordPolicy getPasswordPolicy() Parameters None. Syntax public boolean isDefaultPasswordUsed() 128 Sybase Unwired Platform .Client Object API Usage Name PASSWORD_UNDER_MIN_UNIQUE Value 56 Description Indicates that the password contains fewer than the minimum required number of unique characters. Returns Returns a passwordPolicy structure that contains the policy set by setPasswordPolicy. Syntax public abstract DataVault. Returns a DVPasswordPolicy object with the default values if no password policy is set. Examples • Get the current password policy // Call getPasswordPolicy() to return the current password policy settings. Use this method once the DataVault is unlocked. DataVault. Use this method once the DataVault is unlocked.getPasswordPolicy(). Syntax public void lock() Examples • Locks the data vault – prevents changing the vaults properties or stored content. This code example lacks exception handling. you must unlock it before changing the vault’s properties or storing anything in it. Once a vault is locked.lock(). lock has no effect. boolean isDefaultPasswordUsed = oDataVault. see Developer Guide: Android Object API Applications> Client Object API Usage > Security APIs > DataVault > Code Sample.Client Object API Usage Returns Returns true false Indicates Both the default password and the default salt are used to encrypt the vault. isLocked Checks whether the vault is locked. lock Locks the vault. Either the default password or the default salt are not used to encrypt the vault. Syntax public boolean isLocked() Developer Guide: Android Object API Applications 129 . If the vault is already locked. For a code example that includes exception handling. vault.isDefaultPasswordUsed(). Examples • Check if default password used // Call isDefaultPasswordused() to see if we are using an automatically // generated password (which we are). Client Object API Usage Returns Returns true false Indicates The vault is locked. If null is passed. This value may be an application-specific constant. an IncompatiblePassword exception is thrown. Returns If an incorrect password or salt is used. if (vault. If null is passed. "salt"). Unlock the vault before changing the its properties or storing anything in it.isLocked()) { vault. this method throws an exception.unlock("password". This value. If the number of unsuccessful attempts exceeds the retry limit. a DataVaultException is thrown with the reason INVALID_PASSWORD. a default password is computed and used. Examples • Unlocks the data vault – once the vault is unlocked. The vault is unlocked. combined with the password. In that case. unlock Unlocks the vault. you can change its properties and stored content. String salt) Parameters • • password – the encryption password for this DataVault. The password is validated against the password policy if it has been set using setPasswordPolicy. Syntax public void unlock(String password. call changePassword to set a new password that is compatible with the password policy. salt – the encryption salt value for this DataVault. a default salt is computed and used. } 130 Sybase Unwired Platform . If the password is not compatible with the password policy. the vault is deleted. creates the actual encryption key that protects the data in the vault. If the incorrect password or salt is used. An exception is thrown if the vault is locked when this method is called. The finally clause in the try/catch block ensures that the vault ends in a secure state even if an exception occurs.Client Object API Usage setString Stores a string object in the vault. string teststring = "ABCDEFabcdef". try { vault. An exception is thrown if the vault is locked when this method is called. } finally { vault. Syntax public String getString(String name) Parameters • name – the name associated with the string object to be retrieved.println("Exception: " + e. teststring). "salt"). } getString Retrieves a string value from the vault.lock(). Developer Guide: Android Object API Applications 131 .setString("testString".toString()).out. Examples • Set a string value – creates a test string. value – the string object to store in the vault. unlocks the vault. Syntax Parameters • • name – the name associated with the string object to be stored. and sets a string value associated with the name "testString" in the vault. } catch (DataVaultException e) { System.unlock("password". vault. vault. 132 Sybase Unwired Platform . associated with the specified name. 4. 2. An exception is thrown if the vault is locked when this method is called. The finally clause in the try/catch block ensures that the vault ends in a secure state even if an exception occurs. The finally clause in the try/catch block ensures that the vault ends in a secure state even if an exception occurs. } catch (DataVaultException e) { System. 3. 5}).toString()).unlock("password". byte[] value ) Parameters • • name – the name associated with the binary object to be stored. Examples • Set a binary value – unlocks the vault and stores a binary value associated with the name "testValue" in the vault. new byte[] { 1.setValue("testValue". value – the binary object to store in the vault. Examples • Get a string value – unlocks the vault and retrieves a string value associated with the name "testString" in the vault. Syntax public void setValue( string name.getString("testString"). "salt"). } setValue Stores a binary object in the vault.out.println("Exception: " + e. try { vault. } finally { vault. string retrievedstring = vault.lock().unlock("password". from the vault. "salt"). try { vault.Client Object API Usage Returns Returns a string data value. The finally clause in the try/catch block ensures that the vault ends in a secure state even if an exception occurs. } getValue Retrieves a binary object from the vault. Examples • Get a binary value – unlocks the vault and retrieves a binary value associated with the name "testValue" in the vault.unlock("password".Client Object API Usage } catch (DataVaultException e) { System. byte[] retrievedvalue = vault.lock(). An exception is thrown if the vault is locked when this method is called.println("Exception: " + e.out. } finally { vault.toString()). "salt"). Syntax public byte[] getValue(string name) Parameters • name – the name associated with the binary object to be retrieved. Returns Returns a binary data value.lock(). associated with the specified name. } finally { vault.out.toString()). try { vault. } catch (DataVaultException e) { System.getValue("testValue").println("Exception: " + e. from the vault. } Developer Guide: Android Object API Applications 133 . println("Exception: " + e. newSalt – the new encryption salt value. Syntax Parameters • • newPassword – the new password. } 134 Sybase Unwired Platform . Use this method when the vault is unlocked. an exception is thrown. "newSalt"). "salt"). Syntax public static void deleteValue(String name) Parameters • name – the name of the value to be deleted.out. changePassword (two parameters) Changes the password for the vault. } finally { vault.toString()). Examples • Change the password for a data vault – changes the password to "newPassword". } catch (DataVaultException e) { System. The finally clause in the try/catch block ensures that the vault ends in a secure state even if an exception occurs. If the vault is locked or the new password is empty.deleteValue("myValue").lock(). Examples • Delete a value – deletes a value called myValue.unlock("password". DataVault. Modifies all name/value pairs in the vault to be encrypted with a new password/salt. try { vault.changePassword("newPassword".Client Object API Usage deleteValue Deletes the specified value. vault. combined with the password. creates the actual encryption key that protects the data in the vault. a default password is computed and used. Examples • Change the password for a data vault // Call changePassword with four parameters. currentSalt – the current encryption salt value for this data vault. This value.changePassword( null. string sNewSalt) Parameters • • • • currentPassword – the current encryption password for this data vault. // Pass null for oldSalt and oldPassword if the defaults were used. This value may be an application-specific constant. a default password is computed and used. even if the vault is locked. "password!1A". "saltD#ddg#k05%gnd[!1A" ). public void testFunctionality(Context oContext) { try { DataVault oDataVault = null. Developer Guide: Android Object API Applications 135 . If a null value is passed. Code Sample Create a data vault for encrypted storage of application data.Client Object API Usage changePassword (four parameters) Changes the password for the vault. string sCurrentSalt. If a null value is passed. If a null value is passed. If the current password is not valid an InvalidPassword exception is thrown. newSalt – the new encryption salt value for this data vault. newPassword – the new encryption password for this data vault. If a null value is passed. null. Syntax public abstract void changePassword(string sCurrentPassword. uses the current password to unlock the vault. and changes the password of the vault to a new password. oDataVault. a default password is computed and used. If the new password is not compatible with the password policy set in setPasswordPolicy then an IncompatiblePassword exception is thrown. string sNewPassword. a default password is computed and used. Use this method when the vault is locked This overloaded method ensures the new password is compatible with the password policy. setHasSpecial( true ). DataVault.getVault( "DataVaultExample" ). // We are now locked and need to unlock before we can access the vault. oPasswordPolicy. "saltD#ddg#k05%gnd[!1A" ). // Call getPasswordPolicy() to return the current password policy settings. DataVault. oPasswordPolicy.Client Object API Usage DataVault.unlock( "password!1A". oDataVault. oDataVault.getRetryLimit().createVault( "DataVaultExample".DVPasswordPolicy oCurrentPolicy = oDataVault.setPasswordPolicy( oPasswordPolicy ).getLockTimeout(). // Call setString() by giving it a name:value pair to encrypt and persist // a string data type within your dataVault.DVPasswordPolicy oPasswordPolicy = new DataVault. oPasswordPolicy. int iTimeout = oDataVault.setHasUpper( true ).setRetryLimit( 20 ). This allows you to set the timeout of the vault in seconds oDataVault. int iRetryLimit = oDataVault. then get it by calling getVault() // Else create this new dataVault by calling createVault() if ( DataVault. "stringValue" ). The passwordPolicy also includes the retryLimit and LockTimeout that we set above. "saltD#ddg#k05%gnd[!1A" ). // Call setPasswordPolicy(). oPasswordPolicy.vaultExists( "DataVaultExample" ) ) oDataVault = DataVault. This allows you to set the number of retries before the vault is destroyed oDataVault.setString( "stringName". oPasswordPolicy.setLockTimeout( 1500 ).setLockTimeout( 1600 ). // If this dataVault already exists. else oDataVault = DataVault. oPasswordPolicy. // Call setRetryLimit().setMinLength( 4 ). // Call setLockTimeout().setHasLower( true ).setExpirationDays( 20 ).setRetryLimit( 10 ). oDataVault.DVPasswordPolicy().init( oContext ). "password!1A". oPasswordPolicy.setHasDigits( true ).setMinUniqueChars( 3 ).getPasswordPolicy(). oPasswordPolicy. // SetPasswordPolicy() will always lock the vault to ensure the old password // conforms to the new password policy settings. oPasswordPolicy. oPasswordPolicy. // Call getString to retrieve the string we just stored in our 136 Sybase Unwired Platform .setIsDefaultPasswordAllowed (true). // If you pass null parameters as your new password or your new salt. binaryValue ). null. 2.getName() ). Vault must be unlocked. // Call setValue() by giving it a name:value pair to encrypt and persist // a binary data type within your dataVault. "password!1A". oDataVault. // Call changePassword with 4 parameters even if the vault is locked. oDataVault. 3.getDataNames().getValue( "binaryName" ).setValue( "binaryName". for ( int i = 0. 6.getValue( dataNameArray[i].getName() ). byte[] binaryValue = { 1.length. } else { byte[] thisBinaryValue = oDataVault.Client Object API Usage data vault! String storedStringValue = oDataVault.DV_DATA_TYPE_STRING ) { String thisStringValue = oDataVault. // it will generate a default password or default salt.getString( dataNameArray[i]. // Call getValue to retrieve the binary we just stored in our data vault! byte[] storedBinaryValue = oDataVault. Developer Guide: Android Object API Applications 137 . 4. oDataVault. DataVault.lock(). oDataVault. // Call getDataNames to retrieve all stored element names from our data vault.getString( "stringName" ).isDefaultPasswordUsed(). // Lock the vault. // Call isDefaultPasswordused() to see if we are using an automatically // generated password (which we are). // Here. we pass null for oldSalt and oldPassword because defaults were used. respectively.getType() == DataVault.changePassword( null. 5. 7 }. null ). boolean isDefaultPasswordUsed = oDataVault.changePassword( null. } } // Call changePassword with 2 parameters. i < dataNameArray.DVDataName[] dataNameArray = oDataVault. i++ ) { if ( dataNameArray[i]. The callback is executed in the thread that is performing the action (for example. if ( DataVault.Object entity) ). } } } Callback and Listener APIs The callback and listener APIs allow you to optionally register a callback handler and listen for device events. or both. the particular activity is already complete. application connection events. } catch( Throwable exception ) { exception. isDefaultPasswordUsed = oDataVault.CallbackHandler interface. override the particular callback that you are interested in (for example. // Call isDefaultPasswordused() and we will see that the default password is NOT used anymore. } finally { try { // Because this is a test example. 138 Sybase Unwired Platform . // This means we will forever lose all data we persisted in our data vault. } catch(Throwable t) { t. A default callback handler is provided. See also • Setting Up Callbacks on page 35 CallbackHandler API The CallbackHandler interface is invoked when any database event occurs. void onReplayFailure(java. we will delete our vault at the end. When you receive the callback.persistence. and package synchronize and replay events. In your handler.lang. replay).deleteVault( "DataVaultExample" ).Client Object API Usage "saltD#ddg#k05%gnd[!1A" ). you must register a CallBackHandler with the generated database class.isDefaultPasswordUsed().printStackTrace().sybase. which basically does nothing. You can create a handler by extending the DefaultCallbackHandler class or by implementing the com. the entity class.vaultExists( "DataVaultExample" ) ) DataVault. You should implement a custom CallbackHandler to register important events. To receive callbacks for database changes. The callback is invoked on the thread that is processing the event.printStackTrace(). Both CallbackHandlers registered for the MBO class of the entity and Package DB will be invoked. 2. Note: Only the CallbackHandler registered for package DB is invoked. However. Parameters: • entity – the Mobile Business Object that was just imported. Developers are encouraged to wait until the next onTransactionCommit() is invoked. then to read from the database to obtain the updated data. void onLoginSuccess() This method is invoked when login succeeds for a beginOnlineLogin call. Note: Only the CallbackHandler registered for package DB will be invoked.Client Object API Usage Table 3.Object entity) Description This method is invoked when an import message is successfully applied to the local database.lang. Note: 1. void onLoginFailure() This method will be invoked when login failed for a beginOnlineLogin call. it is not committed. One message from server may have multiple import entities and they would be committed in one transaction for the whole message. Stale data may be read from the database at this time before commit of the whole message. Callbacks in the CallbackHandler Interface Callback void onImport(java. Developer Guide: Android Object API Applications 139 . Parameters: • entity – the Mobile Business Object to replay.Object entity) fails.Client Object API Usage Callback Description This method is invoked when a replay request void onReplayFailure(java. Note: CallbackHandlers registered for both the MBO class of the entity and the Package DB are invoked. 140 Sybase Unwired Platform .lang. You can use the Change Log API to find records that occur after the synchronization. onReplaySuccess is an MBO object instance that contains the data prior to the synchronization.Object entity) fails.Object entity) succeeds. This method is invoked when a back end search void onSearchSuccess(java.lang. Parameters: • entity – the back-end search object. Note: CallbackHandlers registered for both the MBO class of the entity and the Package DB are invoked. Parameters: • entity – the Mobile Business Object to replay. Note: CallbackHandlers registered for both the MBO class of the entity and the Package DB are invoked. This method is invoked when a replay request void onReplaySuccess(java.lang.Object entity) succeeds. Parameters: • entity – the back-end search object. Note: CallbackHandlers registered for both the MBO class of the entity and the Package DB are invoked. This method is invoked when a back-end search void onSearchFailure(java.lang. STARTING_ON_NOTIFICATION The return value has no effect if the status is not in the above list. Developer Guide: Android Object API Applications 141 . context – the synchronization context. Note: Only the CallbackHandler registered for the Package DB is invoked.ASYNC_REPLAY_COMPLETED SynchronizationStatus.STARTING SynchronizationStatus. Parameters: • • groups – a list of synchronization groups.CONTINUE or Synchronization. context. void onSubscribeSuccess() This method is invoked when subscribe succeeds.CANCEL. int onSynchronize(GenericList<SynchronizationGroup> groups.Status. SynchronizationContext context) This method is invoked at different stages of the synchronization. • • • SynchronizationStatus. specifies the stage of the synchronization. This method is called by the database class synchronize or beginSynchronize methods when the client initiates a synchronization. the synchronize is cancelled if the status of the synchronization context is one of the following. The status of the synchronization context. and is called again when the server responds to the client that synchronization has finished.Client Object API Usage Callback void onSubscribeFailure() Description This method is invoked when subscribe fails. or that synchronization failed. If SynchronizationAction.CANCEL is returned. Note: CallbackHandlers registered for both the MBO class of the entity and the Package DB are invoked. Returns: Either SynchronizationAction. Note: Only the CallbackHandler registered for the Package DB is invoked.This method is invoked when resume subscription fails. void onUnsubscribeFailure() This method is invoked when unsubscribe fails. void onUnsubscribeSuccess() This method is invoked when unsubscribe succeeds.This method is invoked when resume subscription succeeds. void onResumeSubscriptionSuc. Note: Only the CallbackHandler registered for the Package DB is invoked. 142 Sybase Unwired Platform . void onResumeSubscriptionFai. Note: Only the CallbackHandler registered for the Package DB is invoked. void onSuspendSubscriptionSuccess() This method is invoked when suspend subscription succeeds. cess() Note: Only the CallbackHandler registered for the Package DB is invoked. lure() Note: Only the CallbackHandler registered for the Package DB is invoked. Note: Only the CallbackHandler registered for the Package DB is invoked.Client Object API Usage Callback void onSuspendSubscriptionFailure() Description This method is invoked when suspend subscription fails. void onRecoverSuccess() This method is invoked when recover succeeds. Note: Only the CallbackHandler registered for the Package DB is invoked. void onTransactionCommit() This method is invoked after a message is processed and committed.Exception ex) Description This method is invoked when an exception occurs in the processing of a message. Parameters: • ex – the exception thrown when processing a message. so that the message is not retried. Note: In DefaultCallbackHandlers. Note: Only the CallbackHandler registered for the Package DB is invoked. void onResetSuccess() This method is invoked when all data is cleared by the reset.Client Object API Usage Callback void onMessageException(java. Developer Guide: Android Object API Applications 143 . or from a custom Callback method. The application developer has the option to implement a custom CallbackHandler that does not re-throw the exception.lang. based on exception types or other conditions. It only happens when an Exception was thrown when processing the message. void onTransactionRollback() This method is invoked after a message is rolled back. Note: Only the CallbackHandler registered for the Package DB is invoked. onMessageException re-throws the Exception so that the messaging layer can retry the message. Note: Only the CallbackHandler registered for the Package DB is invoked. Note: Only the CallbackHandler registered for the Package DB is invoked. void onRecoverFailure() This method is invoked when recover fails. This method is invoked before importing the void beforeImport(java.Object entity) specified entity. Only the callback handler registered with the package database class is invoked.lang. Note: Only the CallbackHandler registered for the Package DB is invoked. method – The method string from the message header. This method is for DOE-based applications only. Note: Only the CallbackHandler registered for the Package DB is invoked. void onMessageStart(int size. void onImportSuccess() This method is invoked when all data has been successfully imported. mbo – If this message is for a specific MBO. otherwise null. This method is called at the beginning of processing a message from the server. This method deletes all MBO data on the device. This code shows how to create and register a handler to receive callbacks: public class MyCallbackHandler extends DefaultCallbackHandler { // implementation } CallbackHandler handler = new MyCallbackHandler(). the name of the MBO. Parameters: • entity – the Mobile Business Object to be imported.Client Object API Usage Callback void onSubscriptionEnd() Description This method is invoked when a subscription is reregistered or unsubscribed. before the String method. 144 Sybase Unwired Platform . Parameters: • • • size – The size of the incoming message con- tent in bytes. Note: Only the CallbackHandler registered for the Package DB is invoked. String mbo). message transaction starts. Table 4. String er.Application instance to receive these callbacks.rejects HTTP communication with an error code. rorMessage. The possible device condition values are defined in the DeviceCondition class.sybase. You must register an ApplicationCallback implementation to your com.registerCallbackHandler(handler). HTTP server.possible registration status values are defined in the RegistrationStatus class. Callbacks in the ApplicationCallback Interface Callback Description Invoked when one or more application settings void onApplicationSettingsChanged(StringList nameList) have been changed by the server administration. void onConnectionStatusChanged(int connectionStatus. int errorCode. String errorMessage) Invoked when an HTTP communication server void onHttpCommunicationError(int errorCode.mobile. int errorCode. The void onRegistrationStatusChanged(int registrationSta. • • errorMessage – Error message returned by the HTTP server. tus. Developer Guide: Android Object API Applications 145 . The possible connection status values are defined in the ConnectionStatus class. code 403 for authorization failure. Invoked when a condition is detected on the mobile device that may be of interest to the application or the application user. String errorMessage) void onDeviceConditionChanged(int condition) Invoked when the connection status changes. For example: code 401 for authentication failure. httpHeaders – Response headers returned by the HTTP server. StringProperties • errorCode – Error code returned by the httpHeaders). ApplicationCallback API This callback interface is invoked by events of interest to a mobile application.Client Object API Usage <PkgName>DB. Invoked when the registration status changes. // or SUP101DB. the application can react accordingly to the state of the synchronization. such as a green image when the synchronization is in progress. the connection to which it is related. a red image if the synchronization fails. the client cannot update its screen as the status changes. Note: This topic is not applicable for DOE-based applications. Possible uses of objectSyncStatus method include changing form elements on the client screen to show synchronization progress. Create a listener that implements the SyncStatusListener interface.synchronize(listener). listener). SUP101DB. the objectSyncStatus method defined by the SyncStatusListener interface is called and is passed an ObjectSyncStatusData object. The ObjectSyncStatusData object contains information about the MBO being synchronized. If the method returns true. public interface SyncStatusListener { boolean objectSyncStatus(ObjectSyncStatusData statusData). if we want to synchronize all // synchronization groups As the application synchronization progresses. If a client runs synchronizations in a thread other than the primary user interface thread. and the current state of the synchronization process. By testing the State property of the ObjectSyncStatusData object and comparing it to the possible values in the SyncStatusState enumeration. SyncStatusListener listener = new MySyncListener(). and a gray image when the synchronization has completed successfully and disconnected from the server. The client must instruct the primary user interface thread to update the screen regarding the current synchronization status.synchronize("sync_group". the synchronization is aborted. Note: The objectSyncStatus method of SyncStatusListener is called and executed in the data synchronization thread.Client Object API Usage SyncStatusListener API You can implement a synchronization status listener to track synchronization progress. The method returns false to allow synchronization to continue. } public class MySyncListener implements SyncStatusListener { // implementation } Pass an instance of the listener to the synchronize methods. This is an example of SyncStatusListener implementation: public class SyncListener implements SyncStatusListener { 146 Sybase Unwired Platform . parameters. and through filtering query result sets. case SyncStatusState. use one of the static Object Query methods in the MBO class. arbitrary find.getSyncStatusState()) { case SyncStatusState. See also • Accessing MBO Data on page 45 • Object Queries on page 45 • Dynamic Queries on page 46 • MBOs with Complex Types on page 47 • Relationships on page 47 Retrieving Data from Mobile Business Objects You can retrieve data from mobile business objects through a variety of queries. } return false. including object queries.Client Object API Usage public boolean objectSyncStatus(ObjectSyncStatusData data) { switch (data. } } Query APIs The Query API allows you to retrieve data from mobile business objects. Developer Guide: Android Object API Applications 147 .APPLICATION_SYNC_ERROR: //implement your own UI indicator bar break. or a collection of objects that match the specified search criteria. Object Queries To retrieve data from a local database.APPLICATION_SYNC_DONE: //implement your own UI indicator bar break.. case SyncStatusState. You can also use the Query API to filter children MBOs of a parent MBO in a one to many relationship. and return types defined in Unwired WorkSpace. Object Query methods return either an object. Object Query methods are generated based on the object queries defined by the modeler in Unwired WorkSpace. to page data..SYNC_STARTING: //implement your own UI indicator bar break. case SyncStatusState. . and to retrieve a query result by filtering.SYNC_DONE: //implement your own UI indicator bar break. Object Query methods carry query names. findAll(10.findAll().Client Object API Usage The following examples demonstrate how to use the Object Query methods of the Customer MBO to retrieve data.sybase.fname = :firstName return type – Sybase. int take) com.sybase. This method retrieves all customers: public static com. Query and Related Classes The following classes define arbitrary search methods and filter conditions. Contains a method to combine test criteria using the logical operators AND. and provide methods for combining test criteria and dynamically querying result sets.sybase.* FROM Customer x WHERE x. Defines filter conditions for MBO attributes.sybase.collections. and NOT to create a compound filter. and data ordering information.GenericList<Customer> findByFirstName(String firstName) com.collections.collections.GenericList<Customer> findAll(int skip. Query and Related Classes Class Query Description Defines arbitrary search methods and can be composed of search conditions.sybase.GenericList<Customer> findAll() com.collections.collections.Collections. object/row state filter conditions.collections.GenericList The preceding Object Query results in this generated method: public static com. 5). Suppose the modeler defined the following Object Query for the Customer MBO in Unwired WorkSpace: • • • • name – findByFirstName parameter – String firstName query definition – SELECT x.GenericList<Customer> customers = Customer. OR. Table 5.GenericList<Customer> customers = Customer.sybase.GenericList<Customer> customers = Customer.findByFirstName("fname"). This method retrieves all customers in a certain page: public static com. AttributeTest CompositeTest 148 Sybase Unwired Platform . where "X. Used for paging. and join statements.fname.s. The arbitrary find method also lets the user specify a desired ordering of the results and object state criteria. Used for paging. object/row state filter conditions. Take – an integer specifying the maximum number of rows to return. The Query. The default value is false for entity types. Query query2 = new Query(). Query query1 = new Query().DISTINCT property lets you exclude duplicate entries from the result set. For example.c. TestCriteria You can construct a query SQL statement to query data from a local database.select("c. Skip – an integer specifying how many rows to skip. where.region"). A Query class is included in the client object API.s.lname.attr1 from MBO x".Client Object API Usage Class QueryResultSet Description Provides for querying a result set for the dynamic query API. Set the Query. "select x. You can create a TestCriteria object (in this example. Define these conditions by setting properties in a query: • • • • TestCriteria – criteria used to filter returned data. query2. You can also query across multiple tables (MBOs) when using the executeQuery API. SortCriteria – criteria used to order returned data.order_date. "c").Distinct property to true to exclude duplicate entries from the result set. SelectItem Column In addition queries support select. Arbitrary Find The arbitrary find method lets custom device applications dynamically build queries based on user input. query2. Used in a subquery to reference the outer query's attribute. AttributeTest) to filter results. query1.attr1" represents one SelectItem. The Query class is the single object passed to the arbitrary search methods and consists of search conditions.setDistinct(true).from("Customer". and its usage is optional for all other types. TestCriteria can be an AttributeTest or a CompositeTest. // // Convenience method for adding a join to the query // Detailed construction of the join criteria Developer Guide: Android Object API Applications 149 . and data ordering information. Defines the entry of a select query. AttributeTest ts = new AttributeTest(). v.add("3"). • • • • • • • • • • • • • • • • • • • • IS_NULL NOT_NULL EQUAL NOT_EQUAL LIKE NOT_LIKE LESS_THAN LESS_EQUAL GREATER_THAN GREATER_EQUAL CONTAINS STARTS_WITH ENDS_WITH NOT_START_WITH NOT_END_WITH NOT_CONTAIN IN NOT_IN EXISTS NOT_EXISTS For example.collections.setValue(v). AttributeTest test = new AttributeTest().Client Object API Usage query2. query2. v. the Java code shown below is equivalent to this SQL query: SELECT * from A where id in [1.setAttribute("id").collections. test. test. QueryResultSet qrs = SUP101DB.cust_id"). test.executeQuery(query2). and supports multiple conditions. 150 Sybase Unwired Platform .setAttribute("fname"). v.setOperator(AttributeTest.add("1").add("2"). "c. "s.sybase.sybase. ts.3] Query query = new Query(). "s". com.where(test).ObjectList v = new com. AttributeTest An AttributeTest defines a filter condition using an MBO attribute. ts.join("Sales_order".id".where(ts).ObjectList(). query.IN).2.setTestValue("Beth"). setValue(existQuery).setOperator(AttributeTest.add("lname". existQuery. For example. QueryResultSet qs = SUP101DB.setAlias("a"). query.ASCENDING). test1.from("AllType".id) Query query = new Query(). cl. test.setOperator(AttributeTest.setTestCriteria(aTest).select("c. existQuery. AttributeTest aTest = new AttributeTest(). cl.EQUAL).EQUAL).ASCENDING). aTest.id from AllType a where exists (select b.Client Object API Usage When using EXISTS and NOT_EXISTS.select("b.id"). AttributeTest test = new AttributeTest(). test.id = a. AttributeTest test1 = new AttributeTest(). Column cl = new Column(). "c"). SortCriteria SortCriteria defines a SortOrder.setSortCriteria(sort). query.id from AllType b where b. which contains an attribute name and an order type (ASCENDING or DESCENDING).id"). existQuery. SortCriteria sort = new SortCriteria().EXISTS). SortOrderType.where(test).where(test1).id"). query.from("Customer". c. query. query.setTestType(AttributeTest. aTest. Developer Guide: Android Object API Applications 151 . Query existQuery = new Query(). The query can reference an attribute value via its alias in the outer scope. query. SortOrderType. aTest.setAttribute("state").fname").setAttribute ("b. test1. "a"). query.from("AllType". sort.executeQuery(query).setTestValue("CA").setAttribute("id"). The Java code shown below is equivalent to this SQL query: SELECT a.select("a.setValue(cl). Query query = new Query(). the attribute name is not required in the AttributeTest. sort.add("fname".lname. "b"). test1. float. date. byte. decimal. Query query1 = new Query(). short. short. date. long. double If you use an unsupported type. float. you can use any of these aggregate functions: Aggregate Function COUNT MAX MIN SUM AVG Supported Datatypes integer string.findWithQuery(props).name) as minName"). int. Aggregate Functions You can use aggregate functions in dynamic queries. Consider using the Query object to limit the result set: Query props = new Query(). When using the Query. long. dateTime byte. retrieving up to 30. time. decimal.id). //other code for query1 query1. decimal. long.id. integer.000 records from the database may cause the custom client to fail and throw an OutOfMemoryException. use the Query. int.groupBy(groupByItem). double byte. binary. char.select(String) method. integer. integer. To group your results according to specific attributes. use: String groupByItem = ("c. a PersistenceException is thrown. int. short. props. long. decimal.name"). int. float. query1.setTake(5). double. time.setSkip(10).groupBy(String groupByItem) method. For example.Client Object API Usage Paging Data On low-memory devices. c. char. short. byte. integer. MIN(c. 152 Sybase Unwired Platform . props. binary.select("MAX(c. float. to group your results by ID and name. dateTime string. GenericList<Customer> customers = Customer. double. Grouping Results Apply grouping criteria to your results. Query query1 = new Query(). selected items. String alias) method.setValue("0").GREATER_EQUAL).TestCriteria) method for queries using groupBy.setAttribute("c.setValue("0"). ts..id FROM AllType b) AS a WHERE a.except(query2). For example.from(Query query.having(com.Client Object API Usage Filtering Results Specify test criteria for group queries.. query2. Subqueries Execute subqueries using clauses. . ts. . You can execute subqueries using the Query. the Java code shown below is equivalent to this SQL query: SELECT a.id").sybase.. query2.persistence. Concatenating Queries Concatenate two queries having the same selected items.where(ts).setOperator(AttributeTest. ts2. . "c"). query2. ts2.. AttributeTest ts2 = new AttributeTest().id attribute values that are greater than or equal to 0 using: Query query2 = new Query().id)"). AttributeTest ts = new AttributeTest(). . query2. You can specify how your results are filtered by using the Query. The Query class methods for concatenating queries are: • • • • union(Query) unionAll(Query) except(Query) intersect(Query) This example obtains the results from one query except for those results appearing in a second query: Query query1 = new Query().having(ts2).GREATER_EQUAL).id. //other code for query 2 Query query3 = query1. ts2.setOperator(AttributeTest.id")..from("AllType".setAttribute("c.select("c.groupBy("c. SUP101DB.id"). limit your AllType MBO's results to c. SUM(c..executeQuery(query3). //other code for query1 Query query2 = new Query()..id FROM (SELECT b. query2.. and attribute test values.id = 1 Developer Guide: Android Object API Applications 153 . ts. For example. For example.from("AllType".GenericList<com. selQuery.setValue(cl).setAttribute("a. Query subQuery2 = new Query(). id FROM AllType d Use this Java code: Query selQuery = new Query().collections.add(item).id").collections.Client Object API Usage Use this Java code: Query query1 = new Query(). "b").from("AllType".id"). query1.id) AS cn.setAlias("d").where(ttt).select("b.sybase.sybase.setValue(1). selQuery. ts. subQuery2. com.QueryResultSet qs = SUP101DB. "d"). item. AttributeTest ttt = new AttributeTest().from("AllType". item.executeQuery(query2).persistence.sybase.id"). query2. subQuery2.executeQuery(subQuery2). query2. item = new SelectItem().from(query1. "c").where(ts).setAttribute("id").GenericList<com. "a"). query1.sybase.add(item). Column cl = new Column(). Query query2 = new Query().GREATER_EQUAL).id").SelectIte m> selectItems = new com. cl. 154 Sybase Unwired Platform . You can use a subquery as the selected item of a query.setOperator(AttributeTest.sybase. cl.sybase. item.persistence. selQuery.setSelectItems(selectItems). com. query2. selectItems.persistence.QueryResultSet qs = SUP101DB. AttributeTest ts = new AttributeTest().select("a. SelectItem item = new SelectItem(). ttt. ts. the Java code shown below is equivalent to this SQL query: SELECT (SELECT count(1) FROM AllType c WHERE c. ttt.setQuery(selQuery).setAlias("d"). selectItems.SelectIte m>(). com.select("count(1)").persistence.setAttribute("id").setAttribute("c.id >= d.setAlias("cn"). item. Use the SelectItem to set selected items directly. ttt. AttributeTest. props. props.add(new AttributeTest("state".Client Object API Usage CompositeTest A CompositeTest combines multiple TestCriteria using the logical operators AND. SortOrder.add(new AttributeTest("state". OR.sybase.OR).OR). "Doe". sort. CompositeTest outerCompTest = new CompositeTest(). and NOT to create a compound filter. and Query to locate all customer objects based on particular criteria.add(innerCompTest). innerCompTest.add("fname". com.EQUAL)).setSkip(10). AttributeTest. props. //define the attribute based conditions //Users can pass in a string if they know the attribute name. R1 column name = attribute name. AttributeTest. innerCompTest. //set the Query object props.findWithQuery(props). "Jane".add(new AttributeTest("fname".ASCENDING). Note: "Order By" is not supported for a long varchar field. innerCompTest. Credit DESC Skip the first 10 and take 5 Query props = new Query().setSortCriteria(sort).GenericList<Customer> customers2 = Customer. • • • • FirstName = John AND LastName = Doe AND (State = CA OR State = NY) Customer is New OR Updated Ordered by LastName ASC.setOperator(CompositeTest.setTestCriteria(outerCompTest). AttributeTest. //define the ordering SortCriteria sort = new SortCriteria().add("lname".EQUAL)).EQUAL)). Developer Guide: Android Object API Applications 155 . outerCompTest.EQUAL)). outerCompTest. Complex Example This example shows the usage of CompositeTest. "NY". FirstName ASC.setOperator(CompositeTest.ASCENDING). SortCriteria. outerCompTest.collections. sort. "CA". CompositeTest innerCompTest = new CompositeTest().add(new AttributeTest("lname". outerCompTest. SortOrder.setTake(5). creating a Query.sybase.println(qrs.out.fname. The following example shows how to filter a result set and get values by taking data from two mobile business objects. A bidirectional relationship also allows the child MBO to access the associated parent MBO.region").sybase.print(".getString(3)).getStringByName("c.select("c. System.getSalesOrders(). filling in the criteria for the query.findById (101). System. GenericList<Sales_order> orders = customer.persistence.out. You can also use the Query class to filter the return MBO list data. System. and filtering the query results: com.cust_id ". System. "c").id"). System. at.Query query = new com. System.Query().out. 156 Sybase Unwired Platform .executeQuery(query). Customer customer = Customer.print(". Additionally.setTestValue("Devlin"). Assume there are two MBOs defined in Unwired Server. System.out. assume there is an association between Customers and Orders on the customer ID column. System.println(qrs.out."). while(qrs.lname.s.setTestCriteria(at).print(qrs.print(qrs. AttributeTest at = new AttributeTest(). query.persistence.getString(2)).").s.join("SalesOrder ". query.order_date.region")). The Orders application is parameterized to return order information for the customer ID. } Retrieving Relationship Data A relationship between two MBOs allows the parent MBO to access the associated MBO. System.out. One MBO is called Customer and contains a list of customer data records.out.getStringByName("s.out. "c.print(qrs.getString(4)). The second MBO is called SalesOrder and contains order information.").getString(1)).lname")).from("Customer ".getStringByName("c. QueryResultSet qrs = SUP101DB. at. "s".out.print("."). QueryResultSet is returned as a result of executing a query.Client Object API Usage QueryResultSet The QueryResultSet class provides for querying a result set from the dynamic query API.println(qrs. System.getStringByName("s.fname")).setAttribute("lname").out.order_date")).print(". System.out.out. " s.c.next()) { System.print(qrs. query. query.println(qrs. setTake(100).setSearchName("MySearch"). //submit search request to the server search. For example. which will be used as the search criteria BE_SEARCH_GETLIST searchParameters = new BE_SEARCH_GETLIST().setParameters(searchParameters). //Set up the search parameters . search. the generated client code contains a corresponding class file.sybase. Developer Guide: Android Object API Applications 157 .now()).Client Object API Usage Query props = new Query().setNamedQuery ("BE_SEARCH_GETLIST").setSearchTime(com. obtained as a result of executing a specific named query on the server.DateTimeUtil.java. //additional parameters if required. GenericList<Sales_order> orders = customer. the first step is to create a search MBO. Fill up the required fields for the MBO as follows: //any name as desired by the user.. For every named query on the server.. //… // other optional fields of search.afx.setSearchId(1). The attributes of the class represent the parameters for the query and can be set as follows.. BackendSearch search = new BackendSearch().. with the same name as the query. //the name of the query to be executed on the server [search setNamedQuery: [BackendSearch BE_SEARCH_GETLIST]]. search. search. The search MBO has other optional fields: search.getSalesOrdersFilterBy(props). search. //Now set the above as searchparameters in the MBO search..submitPending(). searchParameters. Back-end Search Backend search allows the client to operate on a subset of data. Search MBO Create Consider a named query on the server.setEntityType("ENTITY_TYPE_DETAILS"). // set query parameters . BE_SEARCH_GETLIST. To initiate a back-end search. //entity type for the result set (corresponds to the return type of the named query ) search. BE_SEARCH_GETLIST.setNAME_FIRST("John").util. and delete operations are based on the fill from attribute being set. You can get the search result notification from CallbackHandler. search. update.Client Object API Usage After some time the server sends a search failure or success message. update.setParameters(searchParameters).submitPending(). methods such as Save cannot be automatically generated. The results are saved into the back-end search results table on the device database.setNAME_FIRST(“Ron”). 158 Sybase Unwired Platform . or delete (CUD) operations create non-static instances of operations in the generated client-side objects. where there are multiple instances of create or update operations. Data on the server cannot be deleted using the search MBO and a call to submitPending will not propagate the delete message to the server. Operations in the model that are marked as create. determines whether to insert or update data to the local client-side database.searchResults(search). search. or delete operation that are mapped to the object’s attributes are handled internally by the client object API. search. and are not exposed. search. when called internally.update(). Persistence APIs The persistence APIs include operations and object state APIs. Search MBO Update searchParameters = new BE_SEARCH_GETLIST().delete(). Note: If the Sybase Unwired Platform object model defines one instance of a create operation and one instance of an update operation. and the results of the query.refresh(). In other situations. search. Search MBO Delete Delete on a search MBO will delete the search entity and result locally in the client database. See also • Manipulating Data on page 48 Operations APIs Mobile business object operations are performed on an MBO instance. and all operation parameters are mapped to the object’s attributes. Any parameters not mapped to the object’s attributes are left as parameters in the generated object API. searchParameters. then a Save method can be automatically generated which. Different MBO settings affect the operation methods. The result data can be retrieved as follows: GernericList<ENTITY_TYPE_DETAILS> searchResults = ENTITY_TYPE_DETAILS. The code examples for create. Any parameters in the create. update. set the MBO attributes.submitPending(). get an instance of the MBO. To propagate the changes to the server. To propagate the changes to the server.update().submitPending(). then call the save() or create() operation. Customer cust = new Customer(). or call submitPending() on the changed child MBO: Developer Guide: Android Object API Applications 159 .setCompany_name( "Sybase" ). call submitPending() on the parent MBO.// or cust. This method in the LocalKeyGenerator class generates a unique ID for the package on the local device: public static long generateId() This method in the KeyGenerator class generates a unique ID for the same package across all devices: public static long generateId() Create Operation The create operation allows the client to create a new record in the local database. SUP101DB.save(). // or SUP101DB. To execute a create operation on an MBO.synchronize (String synchronizationGroup) Update Operation The update operation updates a record in the local database on the device. cust. Customer cust = Customer. then call either the save() or update() operation. // or SUP101DB. and set the MBO attributes.save().setCompany_name("Sybase").setFname("supAdmin").setPhone("777-8888").setFname ( "supAdmin" ). call submitPending. cust. cust.synchronize (String synchronizationGroup) To update multiple MBOs in a relationship. cust.create(). cust.synchronize().setPhone( "777-8888" ).findById(101).Client Object API Usage See also • Creating. Updating. To execute update operations on an MBO.synchronize(). // or cust. and Deleting MBO Records on page 49 • Other Operations on page 50 generateId You can use the generateId methods in the LocalKeyGenerator and KeyGenerator classes to generate an ID when creating a new object for which you require a primary key or surrogate key. cust. create a new MBO instance. SUP101DB. cust. cust. call submitPending. cust. cust. set the MBO attributes.synchronize(). SUP101DB.getSalesOrders(). To invoke the Other operation.currentTimeMillis())).getByIndex(0). cust. For example: 160 Sybase Unwired Platform . For MBOs in a relationship. order.submitPending(). In the case of an existing record. Delete Operation The delete operation allows the client to delete a new record in the local database. cust. cust.findById(101). GenericList<Sales_order> orders = cust. order. create an instance of CustomerOtherOperation. or delete operation.delete(). the save operation creates a new record. with parameters "P1" (string).collections. then call the delete operation. update.setOrder_date(new Date(System. This results in a CustomerOtherOperation class being generated. //Insert a new customer Customer cust = new Customer().Client Object API Usage Customer cust = Customer. Suppose the Customer MBO has an Other operation "other".getSalesOrders().save(). with "P1". // or SUP101DB. "P2" (int). An Other operation class is generated for each operation in the MBO that is not a create. update. a save operation calls the update operation. com. Sales_order order = orders.synchronize (String synchronizationGroup) Save Operation The save operation saves a record to the local database. "P2". and "P3" (date).findById(101). get an instance of the MBO.item(0).save(). perform a delete as follows: Customer cust = Customer. or delete operations are called "other" operations. SalesOrder order = (SalesOrder)orders. //Update an existing customer Customer cust = Customer. To propagate the changes to the server. and set the correct operation parameters for its attributes.save().delete().findById(101). and "P3" as its attributes.findById(101). Other Operation Operations other than create. call submitPending. Customer cust = Customer. cust. To execute delete operations on an MBO. order.submitPending(). cust. If a record does not exist.sybase.ObjectList orders = cust. customer.Date()). // or SUP101DB.setSales_rep(102). order.util. SalesOrder order = new SalesOrder().setRegion("Eastern"). Cascade operations allow a single synchronization to execute a chain of related CUD operations.add(order). order. Multilevel Insert Consider creating a Customer and a new Customer order at the same time on the client side. first find the customer. order. order.currentTimeMillis())).save(). customer.submitPending().setCustomer(customer).Date()). customer.setP3(new Date(System.add(order). //Must submit parent . then create a sales order with the customer ID retrieved: Customer customer = Customer. See the Sybase Unwired Platform online documentation for information on defining relationships that support cascading (composite) operations. //Both the child and parent MBO must call save() order. other.setOrder_date(new java. order.setP2(2). customer. customer.Client Object API Usage CustomerOtherOperation other = new CustomerOtherOperation().synchronize(). other.setSales_rep(102).synchronize (String synchronizationGroup) Cascade Operations Composite relationships are cascaded. and for specific multilevel insert requirements.setOrder_date(new java. Multi-level insert is a special case for cascade operations. other. Multilevel insert allows a single synchronization to execute a chain of related insert operations. Developer Guide: Android Object API Applications 161 .getOrders(). order. SUP101DB. other.findById(101). order. where the SalesOrder has a reference to the new Customer identifier.setPhone(“777-8888”)..save().save(). To insert an order for an existing customer.setP1("somevalue"). other.util.submitPending().setRegion("Eastern").. SalesOrder order = new SalesOrder(). creating parent and children objects. order. order.getSalesOrders().setFname(“firstName”).setLname(“lastName”). customer.setCustomer(customer). The following example demonstrates a multilevel insert: Customer customer = new Customer(). customer.save(). LocalTransaction tx = SUP101DB.submitPending().rollback(). objects. • • • cancelPending – cancels the previous create.setPhone("8005551212").beginTransaction().save(). } Complex Attribute Types Some back-end datasources require complex types to be passed in as input parameters. and object lists. • Customer customer = Customer.findById(101). submitPendingOperations – submits all the pending records for the entity to the Unwired Server. submitPending – submits the operation so that it can be replayed on the Unwired Server.sybase. long. or delete operations on the MBO. and delete). if (errorHappened) { customer. } else { customer.submitPending().commit().findByPrimaryKey(100). } catch (Exception e) { tx. try { customer. update. or string).Client Object API Usage Pending Operation You can manage the pending state. The input parameters can be any of the allowed attribute types. } You can group multiple operations into a single transaction for improved performance: // load the customer MBO with customer ID 100 Customer customer = Customer. // use one transaction to do save and submitPending com. including primitive lists. A request is sent to the Unwired Server during a synchronization. It cannot cancel submitted operations. and make use of the basic database operations (create. The MBO examples have attributes that are primitive types (such as int. cancelPendingOperations – cancels all the pending records for the entity. This method internally invokes the submitPending method on each of the pending records. This method internally invokes the cancelPending method on each of the pending records.persistence. 162 Sybase Unwired Platform . update. customer. // Change phone number of that customer customer.cancelPending(). tx. newCase. newCase. newCase.setTimeZone("GMT").setSubmitted_By("Demo").java. but the principles are similar. The generated code for the create operation is: public void create(complex. CA").String pending.setUserName("Demo").lang. newCase. authen. authen. authen. configuration.lang.setStatus("Assigned"). and so on. including one named _HEADER_ that is a structure datatype named AuthenticationInfo.AuthenticationInfo _HEADER_.java.setAuthentication("").").setCase_Type("Incident").setPhone_Number("#0861023242526").setCategory("Networking").setPassword(""). Developer Guide: Android Object API Applications 163 .setSummary("MarkHellous was here Fix it.java. newCase.setDescription("A new help desk case. along with the other operation parameters.String escalated.setSource("Requester"). newCase.Client Object API Usage Passing Structures to Operations An Unwired WorkSpace project includes an example MBO that is bound to a Web service data source that includes a create operation that takes a structure as an operation parameter.setOffice("#3 Sybase Drive"). authen."). newCase.setRequester_Login_Name("Demo"). defined as: AuthenticationInfo userName: String password: String authentication: String locale: String timeZone: String Structures are implemented as classes. SimpleCaseList newCase = new SimpleCaseList().java.String hotlist. newCase. newCase. newCase. newCase.setDepartment("Marketing"). MBOs differ depending on the data source.setRegion("USA").lang. newCase.setItem("Configuration"). newCase.String orig_Submitter. newCase.setPriority("High").String workLog) This example demonstrates how to initialize the AuthenticationInfo class instance and pass it.lang. The SimpleCaseList MBO contains a create operation that has a number of parameters. to the create operation: AuthenticationInfo authen = new AuthenticationInfo().lang. so the parameter _HEADER_ is an instance of the AuthenticationInfo class.setRequest_Urgency("High").setRequester_Name("Demo").setLocale("EN_US"). authen.java. newCase.setSite("25 Bay St. newCase. newCase. Mountain View. and one of the following is true: • • • The entity has not yet been submitted to the server with a replay request.Timestamp(System. Returns true if this entity has been newly created in the client database. but the change has not yet been saved to the client database. Entity State Management The object state APIs provide methods for returning information about entities in the database. but has not yet been created in the client database. but the server has not finished processing the request.sql. All entities that support pending state have the following attributes: Name isNew isCreated Type boolean boolean Description Returns true if this entity is new.currentTimeMillis())). isDirty boolean Returns true if this entity has been changed in memory. The entity has been submitted to the server. "Other". isDeleted boolean 164 Sybase Unwired Platform .submitPending(). newCase. Returns true if this entity was loaded from the database and subsequently deleted. "Demo". "worklog").create(authen. newCase. newCase.setCreate_Time(new java. "Other".Client Object API Usage newCase.setType("Access to Files/Drives"). The server rejected the replay request (replayFailure message received). "false". Object State APIs The object state APIs provide methods for returning information about the state of an entity in an application. The server rejected the replay request (replayFailure message received). 'U' (update). this attribute's value is 'C' (create). If pending is false. if the value of replayCounter is greater than replayPending). Returns a long value. The entity has been submitted to the server. the value of replayCounter is copied to replayFailure. pending boolean Returns true for any row that represents a pending create. and one of the following is true: • • • The entity has not yet been submitted to the server with a replay request. If pending is true. 'D' (delete). pendingChange char replayCounter long replayPending long replayFailure long Developer Guide: Android Object API Applications 165 . and replayPending is set to 0. or delete operation.Client Object API Usage Name isUpdated Type boolean Description Returns true if this entity has been updated or changed in the database. but the server has not finished processing the request. When a pending row is submitted to the server. Returns a long value that is updated each time a row is created or modified by the client. update or delete operations). This value is a unique value obtained from KeyGenerator. Returns a long value. or a row that has cascading children with a pending operation. the value of replayCounter is copied to replayPending. update. This allows the client code to detect if a row has been changed since it was submitted to the server (that is.generateID method. When the server responds with a replayFailure message for a row that was submitted to the server. or 'P' (to indicate that this MBO is a parent in a cascading relationship for one or more pending child objects. this attribute's value is 'N'. Note that the value increases every time it is retrieved. but this MBO itself has no pending create. this flag clears. The replayCounter value that gets sent to the Unwired Server is the value in the database before you call submitPending. The values that change between different states appear in bold. The last two entries in the table are two possible results from the operation. only one of these results can occur for a replay request. Once you save the MBO. Note these entity behaviors: • • The isDirty flag is set if the entity changes in memory but is not yet written to the database. before any changes isNew=false are made.Client Object API Usage Entity State Example Shows how the values of the entities that support pending state change at different stages during the MBO update process. After a successful replay. isCreated=false isDirty=false isDeleted=false isUpdated=false pending=false pendingChange='N' replayCounter=33422977 replayPending=0 replayFailure=0 166 Sybase Unwired Platform . that value is imported from the Unwired Server. Description Flags/Values • After reading from the database. Client Object API Usage Description Flags/Values One or more attributes are changed. isNew=false isCreated=false isDirty=false isDeleted=false isUpdated=true pending=true pendingChange='U' replayCounter=33424979 replayPending=0 replayFailure=0 Developer Guide: Android Object API Applications 167 .save()[entity save] or entity.update()[entity update] is called. but changes not isNew=false saved. isCreated=false isDirty=true isDeleted=false isUpdated=false pending=false pendingChange='N' replayCounter=33422977 replayPending=0 replayFailure=0 After entity. and then refreshes the entity from the isDirty=false database.submitPending()[en. sends an import and a replayResult for isCreated=false the entity.isNew=false date.Client Object API Usage Description Flags/Values After entity.isNew=false tity submitPending] is called to submit isCreated=false the MBO to the server. isDeleted=false isUpdated=false pending=false pendingChange='N' replayCounter=33422977 replayPending=0 replayFailure=0 168 Sybase Unwired Platform . isDirty=false isDeleted=false isUpdated=true pending=true pendingChange='U' replayCounter=33424981 replayPending=33424981 replayFailure=0 Possible result: the Unwired Server accepts the up. findById(101).findById(101). // state Customer org = cust. Refresh Operation The refresh operation of an MBO allows you to refresh the MBO state from the client database.setFname("firstName"). // state cust.save(). // state cust.getDownloadState().Client Object API Usage Description Flags/Values Possible result: The Unwired Server rejects the up. // state //suppose there is new download for Customer 101 here Customer download = cust. sends a replayFailure for the entity. The mobile business object class provides properties for querying the original state and the downloaded state: public Customer getOriginalState(). cust. public Customer getDownloadState(). // state 1 2 1 3 3 Using all three states. Current state – the state after any CUD operation. cust. isCreated=false and refreshes the entity from the database isDirty=false isDeleted=false isUpdated=true pending=true pendingChange='U' replayCounter=33424981 replayPending=0 replayFailure=33424981 Mobile Business Object States A mobile business object can be in one of three states.setPhone("777-8888"). Downloaded state – the state downloaded from the Unwired Server.setCompany_name("Sybase").// newName is discarded Developer Guide: Android Object API Applications 169 . For example: Customer cust = Customer.getOriginalState().cancelPending().refresh(). cust. cust. • • • Original state – the state before any CUD operation. Customer cust = Customer. the application can resolve most conflicts that may occur.setFname("newName").isNew=false date. cust. Client Object API Usage Generated Package Database APIs The generated package database APIs include methods that exist in each generated package database. You can import large messages containing binary objects (BLOBs) to the client. tx. Throws a StreamNotOpenException if the stream is not open. // Use one transaction to save and submit pending LocalTransaction tx = SUP101DB. createDatabase does not need to be called since it is called internally when necessary. clients can execute queries without having large attribute valuies automatically filled in the returned MBO lists or result sets. Closes the value stream. Use the transaction API to group several transactions together for better performance. The large attribute APIs allow clients to import large messages from the server or send a replay message without using excessive memory and possibly throwing exceptions. An application may use deleteDatabase when uninstalling the application.beginTransaction().persistence. public static void createDatabase() public static void deleteDatabase() public static boolean databaseExists() Typically. send new or changed large objects to the server. close Closes the value stream.commit().submitPending(). customer.findByPrimaryKey(101). public static com. In addition.LocalTransaction beginTransaction() Customer customer = Customer. Clients can also access or modify a large attribute without reading the entire attribute into memory. Any buffered writes are automatically flushed. A streaming API is provided to allow the value to be accessed in chunks. and efficiently handle large attributes on the client.save(). 170 Sybase Unwired Platform . // modify customer information customer. Client Database APIs The generated package database class provides methods for managing the client database.sybase. Large Attribute APIs Use large string and binary attributes. BigBinary An object that allows access to a persistent binary value that may be too large to fit in available memory. Any previous contents of the file will be discarded..lang.Client Object API Usage Syntax public void close() Examples • Close the value stream – Writes a binary book cover image and closes the image file.getCover().sybase.BigBinary image = book. Throws an ObjectNotSavedException if this BigBinary object is an attribute of an entity that has not yet been created in the database. image.openForWrite(0).close().. Throws a StreamNotClosedException if the object is not closed.String filepath) Parameters • filepath – The file to be overwritten. Syntax public void copyFromFile(java. copyToFile Overwrites the specified file with the contents of this BigBinary object. Developer Guide: Android Object API Applications 171 . Any previous contents of the file are discarded. // . Syntax public void copyToFile(java. copyFromFile Overwrites this BigBinary object with data from the specified file.lang.findByPrimaryKey(bookID). Throws a StreamNotClosedException if the object is not closed. image.String filepath) Parameters • filepath – The file containing the data to be copied. book is the instance of an MBO and cover is a BigBinary attribute Book book = Book. In the following example.persistence. Throws an ObjectNotSavedException if this BigBinary object is an attribute of an entity that has not yet been created in the database. com. Syntax public void openForRead() Examples • Open for reading – Opens a binary book image for reading. openForWrite Opens the value stream for writing.sybase. Throws an ObjectNotSavedException if this BigBinary object is an attribute of an entity that has not yet been created in the database. This parameter is required for some platforms.getCover().findByPrimaryKey(bookID). Syntax public void openForWrite(long newLength) Parameters • newLength – The new value length in bytes. 172 Sybase Unwired Platform . and can be specified as 0.Client Object API Usage flush Flushes any buffered writes. image.openForRead(). but for Android the parameter value is ignored. Book book = Book. Throws an ObjectNotSavedException if this BigBinary object is an attribute of an entity that has not yet been created in the database. it is flushed before being reopened for reading. If the stream was already open for writing. Throws an ObjectNotFoundException if this object is null. Syntax public void flush() openForRead Opens the value stream for reading. Has no effect if the stream was already open for reading. Throws a StreamNotOpenException if the stream is not open.BigBinary image = book. com. Any previous contents of the value will be discarded. Flushes any buffered writes to the database.persistence. Client Object API Usage Examples • Open for writing – Opens a binary book image for writing.read(bufferLength). Book book = Book. Throws a StreamNotOpenException if the stream is not open for reading. Throws a StreamNotOpenException if the stream is not open for reading.close().persistence. Returns read returns a chunk of binary data read from the stream. Syntax public byte[] read(int length) Parameters • length – The maximum number of bytes to be read into the chunk. int bufferLength = 1024. image.BigBinary image = book.sybase.getCover().read(bufferLength). or a null value if the end of the stream has been reached.persistence.findByPrimaryKey(bookID).getCover(). com. readByte Reads a single byte from the stream.openForWrite(0). Book book = Book.findByPrimaryKey(bookID).openForRead(). com. or fewer if the end of stream is reached. read Reads a chunk of data from the stream. Reads and returns the specified number of bytes. Syntax public int readByte() Developer Guide: Android Object API Applications 173 . image. while (binary != null) { binary = image.sybase. byte[] binary = image. Examples • Read – Reads in a binary book image. } image.BigBinary image = book. or -1 if the end of the stream has been reached. 7. 1.write(binary).getCover(). 9 }. image. Throws a WriteAppendOnlyException if the platform only supports appending to the end of a value and the current stream position precedes the end of the value. 5. 8. byte[] binary = new byte[] { 0. Throws a StreamNotOpenException if the stream is not open for reading. Writes data to the stream.BigBinary image = book. Throws a StreamNotOpenException if the stream is not open for writing. write Writes a chunk of data to the stream. 2. 3. seek Changes the stream position. image. beginning at the current position.Client Object API Usage Returns readByte returns a byte of data read from the stream.openForWrite(0). Syntax public void seek(long newPosition) Parameters • newPosition – The new stream position in bytes. Throws a WriteOverLengthException if the platform requires the length to be predetermined before writing and this write would exceed the predetermined length. 174 Sybase Unwired Platform .sybase. Syntax public void write(byte[] data) Parameters • data – The data chunk to be written to the stream. Book book = Book.findByPrimaryKey(bookID).persistence. 4. com. so use flush or close to be certain that any buffered changes have been applied. The stream may be buffered. Zero represents the beginning of the value stream. 6. Examples • Write data – Opens a binary book image for writing. beginning at the current position. Throws a StreamNotOpenException if the stream is not open for writing. Syntax public void writeByte(byte data) Parameters • data – The byte value to be written to the stream. so use flush or close to be certain that any buffered changes have been applied. Throws a StreamNotOpenException if the stream is not open. BigString text = author.close().getBiography().write("something"). Syntax public void close() Examples • Close the value stream – Writes to the biography file. and closes the file. A streaming API is provided to allow the value to be accessed in chunks. text. Any buffered writes are automatically flushed. Author author = Author. Throws a WriteOverLengthException if the platform requires the length to be predetermined before writing and this write would exceed the predetermined length. text. BigString An object that allows access to a persistent string value that might be too large to fit in available memory.openForWrite(0). Throws an ObjectNotSavedException if this BigString object is an attribute of an entity that Developer Guide: Android Object API Applications 175 . Writes a byte of data to the stream. text. close Closes the value stream.Client Object API Usage writeByte Writes a single byte to the stream. Closes the value stream.findByPrimaryKey(authorID). Throws a WriteAppendOnlyException if the platform only supports appending to the end of a value and the current stream position precedes the end of the value. The stream may be buffered. copyFromFile Overwrites this BigString object with data from the specified file. Any previous contents of the value will be discarded. Flushes any buffered writes to the database. Syntax public void flush() openForRead Opens the value stream for reading.lang. Syntax public void copyToFile(java. Throws a StreamNotOpenException if the stream is not open. Throws an ObjectNotSavedException if this BigString object is an attribute of an entity that has not yet been created in the database. it is flushed before being reopened for reading. Throws a StreamNotClosedException if the object is not closed.Client Object API Usage has not yet been created in the database. Has no effect if the stream was already open for reading. Syntax public void openForRead() 176 Sybase Unwired Platform . Syntax public void copyFromFile(java. copyToFile Overwrites the specified file with the contents of this BigString object. If the stream was already open for writing. Throws a StreamNotClosedException if the object is not closed.String filepath) Parameters • filepath – The file to be overwritten.String filepath) Parameters • filepath – The file containing the data to be copied. Throws an ObjectNotSavedException if this BigString object is an attribute of an entity that has not yet been created in the database.lang. Any previous contents of the file are discarded. flush Flushes any buffered writes. BigString text = author. Developer Guide: Android Object API Applications 177 . Reads and returns the specified number of characters. Other platforms require the total amount of data written to the stream to match the specified value.getBiography(). Throws a StreamNotOpenException if the stream is not open for reading. text.openForRead().Client Object API Usage Examples • Open for reading – Opens the biography file for reading. read Reads a chunk of data from the stream.getBiography(). Syntax public String read(int length) Parameters • length – The maximum number of characters to be read into the chunk.findByPrimaryKey(authorID). text. Any previous contents of the value will be discarded. Author author = Author. BigString text = author. Examples • Open for writing – Opens the biography file for writing. with the actual length to be determined later. Syntax public void openForWrite(long newLength) Parameters • newLength – The new value length in bytes.openForWrite(0). or fewer if the end of stream is reached. Some platforms may allow this parameter to be specified as 0. Author author = Author. depending on the amount of data written to the stream. Throws an ObjectNotSavedException if this BigString object is an attribute of an entity that has not yet been created in the database. openForWrite Opens the value stream for writing.findByPrimaryKey(authorID). text. Examples • Read – Reads in the biography file.findByPrimaryKey(authorID). String something = text. 178 Sybase Unwired Platform . Syntax public void seek(long newPosition) Parameters • newPosition – The new stream position in characters.getBiography(). Syntax public int readChar() Returns readChar returns a single character read from the stream.Client Object API Usage Returns read returns a chunk of string data read from the stream.read(bufferLength). Throws a StreamNotOpenException if the stream is not open for reading. BigString text = author. seek Changes the stream position.openForRead(). } text. Author author = Author. or a null value if the end of the stream has been reached. Zero represents the beginning of the value stream. //null if EOF while (something != null) { something = text. int bufferLength = 1024.read(bufferLength). readChar Reads a single character from the stream. or -1 if the end of the stream has been reached.close(). Throws a StreamNotOpenException if the stream is not open for reading. Syntax public void write(java. Throws a WriteAppendOnlyException if the platform only supports appending to the end of a value and the current stream position precedes the end of the value. Developer Guide: Android Object API Applications 179 .write("something"). Throws a StreamNotOpenException if the stream is not open for writing. beginning at the current position. text. beginning at the current position. Writes a character of data to the stream. Throws a WriteAppendOnlyException if the platform only supports appending to the end of a value and the current stream position precedes the end of the value. Examples • Write data – Writes to the biography file. BigString text = author.String data) Parameters • data – The data chunk to be written to the stream. so use flush or close to be certain that any buffered changes have been applied.Client Object API Usage write Writes a chunk of data to the stream.getBiography().findByPrimaryKey(authorID). The stream may be buffered.close(). Author author = Author. Writes data to the stream. Throws a WriteOverLengthException if the platform requires the length to be predetermined before writing and this write would exceed the predetermined length. writeChar Writes a single character to the stream.lang. and closes the file.openForWrite(0). Throws a StreamNotOpenException if the stream is not open for writing. so use flush or close to be certain that any buffered changes have been applied. The stream may be buffered. text. Syntax public void writeChar(char data) Parameters • data – The character value to be written to the stream. Throws a WriteOverLengthException if the platform requires the length to be predetermined before writing and this write would exceed the predetermined length. text. classes. You can use it to retrieve data such as synchronization groups.item(i). operations.getOperation("save"). Depending on the options selected in the Eclipse IDE. and parameters using the MetaData API. attributes. MetaData API Some applications or frameworks can operate against MBOs generically by invoking MBO operations without prior knowledge of MBO classes.getMetaData(). including attributes and operations. } ClassMetaData The ClassMetaData class holds metadata for the MBO. including attributes and operations. EntityMetaData The EntityMetaData class holds metadata for the MBO. metadata for attributes and operations may be generated for all classes and entities.collections. entities. Any entity for which "allow dynamic queries" is enabled generates attribute metadata. These APIs allow retrieving the metadata of packages. OperationMetaData save = customerMetaData. System.getAttribute("lname"). i<syncGroups. i++) { String syncGroup = syncGroups. This can be achieved by using the MetaData API. 180 Sybase Unwired Platform .println(syncGroup)..StringList syncGroups = dmd.sybase. . for(int i=0. AttributeMetaData lname = customerMetaData. MBOs.. and parameters during runtime. the default database file. MetaData classes are generated automatically. and MBO metadata. DatabaseMetaData The DatabaseMetaData class holds package-level metadata.Client Object API Usage MetaData API You can access metadata for database.getSynchronizationGroups(). DatabaseMetaData dmd = SUP101DB. attributes.out.size(). com. operations. If no corresponding code exists. Developer Guide: Android Object API Applications 181 . and a log record (LogRecordImpl) imported to the client with information on the problem.println(lname. AttributeMetaData lname = customerMetaData. or an unrecognized EIS error.out.Client Object API Usage EntityMetaData customerMetaData = Customer. AttributeMetaData The AttributeMetaData class holds metadata for an attribute such as attribute name. column name. A server-side exception results in a stack trace in the server log. or the connection is terminated.getName()).getColumn()). Recoverable Error Codes Error Code 409 503 Probable Cause Backend EIS is deadlocked.out. All error codes that are not explicitly considered recoverable are considered unrecoverable. the 500 code is assigned to signify either a Sybase Unwired Platform internal error.getAttribute("lname"). System. System.getMetaData().println(lname.getOperation("save"). The EIS code and HTTP error code values are stored in log records. These tables list recoverable and unrecoverable error codes. and maxlength. Handling Exceptions The Client Object API defines server-side and client-side exceptions. System. type.out. Table 6. HTTP Error Codes Unwired Server examines the EIS code received in a server response message and maps it to a logical HTTP error code.getMaxLength()). Exceptions Reviewing exceptions allows you to identify where an error has occurred during application execution. Server-Side Exceptions A server-side exception occurs when a client tries to update or create a record and the Unwired Server throws an exception. OperationMetaData save = customerMetaData.println(lname. if a corresponding error code exists. Backend EIS is down. Manual Recovery Action Change the connection information. Mapping of SAP Error Codes to HTTP Error Codes Constant JCO_ERROR_COMMUNICATION Description Exception caused by network problems. error code 401 is treated as a normal recoverable exception. User authorization failed on Unwired Server due to role constraints (applicable only for MBS). or unavailability of the remote SAP system. Mapping of EIS Codes to Logical HTTP Error Codes A list of SAP® error codes mapped to HTTP error codes. SAP error codes that are not listed map to HTTP error code 500. gateway problems. Error code 401 is not treated as a simple recoverable error. N/A Delete the conflicting entry in the EIS. If the SupThrowCredentialRequestOn401Error context variable is set to true (the default). which sends a credential request notification to the user's inbox. N/A 404 405 412 500 Resource (table/Web service/BA. such as connection breakdowns. Note: These JCO error codes are not applicable for DOE-based applications. You can change this behavior by modifying the value of the SupThrowCredentialRequestOn401Error context variable in Sybase Control Center.Restore the EIS configuration. or backend user password. Table 8. If SupThrowCredentialRequestOn401Error is set to false. Backend EIS threw a constraint exception. Unrecoverable Error Codes Error Code 401 403 Probable Cause Backend EIS credentials wrong. PI) not found on backend EIS. By default. Invalid license for the client (applicable only for MBS). HTTP Error Code 503 182 Sybase Unwired Platform . Sybase Unwired Platform internal N/A error in modifying the CDB cache.Client Object API Usage Table 7. error code 401 throws a CredentialRequestException. Try again later. Exception Classes The Client Object API supports exception classes for queries and for the messaging client. etc. ConnectionPropertyException – thrown when a call to start the connection. Note: See Callback Handlers. PersistenceException – thrown when trying to access the local database. or unregister the application cannot be completed due to an error in a connection property value or application identifier ApplicationTimeoutException – thrown when a call to start the connection.) if the Query passed in selects for an attribute that does not exist in the MBO queried. register the application. ObjectNotFoundException – thrown when trying to load an MBO that is not inside the local database. ObjectNotSavedException – thrown when a BigBinary or BigString method is called that requires the object to already exist in the database. or invalid certificates. wrong password.401 ing login. • • ApplicationRuntimeException – thrown when a call to start the connection. Usually caused by unknown user name.Client Object API Usage Constant JCO_ERROR_LOGON_FAILURE Description HTTP Error Code Authorization failures dur. The remote SAP system is busy. register the application. NoSuchOperationException – thrown when trying to access operation metadata that does not exist in class metadata. • • • • • • • Developer Guide: Android Object API Applications 183 . NoSuchAttributeException – thrown when trying to access an attribute that does not exist in class or entity metadata and thrown by a dynamic query method (ExecuteQuery. Indicates that JCO has run out of resources such as connections in a connection pool. 503 JCO_ERROR_RESOURCE JCO_ERROR_STATE_BUSY 503 Client-Side Exceptions Device applications are responsible for catching and handling exceptions thrown by the client object API. register the application. or unregister the application cannot be completed due to an error. or unregister the application times out. LoginRequiredException – thrown when the client application does not login to the server. Client Object API Usage • • • • • • ProtocolException – thrown when an exception occurs during protocol version mismatch. WriteOverLengthException – thrown if the platform requires the length to be predetermined before write and a BigBinary or BigString method is called that writes past the predetermined length. WriteAppendOnlyException – thrown if a BigBinary or BigString method is called that writes to the middle of a value where only appending is allowed by the underlying database. StreamNotOpenException – thrown when a BigBinary or BigString method is called that requires the object to be open. SynchronizeException – thrown when an error occurs during synchronization. SynchronizeRequiredException – thrown when synchronization is needed. StreamNotClosedException – thrown when a BigBinary or BigString method is called that requires the object to not be open. • 184 Sybase Unwired Platform . 95. 21. 93. 135 creating 121 deleting 123 exists 122 locked 129 locking 129 retrieve data names 123 retrieve string 131 retrieve value 133 set string 131 set value 132 Developer Guide: Android Object API Applications 185 . 27. 93 Android Development Tools Plugin for Eclipse installing 7. installing 7. 138 CallbackHandler 53 callbacks 35 cascade operations 161 certificates 7. 118 change notification 42 ClassMetadata 180 ClassMetaData 180 client database 170 closeConnection 95 complex attribute type 162 complex type 47 composite relationships 161 CompositeTest 155 CompositeTest condition 149 concatenate queries 153 D data synchronization protocol 3. 150. 21 Android SDK 7. 33 ConnectionProfile 95. 4 data vault 122 change password 134. 49 create operation 159 createDatabase 170 B back-end search 157 beginOnlineLogin 106 beginSynchronize 108 BigBinary 170 BigString 175 C callback handlers 35. 155 AttributeMetaData 181 AttributeTest 149. 151.Index Index A ADT Plugin for Eclipse. 118 ConnectionProperties 73 retrieve activation code 73 retrieve Farm ID 78 retrieve HTTP cookies 80 retrieve HTTP credentials 81 retrieve HTTP headers 79 retrieve login certificate 74 retrieve login credentials 75 retrieve network protocol 73 retrieve port number 75 retrieve security configuration 77 retrieve server name 76 retrieve URL suffix 77 set HTTP cookies 80 set HTTP credentials 81 set HTTP headers 80 set login certificate 74 set login credentials 75 set network protocol 74 set port number 76 set security configuration 77 set server name 76 set URL suffix 78. 20 Application APIs retrieve connection properties 69 application callback handlers 145 application registration 31 arbitrary find method 149. 21 Afaria 18. 79 URL scheme 74 COUNT 152 create 48. 155 AttributeTest condition 149 authentication online 34 AVG 152 connection profile 32. 20 JMSBridge 53 K KeyGenerator 159 L listeners 35 LocalKeyGenerator 159 LogRecord API 111 E EIS error codes 181. 182 I init creating 120 186 Sybase Unwired Platform . 46 INTERSECT 153 J Javadoc 1 Javadocs. 23 Object Manager API 180 object query 45. 4 MetaData API 180 MIN 152 mobile business object states 169 mobile middleware services 3 multilevel insert 161 F filtering results 153 FROM clause 153 N NoSuchAttributeException 183 NoSuchOperationException 183 G generated code contents 14. 23 generateId 159 group by 152 O Object API code location of generated 14. 182 mapping of SAP error codes 182 non-recoverable 181 recoverable 181 EXCEPT 153 exceptions client-side 183 server-side 181 M MAX 152 maxDbConnections 96 MBO 43–45. 182 HTTP 181. 49 delete operation 160 deleteDatabase 170 device database 40 documentation roadmap 4 dynamic query 45. 55 default password 128 delete 48.Index unlocking 130 database client 170 database connections managing 95 DatabaseMetaData 180 DataVault 119 DataVaultException 119 debugging 53. 166 error codes EIS 181. location 14. 23 generated code. 147 ObjectNotFoundException 183 OnImportSuccess 104 onlineLogin 100 openConnection 95 other operation 160 H HTTP error codes 181. 182 encryption key 118 entity states 164. opening 61 JDK 7. 47–49 MBOLogger 53 messaging protocol 3. 155 QueryResultSet 156 T TestCriteria 155 TestCriteria condition 149 R Refresh operation 169 relationships 156 replay 37. 99 resumeSubscription 109 U UltraLite 40 UNION 153 UNION_ALL 153 unsubscribe 107 update 48. 27 Developer Guide: Android Object API Applications 187 . 20 simultaneous synchronization 104 Skip 155 Skip condition 149 SortCriteria 151.509 certificates 7. 155 SortCriteria condition 149 status methods 164. 98 SynchronizeException 183 P paging data 149. 152. 49 update operation 159 S save operation 160 SelectItem 153 setting the database file location on the device 97 setting the databaseFile location 97 signing 59 simulator 7. 152 passing structures to operations 162 password policy 128 set 124 pending operation 162 pending state 48 personalization keys 103 types 103 Q Query class 149 Query object 149. 166 structures passing to operations 162 subqueries 153 V value deleting 134 virtual devices 7. 21 Xcode 18. 20 X X. 44 synchronization profile 33 SynchronizationProfile 97.Index subscribe 106 subscribe() 104 SUM 152 SUPBridge 53 suspendSubscription 108 synchronization 40 MBO package 104 of MBOs 104 replication-based 104 simultaneous 104 synchronization group 42 synchronization parameters 43. Index 188 Sybase Unwired Platform .
Copyright © 2024 DOKUMEN.SITE Inc.