Skip to Content
Author's profile photo Claudia Pacheco

Getting Started with the Offline Store for Android

The SMP 3.0 OData SDK SP05 introduced the concept of store, which is an abstraction for services that can be consumed via OData protocol. There are two type of stores: online and offline. The methods for creating, updating, deleting and querying data are the same for both stores, however there are some differences. Let’s get you started with the Offline store.

IMPORT LIBRARIES AND RESOURCES

Your android project must include the following libraries under libs folder

  • AfariaSLL.jar
  • ClientHubSLL
  • ClientLog.jar
  • Common.jar
  • Connectivity.jar
  • CoreServices.jar
  • DataVaultLib.jar
  • E2ETrace.jar
  • HttpConvAuthFlows.jar
  • HttpConversation.jar
  • maflogger.jar
  • maflogoncore.jar
  • maflogonui.jar
  • mafuicomponents.jar
  • mafsettingscreen.jar
  • MobilePlace.jar
  • ODataAPI.jar
  • odataoffline.jar
  • ODataOnline.jar
  • perflib.jar
  • Request.jar
  • sap-e2etrace.jar
  • SupportabilityFacade.jar
  • XscriptParser.jar

The following resources should be imported under libs/armeabi folder

  • libmlcrsa16.so
  • thelibodataofflinejni.so

You can find the .jar and .so files in your OData SDK installation folder:

<Client SDK dir>\NativeSDK\ODataFramework\Android\libraries

<Client SDK dir>\NativeSDK\MAFReuse\Android\libraries

<Client SDK dir>\NativeSDK\ODataFramework\Android\libraries\armeabi


INITIALIZE OFFLINE STORE

The offline store requires among other information, the collections (also called defining requests) that will be accessible offline. When the client app requests the initialization of the offline store this is what happens under the covers:

  1. The mobile services (either SMP 3.0 SP04 on premise or HCPms) will send a GET requests to the OData producer to get the metadata (OData model) and it will use the OData model to create the Ultralite database schema.
  2. For each defining requests, the mobile services will pull the data from the OData producer and will populate the database. The mobile services checks if there’s a delta token:
    1. If there is a delta token, it will cache it and use it in the following refresh.
    2. If there is not delta token, it will cache the keys populated in the database.
  3. The mobile services will notify the client app the database is ready
  4. Using Ultralite functionality the client app will download the database. At this point the database can use used offline

Code Snippet – How to open an offline store

//This instantiate the native UDB libraries which are located in the
//libodataofflinejni.so file
ODataOfflineStore.globalInit();

//Get application endpoint URL
LogonCoreContext lgCtx = LogonCore.getInstance().getLogonContext();
String endPointURL = lgCtx.getAppEndPointUrl();
URL url = new URL(endPointURL);
                     
// Define the offline store options.
// Connection parameter and credentials and
// the application connection id we got at the registration
ODataOfflineStoreOptions options = new ODataOfflineStoreOptions();
options.host
options.port
options.enableHTTPS

// the serviceRoot is the backend connector name, which is usually the same

// as the application configuration name in the SMP Management Cockpit

options.serviceRoot= “com.sap.flight”;

                     
//The logon configurator uses the information obtained in the registration
// (i.e endpoint URL, login, etc ) to configure the conversation manager

// It assumes you used MAF Logon component to on-board a user      
IManagerConfigurator configurator = LogonUIFacade.getInstance().getLogonConfigurator(context);

HttpConversationManager manager = new HttpConversationManager(context);

configurator.configure(manager);

options.conversationManager = manager;

//Preferred settings – if back-end implements repeatable request

//look at a comment below for more details

options.enableRepeatableRequests = true;

options.storeName =“flight”;

             

//This defines the oData collections which will be stored in the offline store

options.definingRequests.put(“defreq1”, “TravelAgencies_DQ”);

//Open offline store synchronously

ODataOfflineStore offlineStore = new ODataOfflineStore(context);

offlineStore.openStoreSync(options);

