Skip to Content

Step by Step with the SAP Cloud Platform SDK for Android

Part 5 — Online OData

Previous (Logging)   Next (Offline OData)

OData stands for Open Data Protocol and is a common way of accessing data from an SAP or other backend using RESTful APIs. The SAP Cloud Platform SDK for Android can be used to generate proxy classes from a backend that provides an OData interface.

The following are some additional sources of documentation on OData and generating and using proxy classes to access OData.
OData Overview
OData Asynchronous APIs
OData Version 2.0

The following instructions demonstrate how to make a data request. Proxy classes that represent the entity types in the of the sample OData service such as Product or SalesOrder will be used.
Generating Proxy Classes
Using the Proxy Classes
Using the Async OData API

Generating Proxy Classes

  1. Modify the app’s build.gradle to include the OData library.
    implementation 'com.sap.cloud.android:odata:1.1.100'

  2. The metadata document for the service can be viewed with the below URL. Note replace the user id (p1743065160) with your user id.
    https://hcpms-p1743065160trial.hanatrial.ondemand.com/mobileservices/origin/hcpms/ESPM.svc/v2/$metadata

    Right click the res folder and create a directory named xml. Create a file named metadata.xml.
    Copy the content from the url and paste into res/xml/metadata.xml.
    If the metadata.xml does not display well, right click on the file in Android Studio and choose Reformat Code.

  3. Change directories to the root of the project.
    cd %USERPROFILE%\AndroidStudioProjects\StepbyStep
    or on a Mac
    cd $HOME/AndroidStudioProjects/StepbyStep
    
  4. Generate the proxy OData classes by executing the following command in a terminal. The proxy classes will be generated into the project at StepbyStep\app\src\main\java\com\example\android\stepbystep.
    C:\SAP\AndroidSDK\tools\proxygenerator\bin\proxygenerator -na app\src\main\res\xml\metadata.xml -p com.example.android.stepbystep.ESPM -d app\src\main\java
    or on a Mac
    ~/SAP/AndroidSDK/tools/proxygenerator/bin/proxygenerator -na app/src/main/res/xml/metadata.xml -p com.example.android.stepbystep.ESPM -d app/src/main/java
    

    Note, the proxygenerator requires a JAVA_HOME environment variable or the java command to be found in your path.

    set JAVA_HOME=C:\Android\Android Studio\jre
  5. Notice that the proxy classes now appear in the project.

Using the Proxy Classes

  1. Add the following variables to MainActivity.
    private ESPMContainer myServiceContainer;
    private OnlineODataProvider myDataProvider;
  2. In the onRegister method, in the updateUICallback, in the response.isSuccessful block, add the below code.
    myDataProvider = new OnlineODataProvider("ESPMContainer", serviceURL + "/" + connectionID , myOkHttpClient);
    myServiceContainer = new ESPMContainer(myDataProvider);
  3. Add the following class in MainActivity (ie, before the closing }). This class when called will make a request to the OData service to return products using AsyncTask as network tasks cannot be performed on the main thread.
    private class ODataQueryTask extends AsyncTask<Void, Void, List<Product>> {
        @Override
        protected List doInBackground(Void... voids) {
            if (myServiceContainer != null) {
                try {
                    return myServiceContainer.getProducts();
                }
                catch (DataServiceException dse) {
                    Log.d(myTag, "Exception " + dse.getMessage());
                }
                catch (Exception e){
                    Log.d(myTag, "Exception " + e.getCause().getMessage());
                }
                return Arrays.asList(new Product[0]);
            }
            else {
                Log.d(myTag, "service container is null");
                return Arrays.asList(new Product[0]);
            }
        }
    
        @Override
        protected void onPostExecute(List<Product> products) {
            //Can update the UI thread here
            toastAMessage(products.size() + " products returned");
            for (Product product : products) {
                Log.d(myTag, product.getName());
            }
        }
    }
    
  4. Add the following code to the onODataOnline method.
    new ODataQueryTask().execute();
        
  5. Deploy and run the project and examine the Logcat after pressing the OData Online button.

Using the Async OData API

The below example makes use of a query to sort the results, uses an async method, and returns the product names that are in the Notebooks category.

    1. The async OData API uses Lambda expressions which require setting the source and target compatibility to 1.8. The Project Structure dialog can be opened via File, Project Structure.
    2. Regenerate the proxy OData classes, and this time do not include the -na option (noasync) by executing the following command in a terminal.
      C:\SAP\AndroidSDK\tools\proxygenerator\bin\proxygenerator app\src\main\res\xml\metadata.xml -p com.example.android.stepbystep.ESPM -d app\src\main\java
      or on a Mac
      ~/SAP/AndroidSDK/tools/proxygenerator/bin/proxygenerator app/src/main/res/xml/metadata.xml -p com.example.android.stepbystep.ESPM -d app/src/main/java
          

      Notice that there are now sync and async methods.

    3. Add the below method.
      private void asyncOData() {
          Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.sap.cloud.mobile.odata");
          logger.setLevel(Level.ALL);
          myDataProvider.getServiceOptions().setCacheMetadata(false);
          myDataProvider.setTraceRequests(true);
          myDataProvider.setPrettyTracing(true);
          myDataProvider.setTraceWithData(true);
      
          Log.d(myTag, "In aysncOData");
          DataQuery query = new DataQuery()
                  .from(ESPMContainerMetadata.EntitySets.products)
                  .select(Product.name)
                  .where(Product.category.equal("Notebooks"))
                  .orderBy(Product.name);
      
          myServiceContainer.getProductsAsync(query, (List<Product> products) -> {
              toastAMessage(products.size() + " products returned");
              for (Product product : products) {
                  Log.d(myTag, product.getName());
              }
          }, (RuntimeException re) -> {
              toastAMessage("OData online request failed: " + re.getMessage());
              Log.d(myTag, "An error occurred during async query:  "  + re.getMessage());
          });
      }
    4. Modify the onODataOnline method.
      //new ODataQueryTask().execute();
      asyncOData();
      
    5. The following is a subset of the debug/trace output from the above query. Notice that it contains trace information as well as a sorted list of products in the category of Notebooks.
      
      V/com.sap.cloud.mobile.odata.http.HttpRequest: [AsyncTask #2] [ESPMContainer] Request: GET 
      https://hcpms-p1743065160trial.hanatrial.ondemand.com/com.sap.edm.sampleservice.v2/Products?$select=Name
      &$filter=(Category%20eq%20'Notebooks')&$orderby=Name
      V/com.sap.cloud.mobile.odata.http.HttpRequest: [AsyncTask #2] [ESPMContainer] Response: status code = 200, status text = OK, time = 555 ms
      V/com.sap.cloud.mobile.odata.http.HttpRequest: [AsyncTask #2] [ESPMContainer] Response Headers:
      ...
      V/com.sap.cloud.mobile.odata.http.HttpRequest: [AsyncTask #2] [ESPMContainer] Response Content: (pretty printed)
      ...
      D/myDebuggingTag: Astro Laptop 1516
          Benda Laptop 1408
          ITelO FlexTop I4000
      ...
      
    6. A generated project using the Wizard contains a more complete example that demonstrates create, update and delete operations.
    7. Another option to generate the proxy classes is to use the OData Plug-in.

Previous (Logging)   Next (Offline OData)

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply