Technical Articles
Step by Step with the SAP Cloud Platform SDK for Android — Part 6 — Offline OData
Previous (Online OData) Home Next (Remembering Credentials)
A mobile application may not always be used in areas where a network connection is present or if it is, it may have high latency. The Offline OData framework enables the application to work against a local database instead of making online requests to read or update data.
The following are some additional sources of documentation on this topic.
Introduction to Offline API
Offline Applications Overview (SCPms docs)
Defining an Application Configuration File
Offline Enable Your Android Application
The following steps demonstrate how to enable the app to access data from a local database enabling it to work without network connectivity.
- Modify the app’s build.gradle to include the Offline OData library.
implementation 'com.sap.cloud.android:offline-odata:2.1.2'
- Add the following variables to MainActivity.
private ESPMContainer myOfflineServiceContainer; private OfflineODataProvider myOfflineDataProvider;
- Add the following method.
private void setupOfflineOData() { Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.sap.cloud.mobile.odata"); //logger.setLevel(Level.ALL); AndroidSystem.setContext(getApplicationContext()); try { URL url = new URL(serviceURL + "/" + connectionID); OfflineODataParameters offParam = new OfflineODataParameters(); offParam.setEnableRepeatableRequests(false); myOfflineDataProvider = new OfflineODataProvider(url, offParam, myOkHttpClient, null, null); OfflineODataDefiningQuery myDefiningQuery = new OfflineODataDefiningQuery("Products", "Products", false); myOfflineDataProvider.addDefiningQuery(myDefiningQuery); } catch (OfflineODataException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } myOfflineDataProvider.open(() -> { Log.d(myTag, "Offline store opened"); toastAMessage("Offline store opened"); final Button offlineODataButton = (Button) findViewById(R.id.b_offlineOData); Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { offlineODataButton.setEnabled(true); } }); myOfflineServiceContainer = new ESPMContainer(myOfflineDataProvider); }, (OfflineODataException offlineOdataException) -> { Log.d(myTag, "Offline store did not open.", offlineOdataException); toastAMessage("Offline store failed to open. " + offlineOdataException.getMessage()); }); }
- In the onRegister method in the updateUICallback add the below code to the onFailure and onResponse methods as shown below. If the app is started and there is no network connection, onFailure is called.
setupOfflineOData();
- Add the following code to the onOfflineOData method.
if (myOfflineServiceContainer != null) { List<Product> products = myOfflineServiceContainer.getProducts(); toastAMessage(products.size() + " products returned"); for (Product product : products) { Log.d(myTag, product.getName()); } } else { Log.d(myTag, "Offline service container is null."); toastAMessage("Offline service container is null."); }
- Run the example with a network connection. The first time the store is opened, a database will be created on the server and downloaded to the device. The Offline OData button will become enabled once the store has been opened. The results of pressing the Offline OData button are shown below.
- Turn on airplane mode and click on the Offline OData button and notice that the data is successfully returned as the query is fulfilled from the offline store on the device.
The Offline Sample and the following sections demonstrate more advanced features of offline apps. These are optional sections.
Syncing an Offline Store
Using a Foreground Service when Syncing
Using ILOData
Hi,
I'm facing problem with metadata here. earlier we used to declare group of defining queries/requests. my service url (metadata has duplicate entity type ex: customers & CUSTOMERS) because of this i'm getting offline store exception saying
Note : CUSTOMERS & Customers are replaced by some values.
com.sap.cloud.mobile.odata.offline.OfflineODataException: :1
EntityType Error: EntityType Name='CUSTOMERS' collides with EntityType Name='Customers'. Each definition must have a unique name. You can use the ALLOW_CASE_CONFLICTS option to allow names differing only in case, but preferably the schema should be changed to avoid names differing only in case.
<EntityType Name="CUSTOMERS" sap:content-version="1">...
at com.sap.cloud.mobile.odata.offline.internal.OfflineODataConverter.createOfflineODataException(OfflineODataConverter.java:111)
I believe this question has been asked at https://answers.sap.com/questions/747444/sap-cloud-platform-sdk-for-android-wizard-offline.html?childToView=747591&answerPublished=true#answer-747591
Hi,
I have followed the above tutorial to open the store, the store is getting opened. But, I can't see any data in offline DB. I think only schema has downloaded/ I'm not sure.
Later I've tried opening the offlinestore and I've used this method to download the db
Are you following the example in this tutorial using the sample back end?
The first time that you open the offline store, it is created, populated and downloaded from the server.
The next time you open the offline store, you will notice that it opens much quicker as it already exists on the device.
As a developer you control when the database can be updated from the back-end by calling download or when to pass any changes from the database to the back-end by calling upload.
Here is the documentation link that talks about updates to the metadata. In an offline app, the recommendation is for updates to be additive only.
https://help.sap.com/doc/c2d571df73104f72b9f1b73e06c5609a/Latest/en-US/docs/user-guide/odata/Offline_OData_Synchronizing_Data.html#schema-upgrades
Regards,
Dan van Leeuwen