//A way to verify if the store opened successfully

Log.d(“openOfflineStore: library version”+ ODataOfflineStore.libraryVersion());


What does it mean to support repeatable request?

If some type of connection issue prevents the client from receiving the response, then the client is unable to determine whether the request was processed by the server. However, sending the request a second time is not a solution as this could cause application errors in the backend.

If repeatable request is supported and the client makes the same request multiple times, the back-end will processed the first request, but thereafter, the only response the client will receive is a link pointing to the response created by the first request.

options.enableRepeatableRequests = true;

– By switching on the enableRepeatableRequest to true in the SMP offline store, this process is handle automatically in the client side.

– For more information on how to enable repeatable request in the back-end (gateway), please look at this documentation Settings for Idempotent Services – SAP NetWeaver Gateway – SAP Library

Once the offline store is open, you can create, update, delete and query data offline. As we mentioned before, the methods for creating, updating, deleting and querying data are the same for both stores. Note that all offline store requests are sent to the local database.


Code Snippet – How to query data with an offline store

//Define the resource path

String resourcePath = “TravelAgencies_DQ”;

ODataRequestParamSingle request = new ODataRequestParamSingleDefaultImpl();

request.setMode(Mode.Read);

request.setResourcePath(resourcePath);


//Send a request to read the travel agencies from the local database

ODataResponseSingle response = (ODataResponseSingle) offlineStore.executeRequest(request);

//Check if the response is an error

if (response.getPayloadType() == ODataPayload.Type.Error) {

       ODataErrorDefaultImpl error =  (ODataErrorDefaultImpl) response.getPayload();

       //TODO show the error


//Check if the response contains EntitySet

} else if (response.getPayloadType() == ODataPayload.Type.EntitySet) {

    ODataEntitySet feed = (ODataEntitySet) response.getPayload();

    List<ODataEntity> entities = feed.getEntities();

       //Retrieve the data from the response

    ODataProperty property;

    ODataPropMap properties;

    String agencyID, agencyName;

       for (ODataEntity entity: entities){

              properties = entity.getProperties();

              property = properties.get(“agencynum”);

              agencyID = (String) property.getValue();

              property = properties.get(“NAME”);

              agencyName = (String) property.getValue();

              . . .

     }

}


SYNCHRONIZE WITH ODATA PRODUCER


Flush

When connectivity is available, the client app must send all the local changes, this process is called Flush. When the client app requests a flush, this is what happens under the covers:

  1. The offline store communicates with mobile services
  2. For each requests the mobile services attempts to execute the request against the OData Producer
  3. The mobile services send the responses (errors and successes) to the client app and the errors will be stored in the ErrorArchive collection of the offline store.


Code Snippet – Flush
offlineStore.flushQueuedRequests();



Refresh

After the flush, the client app must receive all the changes from the OData producer that have occurred since the last refresh. When the client app requests a refresh, this is what happens under the covers:

  1. If delta token is enabled, for each request the mobile services requests data with the delta token
  2. Otherwise, the mobile services retrieve all the data from the OData producer and retrieve keys from cache and compute the delta. Reducing the traffic from the mobile services to the client app
  3. The mobile services transform all the changes to the relational mobilink protocol and send it back to the client app.
  4. The client app Ultralite database performs all the instructions
Code Snippet – Refresh
offlineStore.refresh();

NOTE

The code snippets showed in this blog are using the synchronous methods for simplicity purposes. Please note there are asynchronous methods available.


This blog assumed

  • You have configured an application in the mobile services with Back-End Connections

http://<sap gateway host>:<port>/sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/  

  • A user has been on-boarded with the mobile services using MAF Logon component.


ADDITIONAL LINKS

For more information on how to create an application configuration, visit Deploying Applications

If you prefer hands-on exercises, check these guides out

How To… Enable user On-boarding using MAF Logon with Template Project (Android)

How To…Consume OData Services in Offline Mode (Android)

How to… Handle Synchronization Errors (Android)

Hope you find this information useful,

