Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Dan_vL
Product and Topic Expert
Product and Topic Expert
0 Kudos
Previous (Client Usage)   Home   Next (SAML and 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 folder named res/raw.
    Within that folder create a file named configurationprovider.json 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.json 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">

    <com.google.android.material.textfield.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" />

    </com.google.android.material.textfield.TextInputLayout;
    </FrameLayout>


  3. Add the below variable to MainActivity
    private ConfigurationLoader discoveryServiceConfigurationLoader;


  4. Add the following methods. In the below code, replace p1743065160 with your user ID.
    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()) //explicitly using string below to show the value
    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. In the app's build.gradle, in the dependencies section, add the following.
    implementation 'com.google.android.material:material:1.0.0'


  6. At the end of the onCreate method replace the call to getConfiguration(); with getConfigurationFromDiscoveryService();

  7. Uninstall and reinstall the app. Notice that it now requests an email address.

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

  8. 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)   Home   Next (SAML and OAuth)