Skip to Content

Step by Step with the SAP Cloud Platform SDK for Android

Part 9 — Configuration Provider and the Discovery Service

Previous (Client Usage)   Next (OAuth)

The configuration provider includes a set of classes that can be used for the application connection settings. The configuration provider retrieves the settings from a file in the application, from the discovery service or a mobile device management (MDM) solution.

The following are some additional sources of documentation on the configuration provider and the discovery service.
Configuration Provider
Discovery Service Overview

The below steps will modify the sample to use the file configuration provider to load the settings from a separate file. Then the app will be changed to load the configuration from the discovery service.
Configuration Provider
Discovery Service

Configuration Provider

  1. Create a file named StepbyStep\app\src\main\res\raw\configurationprovider and paste the below information into it.
    Replace the user id(p1743065160) with your user ID.

    {
        serviceURL:"https://hcpms-p1743065160trial.hanatrial.ondemand.com",
        appID:"com.sap.stepbystep",
        connectionID:"com.sap.edm.sampleservice.v2"
    }

  2. In MainActivity.java, modify the variables serviceURL, appID and connection ID to not hard code their values and to not be final. For example, change
    private final String connectionID = "com.sap.edm.sampleservice.v2";

    to

    private String connectionID;
  3. Add the following method.
    private void getConfiguration() {
        ConfigurationLoaderCallback myConfigCallback = new ConfigurationLoaderCallback() {
            public void onCompletion(ProviderIdentifier providerId, boolean success) {
                Log.d(myTag, "Provider loaded successfully.  " + providerId);
                try {
                    JSONObject config = DefaultPersistenceMethod.getPersistedConfiguration(getApplicationContext());
                    serviceURL = config.getString("serviceURL");
                    appID = config.getString("appID");
                    connectionID = config.getString("connectionID");
                    Log.d(myTag, "Config data is:  " + config.toString());
                    onRegister(null);
                } catch (ConfigurationPersistenceException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
    
            public void onError(ConfigurationLoader configurationLoader,
                                ProviderIdentifier providerId,
                                UserInputs requestedInput,
                                ConfigurationProviderError error) {
                Log.d(myTag, "Provider failed to load.  " + error);
            }
    
            public void onInputRequired(ConfigurationLoader configurationLoader, UserInputs requestedInput) {
                Log.d(myTag, "Provider requires input. " + requestedInput);
            }
        };
    
        final ConfigurationLoader myLoader = new ConfigurationLoader(getApplicationContext(), myConfigCallback);
        myLoader.loadConfiguration();
    }
    
  4. At the end of the onCreate method, remove the call to onRegister and replace it with getConfiguration() which will call onRegister.
  5. Delete the app and rerun it. It should now load the configuration values from the raw\configurationprovider file.

Discovery Service

In this section, the configuration will be loaded from the server (Discovery Service) instead of being part of the app. When the app opens for the first time, the user will need to identify the server to receive the configuration from. This is done by asking the user to enter an email address. The combination of the appID and email domain name will be used by the configuration provider to request the configuration data.

  1. In the management cockpit, click on the Publish to Discovery Service button.

    Click on the custom button and provide the below configuration after replacing the user id (p1743065160) with your user id.

    {
        "serviceURL":"https://hcpms-p1743065160trial.hanatrial.ondemand.com",
        "appID":"com.sap.stepbystep",
        "connectionID":"com.sap.edm.sampleservice.v2"
    }

  2. Create a new layout file res/layout/email_edit_text_layout which will be used when the user is asked to enter their email address. Replace its contents with the below xml.
    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="16dp"
        android:paddingRight="16dp">
    
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <AutoCompleteTextView
                android:id="@+id/input"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/browser_actions_bg_grey"
                android:imeOptions="actionDone"
                android:inputType="text" />
    
        </android.support.design.widget.TextInputLayout>
    </FrameLayout>
    
  3. Add the below variable to MainActivity
    private ConfigurationLoader discoveryServiceConfigurationLoader;
  4. Add the following methods.
    private void getConfigurationFromDiscoveryService() {
        ConfigurationLoaderCallback myConfigCallback = new ConfigurationLoaderCallback() {
            public void onCompletion(ProviderIdentifier providerId, boolean success) {
                Log.d(myTag, "Provider loaded successfully.  " + providerId);
                try {
                    JSONObject config = DefaultPersistenceMethod.getPersistedConfiguration(getApplicationContext());
                    serviceURL = config.getString("serviceURL");
                    appID = config.getString("appID");
                    connectionID = config.getString("connectionID");
                    Log.d(myTag, "Config data is:  " + config.toString());
                    onRegister(null);
                } catch (ConfigurationPersistenceException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
    
            public void onError(ConfigurationLoader configurationLoader,
                                ProviderIdentifier providerId,
                                UserInputs requestedInput,
                                ConfigurationProviderError error) {
                Log.d(myTag, "Provider failed to load.  " + error);
            }
    
            public void onInputRequired(ConfigurationLoader configurationLoader, UserInputs requestedInput) {
                JSONObject config = null;
                //Don't try to download the configuration data if we already have saved data.
                try {
                    config = DefaultPersistenceMethod.getPersistedConfiguration(getApplicationContext());
                } catch (ConfigurationPersistenceException e) {
                    e.printStackTrace();
                }
                if (config.length() != 0) {
                    configurationLoader.processRequestedInputs(requestedInput);
                }
                else {
                    Log.d(myTag, "Provider requires input. " + requestedInput);
                    discoveryServiceConfigurationLoader = configurationLoader;
                    getEmail();
                }
            }
        };
    
        ConfigurationProvider[] providers = new ConfigurationProvider[] {
                //new DiscoveryServiceConfigurationProvider(getApplicationContext())  //This would use the package name com.example.android.stepbystep but we need the appID.
                new DiscoveryServiceConfigurationProvider("com.sap.stepbystep:1.0")
        };
        final ConfigurationLoader myLoader = new ConfigurationLoader(getApplicationContext(), myConfigCallback, providers);
    
        myLoader.loadConfiguration();
    }
    
    //https://stackoverflow.com/questions/10903754/input-text-dialog-android
    private void getEmail() {  //This dialog could also be provided by the Fiori Onboariding Library
        AlertDialog.Builder builder = new AlertDialog.Builder(this, android.R.style.Theme_DeviceDefault_Dialog_NoActionBar_MinWidth);
        builder.setMessage("Enter your email address to download the configuration for your app.");
        builder.setTitle("Enter email");
    
        //Set up the input
        View viewInflated = LayoutInflater.from(this).inflate(R.layout.email_edit_text_layout, (ViewGroup)findViewById(android.R.id.content), false);
        final EditText input = (EditText) viewInflated.findViewById(R.id.input);
        input.setText("Dan@trial-p1743065160trial.sapmobileplace.com");  //TODO, hardcoded to make it easier to test
        builder.setView(viewInflated);
    
        // Set up the buttons
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String email4DiscoveryService = input.getText().toString();
                Log.d(myTag, "Email is: " + input.getText().toString());
                UserInputs inputs = new UserInputs();
                ProviderInputs discoveryInputs = new ProviderInputs();
                discoveryInputs.addInput(DiscoveryServiceConfigurationProvider.EMAIL_ADDRESS, email4DiscoveryService);
                inputs.addProvider(ProviderIdentifier.DISCOVERY_SERVICE_CONFIGURATION_PROVIDER, discoveryInputs);
                discoveryServiceConfigurationLoader.processRequestedInputs(inputs);
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
    
        builder.show();
    }
  5. At the end of the onCreate method replace the call to getConfiguration(); with getConfigurationFromDiscoveryService();
  6. Uninstall and reinstall the app. Notice that it now requests an email address.

    The domain name of the email be that of the configured domain as shown below. For convenience the trial account has this configured. In a production scenario, the user would enter their company’s email.

  7. Note the request to get the configuration data can be seen using the below URL in a browser.
    https://discovery.sapmobilesecure.com/config-api.svc/ApplicationConfigurations/getApplicationConfiguration(AppConfigID=’com.sap.stepbystep:1.0′,EmailAddress=’Dan@trial-p1743065160trial.sapmobileplace.com’)

Previous (Client Usage)   Next (OAuth)

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