Claudia

Assigned Tags

      23 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hi Claudia Pacheco!

      I have that exact code and the libraries in my app, but I'm getting this error: com.sap.smp.client.odata.offline.ODataOfflineException: [-10060] An error occurred while performing a synchronization.  Reason: -1305 (MOBILINK_COMMUNICATIONS_ERROR) %1:24 %2: %3:336134278.  Do you know what is wrong?

      I posted it here: http://scn.sap.com/thread/3659837

      Hope you can help me.

      Author's profile photo Former Member
      Former Member

      Do we need to create offline store (ODataOfflineStore offlineStore = new ODataOfflineStore(context);) each time user login to application or is there any other methods just to instantiate the offline store instance object (ODataOfflineStore offlineStore = ??)

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      Hi Sukesh,

      That's right, the only way to initialize a new store is through the constructor

      ODataOfflineStore offlineStore = newODataOfflineStore(context);

      Please check the help.sap site for more details about constructor and methods available.

      http://help.sap.com/saphelp_smp305sdk/helpdata/en/da/ac9e4c79b11014a0f5b63479afdb1a/content.htm

      Best regards

      Claudia

      Author's profile photo Former Member
      Former Member

      Hello Claudia,

      Its rally interesting blog 🙂 , is there any for IOS as well? Offline Odata Store is nothing but, Creating offline Apps by using SMP3?

      Regards,

      Prasad.

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      Hi Prasad,

      The Offline Odata store is a class (an abstraction) to consume OData services that we provide on the SMP 3.0 OData SDK SP05+ and that connects with the offline component in the SMP 3.0 SP04+ server to provision the local database and to synchronize the changes.

      My colleague Kenichi Unnai has created a lot of material on iOS. Please visit this page for more details. Mobile Application Development Platform for Developers - Native Apps

      Best regards,

      Claudia

      Author's profile photo Former Member
      Former Member

      Hi Claudia,

      Is it mandatory to define 'application configuration file' in order to create offline store, as specified in below url.

      http://help.sap.com/saphelp_smp305sdk/helpdata/en/f5/a25877c16f4fc384c44fcf0b92dab8/content.htm

      Regards,

      Sukesh N

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      Hi Sukesh,

      It's not mandatory to use the application configuration file. By default,

      - If the OData producer supports delta token, the Offline component in SMP will use the delta token in the following request

      - If the OData producer does not supports delta token, the Offline component in SMP will track the deltas to reduce the traffic from SMP to the client.

      You can change this behaviour with the configuration file as mentioned here

      http://help.sap.com/saphelp_smp305sdk/helpdata/en/da/6c897199704e39b561c8f5b3ddfe98/content.htm?frameset=/en/f5/a25877c1…

      with this configuration file you can also use the cache and indexes to improve performance.

      Best regards

      Claudia

      Author's profile photo Former Member
      Former Member

      Hi claudia.pacheco,

      Whether offline data store is supported in SMP 3.0 OData SDK SP03 for android?

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      Hi Swetha,

      the offline odata store is available for Android from SDK SP05.

      cheers

      Claudia

      Author's profile photo Former Member
      Former Member

      Hi claudia ,

      Very helpful. Thank you.

      but i get that error :- The method getLogonConfigurator(Context) is undefined for the type LogonUIFacade

      IManagerConfigurator configurator = 

                        LogonUIFacade.getInstance().getLogonConfigurator(context);

      Author's profile photo Former Member
      Former Member

      Hi Claudia Pacheco!,


      Can you share the code to implement offline data store without mafLogOn

      Author's profile photo Former Member
      Former Member

      Hi Experts,

      I have tried the above code. But, i am not able to achieve offline scenario. Is there any configuration that has to be done from SMP3.0 "Offline" tab.

      Thanks.

      Shilpi.

      Author's profile photo Midhun VP
      Midhun VP

      Hi Shilpi,

      Offline configuration in SMP cockpit is not mandatory.

      You should find the root cause of issue from server logs (increase the log level of offline component to debug and enable it).

      Also note the current limitations of Odata offline:http://help.sap.com/saphelp_smp307sdk/helpdata/en/88/9d29b3fac0456b812d86b5794c6e54/frameset.htm

      Regards,Midhun

      SAP Technology RIG

      Author's profile photo Former Member
      Former Member

      Hi Midhun VP

      I Get erro when using MAF Component , Can You help me to solve this issue ?

      Error using MAF Logon component

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      In the initialization of the offline store, I replaced

      options.serviceRoot= endPointURL;

      for

      // the serviceRoot is the backend connector name, which is usually the same as the

      // application configuration name in the SMP management cockpit
      options.serviceRoot= "com.sap.flight";

      using the endPointURL can cause problems when using relay server

      Author's profile photo Former Member
      Former Member

      Hi Claudia

      Any specific changes required when making a batch request offline ?

      I have a scenario wherein i want to make PO list and Item details available offline. I have been successful in making the list offline and when i call all the List items in a batch, the Data comes thru but when accessing this data it says count is 0.

      Is there anything specific we have to do to make a batch request offline.

      Thanks

      Pradeep Gudipati

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      Hi Pradeep,

      Could you please open a discussion and add code snippet of your project? Please include the way you are setting your defining request when you open the offline store and the requests you are calling in batch.In general batch requests (offline) do not require anything specific, but your count=0 may be related to the way you set your defining requests.

      Let me know when you create the discussion

      Thanks,

      Claudia

      Author's profile photo Hemendra Sabharwal
      Hemendra Sabharwal

      Hi Claudia Pacheco/Midhun VP - SCN Member of the Month May 2014,

      Could you please extend your help on below thread:

      Native Android Offline App - Flush is failing

      Thanks,

      Warm Regards

      Hemendra

      Author's profile photo DineshKumar R
      DineshKumar R

      Hi Claudia,

      I have developed Android Native Offline application without store concept with SMP3 SP5.

      Now we have upgraded to SP11. Hence, Some of the classes showing as deprecated. But the app still works fine. Is it must to convert the old project to store concept?


      I have Started to implement the Store concept for the new projects. and

      I need some clarification about offline store and cache.

      (1) what is the nature of offline store? it will store the response data in the local database?or simply store the request only.

      (2)How to cache and read the data from online store/offline store.

      Kindly give your suggestion and solution.

      Thanks,

      Dinesh

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      Hi Dinesh,

      In this Mobile Application Development Platform for Developers - Native Apps you will find a lot of content about developing native application with SMP. Have you seen it? there are some videos in the Android and the iOS section that talks about the concept at the store too. I'd recommend watching them when you can.

      In the above linke, there are also a lot of tutorials based on SP05/06. The documentation is not up to date, but it will give you an idea on how the store works.

      Hope this helps,

      Claudia

      Author's profile photo Girish Venkatachalam
      Girish Venkatachalam

      Hi Claudia,

       

      I've successfully been able to use the offline data store for my android app. However, not more than 40 entries are beeing fed into my local database for each defining request. I would like to remove the limit or at least raise it to 200 entries. Is there a way to modify this limit or something?

       

      Thanks

      Girish

      Author's profile photo Alessandro Guerra
      Alessandro Guerra

      Hi Claudia ,

      I have a problem with offline store in Android:

      After about 20 minutes of inactivity (app in background) the offline store is inaccessible and I receive the following error:
      com.sap.smp.client.odata.offline.odataofflineexception: [-10207] communication with the server failed due to invalid authentication.

      Thanks in advance.
      Alessandro.

      Author's profile photo Claudia Pacheco
      Claudia Pacheco
      Blog Post Author

      Hi Alessandro,

      Can you take a look at this KBA: https://launchpad.support.sap.com/#/notes/0002305884. Hope it helps.

      it's been a while since I've worked with the Android SDK. if your problem persists, I suggest creating a question in https://answers.sap.com/tags/01200615320800002636 to get help from the community.

      Best regards