Technical Articles
Step by Step with the SAP Cloud Platform SDK for Android — Part 6a — Syncing an Offline Store
Previous (Offline OData) Home Next (Using a Foreground Service when Syncing)
An offline enabled app should perform a sync periodically to ensure the data on the client is up to date and to send any locally made changes to the backend. The user might want to pull the latest changes from the backend multiple times in a day or session, and therefore the app should provide an easy way to accomplish this task.
The following steps demonstrate how to add a sync button enabling a user-initiated sync.
- Add the following XML code to res\layout\activity_main.xml under the other button xml elements.
<Button android:id="@+id/b_offlineSync" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="performSync" android:enabled="false" android:text="Sync" />
- Add the following method to MainActivity.java
public void performSync(View v) { toastAMessage("Performing offline store sync."); Log.d(myTag, "Performing offline store sync."); Log.d(myTag, "Beginning offline store upload."); myOfflineDataProvider.upload(() -> { toastAMessage("Completed upload, beginning download."); Log.d(myTag, "Completed upload, beginning download."); myOfflineDataProvider.download(() -> { toastAMessage("Completed download, sync complete."); Log.d(myTag, "Completed download, sync complete."); }, e -> { toastAMessage("Failed to download the offline store, sync failed with error: " + e.toString()); Log.d(myTag, "Failed to download the offline store, sync failed with error: " + e.toString()); }); }, e -> { toastAMessage("Failed to upload the offline store, sync failed with error: " + e.toString()); Log.d(myTag, "Failed to upload the offline store, sync failed with error: " + e.toString()); }); }
A sync is composed of two operations, upload and download that can be performed independently.
- Add the following line to the success callback of the myOfflineDataProvider.open() call, below the line offlineODataButton.setEnabled(true);
findViewById(R.id.b_offlineSync).setEnabled(true);
- Run the app. Notice now that there is a sync button. When the user presses this button, some toast messages detail the progress of the sync.
- Next, we’ll add some code to notify the user to the progress of the sync operation. In the setupOfflineOData() method, add the following delegate definition.
OfflineODataDelegate delegate = new OfflineODataDelegate() { @Override public void updateDownloadProgress(OfflineODataProvider provider, OfflineODataProgress progress) { super.updateDownloadProgress(provider, progress); runOnUiThread(new Runnable() { @Override public void run() { // As an example, log the # of bytes received Log.d(myTag, "Download Bytes Received: " + progress.getBytesReceived()); } }); } @Override public void updateFileDownloadProgress(OfflineODataProvider provider, OfflineODataFileDownloadProgress progress) { super.updateFileDownloadProgress(provider, progress); runOnUiThread(new Runnable() { @Override public void run() { // As an example, log the # of bytes received Log.d(myTag, "Update File Download Bytes Received: " + progress.getBytesReceived()); } }); } };
- In the setupOfflineOData method, change the
myOfflineDataProvider = new OfflineODataProvider(url, offParam, myOkHttpClient, null, null);
line so that it includes the new delegatemyOfflineDataProvider = new OfflineODataProvider(url, offParam, myOkHttpClient, null, delegate);
- Run the app again and perform a sync by clicking the button. Consult Android Studio’s logs, and filter them using your debugging tag, “myDebuggingTag”. You should see the delegate methods being executed as the OfflineODataDelegate object is used.
- The app should ensure that no errors occurred during the sync. This is a job for the
ErrorArchive
. TheErrorArchive
is used to collect errors caused when using OData. The app can show the user the conflicts and let the user decide how to handle each error. For more information on error handling, see the SAP Handling Errors and Conflicts documentation, as well as the page on Handling Failed Requests. TheErrorArchive
is a list of entities that have the properties listed in the ErrorArchive Entity Properties list. - To query the error archive, add the following code to the success callback in the download call in the performSync(View v) method, as shown in the screenshot below.
// Get ErrorArchive entity set EntitySet errorArchiveSet = myOfflineServiceContainer.getEntitySet("ErrorArchive"); EntityType errorArchiveType = errorArchiveSet.getEntityType(); Property affectedEntityNavProp = errorArchiveType.getProperty("AffectedEntity"); Property requestIDProp = errorArchiveType.getProperty("RequestID"); // more properties such as RequestBody, RequestMethod, RequestURL, Message // CustomTag, Domain, HTTpStatusCode, Code, and InnerError DataQuery query = new DataQuery().from(errorArchiveSet).orderBy(requestIDProp); EntityValueList errorEntities = myOfflineServiceContainer.executeQuery(query).getEntityList(); // Iterate through the entities that have errors for (EntityValue errorEntity : errorEntities) { myOfflineServiceContainer.loadProperty(affectedEntityNavProp, errorEntity); EntityValue affectedEntity = affectedEntityNavProp.getEntity(errorEntity); // Process each affected entity // For this example application, we just log the entity Log.d(myTag,"Error found: " + affectedEntity.toString()); }
Previous (Offline OData) Home Next (Using a Foreground Service when Syncing)
Great Post, Thanks. Is it possible to send delta tokens to the odata service in the download method? I use the Syclo Exchange Framework in my backend to handle delta tokens but I dont know, how can I pass those delta tokens from the client. Do you have an example for that?
Best Regards,
Chris
More information on delta tokens can be found about the track_deltas setting at
https://help.sap.com/doc/c2d571df73104f72b9f1b73e06c5609a/Latest/en-US/docs/user-guide/odata/Offline_OData_Defining_Application_Configuration_File.html#delta-tracking
How to track OData deltas.
You might try enabling a server trace as mentioned in the below blog posting while you try out this feature. You could then see the OData requests being made during download calls.
https://blogs.sap.com/2018/12/08/step-by-step-with-the-sap-cloud-platform-sdk-for-android-part-12-server-logging-and-tracing/
Hope that helps,
Dan van Leeuwen
Thanks again. I have done all that and it is not working. I opend a new question on this topic and hopefully someone can help:
https://answers.sap.com/questions/12717361/odata-offline-delta-download-refresh.html
Best Regards,
Chris