Skip to content

Creating Apps From Scratch

If you decide not to use the Wizard, you can still create a new Android Studio project and then build an app using the SDK libraries, or add the SDK to an existing project. To do this, you'll need to modify the settings.gradle.kts, top-level build.gradle.kts, module-level app/build.gradle.kts, and gradle/libs.versions.toml files manually to include all required repositories, dependencies, and settings.

Modern Android projects use the Kotlin DSL (build.gradle.kts) and a Version Catalog (gradle/libs.versions.toml) to centrally manage dependency versions. This guide follows that structure.

To generate proxy class Kotlin/Java files, use either the OData Gradle Plugin or the Proxy Generator CLI tool. Both tools are included in the software package.

To use the OData Gradle Plugin, modify the settings.gradle.kts and app/build.gradle.kts files to add the plugin and configure it as required. To use the Proxy Generator CLI tool, open a command prompt and enter the required command. For more information, see Using the OData Proxy Class Generator Command-line Tool

Prerequisites

You have run the installation script to install the SDK. See Installing the SAP BTP SDK for Android for more information.

Procedure

  1. From the Android Studio Welcome screen, select Start a new Android Studio project and complete the Create New Project wizard. Refer to your Android Studio documentation for further information.
  2. From the project tool window, navigate to the appropriate folder and open the build.gradle.kts file in the editor window.

For the top-level file, go to <yourproject> > gradle. For the module-level app, go to <yourproject> > app.

  1. Add the required dependencies to the project.
  2. Generate OData proxy classes. See Using the Gradle Tool to Generate Proxy Classes for more information.
  3. To ensure you can debug your new project, enable trace logging for your project; see Debugging.

Adding Required Repositories to Your Project

Repositories are configured in settings.gradle.kts using the dependencyResolutionManagement block (for libraries) and the pluginManagement block (for plugins). This is the recommended approach for modern Android projects and replaces the old allprojects / buildscript blocks in the top-level build.gradle.

Open settings.gradle.kts and add the repositories:

pluginManagement {
    repositories {
        google()
        mavenCentral()
        mavenLocal()
        gradlePluginPortal()
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        mavenLocal()
    }
}

Alternatively, we provide an improved method compared to well-known repositories such as Maven Central. This is the The SAP Cloud Shipment channel. For the Android SDK, the SAP Cloud Shipment channel` offers a customer-facing Maven repository that you can configure in your projects to consume the SAP BTP SDK for Android without additional manual downloads. Finally, we publish Android SDK libraries through the SAP-hosted Maven infrastructure in the DMZ. The process to use this is:

  • Obtain a technical user from the SAP Repositories Management site, and download the Basic Auth Password file. See Creating Required Credentials for further details.
  • Set the user credentials in ENV (SAP_MAVEN_USER, SAP_MAVEN_PASSWORD)
  • Add the SAP Maven repository directly to settings.gradle.kts:
pluginManagement {
    repositories {
        google()
        mavenCentral()
        mavenLocal()
        // SAP Cloud Shipment channel — provides the OData Gradle plugin
        maven {
            url = uri("https://73555000100800001281.mavensrv.cdn.repositories.cloud.sap")
            credentials {
                username = System.getenv("SAP_MAVEN_USER") ?: ""
                password = System.getenv("SAP_MAVEN_PASSWORD") ?: ""
            }
        }
        gradlePluginPortal()
    }
    resolutionStrategy {
        eachPlugin {
            if (requested.id.id == "com.sap.odata.android") {
                useModule("com.sap.cloud.android:odata-android-gradle-plugin:${requested.version}")
            }
        }
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        mavenLocal()
        // SAP Cloud Shipment channel — provides SAP BTP SDK for Android libraries
        // For China region, use: https://73555000100800001281.val.mavensrv.repositories.sapcloud.cn
        maven {
            url = uri("https://73555000100800001281.mavensrv.cdn.repositories.cloud.sap")
            credentials {
                username = System.getenv("SAP_MAVEN_USER") ?: ""
                password = System.getenv("SAP_MAVEN_PASSWORD") ?: ""
            }
        }
    }
}

Now all Android projects will also fetch dependencies from SAP infrastructure. If you are in China, you can update the URL to https://73555000100800001281.val.mavensrv.repositories.sapcloud.cn as well.

Note

The Kotlin DSL approach configures repositories directly in settings.gradle.kts, unlike the previous Groovy DSL approach using $HOME/.gradle/init.gradle. The repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) setting ensures all repositories are declared centrally here.

Adding Project Dependencies

Modern Android projects manage all dependency versions centrally in gradle/libs.versions.toml (the Version Catalog). Dependencies are then referenced via libs.* accessors in build.gradle.kts files.

Step 1: Define Versions and Libraries in gradle/libs.versions.toml

[versions]
sapSdkVersion = "<version>"

[libraries]
sap-cloud-foundation              = { group = "com.sap.cloud.android", name = "foundation",              version.ref = "sapSdkVersion" }
sap-cloud-foundation-app-security = { group = "com.sap.cloud.android", name = "foundation-app-security", version.ref = "sapSdkVersion" }
sap-cloud-onboarding-compose      = { group = "com.sap.cloud.android", name = "onboarding-compose",      version.ref = "sapSdkVersion" }
sap-cloud-flows-compose           = { group = "com.sap.cloud.android", name = "flows-compose",           version.ref = "sapSdkVersion" }
sap-cloud-fiori-composable-theme  = { group = "com.sap.cloud.android", name = "fiori-composable-theme",  version.ref = "sapSdkVersion" }
sap-cloud-fiori-compose-card      = { group = "com.sap.cloud.android", name = "fiori-compose-card",      version.ref = "sapSdkVersion" }
sap-cloud-fiori-compose-ui        = { group = "com.sap.cloud.android", name = "fiori-compose-ui",        version.ref = "sapSdkVersion" }
sap-cloud-odata                   = { group = "com.sap.cloud.android", name = "odata",                   version.ref = "sapSdkVersion" }
sap-cloud-offline-odata           = { group = "com.sap.cloud.android", name = "offline-odata",           version.ref = "sapSdkVersion" }
sap-cloud-chart                   = { group = "com.sap.cloud.android", name = "chart",                   version.ref = "sapSdkVersion" }
sap-cloud-google-vision           = { group = "com.sap.cloud.android", name = "google-vision",           version.ref = "sapSdkVersion" }

[plugins]
sap-odata-android = { id = "com.sap.odata.android", version.ref = "sapSdkVersion" }

The SDK includes the following libraries:

Library Gradle Dependency Line Description
Foundation com.sap.cloud.android:foundation:<version> Required for most mobile apps
Foundation Security com.sap.cloud.android:foundation-app-security:<version> Optional for mobile apps that use application management services
Foundation Firebase Push com.sap.cloud.android:foundation-push-fcm:<version> Optional for mobile apps that use firebase push service
Foundation Baidu Push com.sap.cloud.android:foundation-push-baidu:<version> Optional for mobile apps that use baidu push service
Foundation Logging com.sap.cloud.android:foundation-logging:<version> Optional for mobile apps that use logging without SAP Mobile Services
OData com.sap.cloud.android:odata:<version> Recommended for apps developing in java
OData (Kotlin) com.sap.cloud.android:odata:<version>:kotlin@aar Recommended for apps developing in kotlin
Offline OData com.sap.cloud.android:offline-odata:<version>
Onboarding com.sap.cloud.android:onboarding:<version>
Flows com.sap.cloud.android:flowsv2:<version>
Onboarding(Compose-based) com.sap.cloud.android:onboarding-compose:<version>
Flows(Compose-based) com.sap.cloud.android:flows-compose:<version>
Fiori com.sap.cloud.android:fiori:<version>
Fiori Jetpack Compose Theme com.sap.cloud.android:fiori-composable-theme:<version> Required for Fiori Jetpack compose UI
Fiori Jetpack Compose Card com.sap.cloud.android:fiori-compose-card:<version> Optional for Fiori Jetpack compose Card
Fiori Jetpack Compose UI com.sap.cloud.android:fiori-compose-ui:<version> Optional for Fiori Jetpack compose UI
Google Vision com.sap.cloud.android:google-vision:<version>
Charts com.sap.cloud.android:chart:<version>

Step 2: Add Dependencies in app/build.gradle.kts

dependencies {
    implementation(libs.sap.cloud.foundation)
    implementation(libs.sap.cloud.foundation.app.security)
    implementation(libs.sap.cloud.onboarding.compose)
    implementation(libs.sap.cloud.flows.compose)
    implementation(libs.sap.cloud.fiori.composable.theme)
    implementation(libs.sap.cloud.fiori.compose.card)
    implementation(libs.sap.cloud.fiori.compose.ui)
    implementation(libs.sap.cloud.offline.odata)
    implementation(libs.sap.cloud.chart)
    implementation(libs.sap.cloud.google.vision)

    // For Kotlin projects, use the kotlin classifier artifact
    implementation(libs.sap.cloud.odata) {
        artifact {
            classifier = "kotlin"
            type = "aar"
        }
    }
}

To enable application themes for downloading custom theming files at runtime, add the fiori-compose-customization entry to libs.versions.toml and list it in the dependencies:

gradle/libs.versions.toml:

sap-cloud-fiori-compose-customization = { group = "com.sap.cloud.android", name = "fiori-compose-customization", version.ref = "sapSdkVersion" }

app/build.gradle.kts:

dependencies {
    // ...
    implementation(libs.sap.cloud.fiori.compose.customization)
}

Using these libraries will require multiDex. To enable this for your project, add the following to the defaultConfig section of your app/build.gradle.kts file:

android {
    defaultConfig {
        // ...
        multiDexEnabled = true
    }
    // ...
}

Update the target SDK version and compatibility versions in app/build.gradle.kts:

android {
    compileSdk = 35
    // ...
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}

Initializing SDK

Since there are many modules in the Foundation component, using them in the client code to integrate your application with SAP Mobile Services will require lots of boilerplate code in the mobile application. To reduce the boilerplate code from your mobile application, a new API SDKInitializer.start is introduced as below:

object SDKInitializer {
    fun start(
        application: Application,
        vararg services: MobileService,
        apiKey: String? = null) {
        ...
    }
}

The parameters are explained below:

  1. Application

This parameter represents the running Android app.

  1. MobileService... services

This parameter lists all services initialized in your application. The following services are currently supported:

This parameter accepts a service object with configuration properties for most services. For example, the UsageService configures auto session features and sets the usage store name. Customize configurations before invoking the start method if needed.

Please follow the links above to see the details.

  1. API Key

This parameter is an optional API key that lets apps interact with mobile services before authentication. Each MobileService can use the API key to interact with mobile services during initialization.

This parameter is automatically saved to SettingsParameter when the client code saves the SettingsParameter instance to SettingsProvider. The client code can retrieve the API key from SettingsParameter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
````kotlin
SettingsProvider.get().apiKey?.also { apiKey ->
    //add APIkeyInterceptor into okHttpClient, and save it back into ClientProvider
    val httpClient = ClientProvider.get().addUniqueInterceptor(APIKeyInterceptor(apiKey), save = true)
    //call API with the above httpClient
    ...
    //remove the interceptor and save back to ClientProvider
    ClientProvider.get().removeInterceptorByType(APIKeyInterceptor::class, save = true)
}
````

Generating Proxy Classes

You can generate proxy class Kotlin/Java files based on OData metadata using either the OData Gradle Plugin or the Proxy Generator CLI tool. Both tools are included in the software package.

These generated proxy classes help consume a specific OData service. Use the OData service's metadata document to generate your data model. The generated code includes strongly typed functions to perform any OData operation on the data objects.

Info

Proxy classes are automatically added to projects generated with the Wizard Android Studio plugin.

Using the OData Gradle Plugin

The OData Gradle Plugin supports OData proxy class generation with the Gradle build.

OData service metadata must be saved in a file in the project. Metadata can be downloaded from the OData service metadata URL. Check with your OData service developer or your SAP system administrator for the URL.

If service definition results in changing metadata, the file must be updated to save new metadata. In the case metadata is spread across multiple files, save all the files in the project and reference the top-level file in schemaFile. The proxy generation task executes when the file content changes.

Adding the OData Gradle Plugin

Declare the plugin in gradle/libs.versions.toml:

[versions]
sapSdkVersion = "<version>"

[plugins]
sap-odata-android = { id = "com.sap.odata.android", version.ref = "sapSdkVersion" }

Register it (without applying) in the top-level build.gradle.kts:

plugins {
    alias(libs.plugins.sap.odata.android) apply false
}

Apply it in app/build.gradle.kts:

plugins {
    alias(libs.plugins.sap.odata.android)
}

Configuring the OData Gradle Plugin

To configure the plugin task for proxy class generation, use the configure<ODataPluginExtension> block in app/build.gradle.kts:

OData Plugin Configuration

Property Description
verbose Turn on verbose logging. Default is false.
services Configures the OData task to generate proxy classes for the app.
testServices Configures the OData task to generate proxy classes for local tests.
androidTestServices Configures the OData task to generate proxy classes for Android connected tests.

Service Proxy Class Generation Configuration

Property Description
schemaFile The metadata file for the OData service. Located at the $metadata endpoint of the OData service.
packageName Output package name (defaults to CSDL Schema Namespace)
serviceClass Service class name (defaults to entity container name)
nullableProperties All complex/entity properties are nullable (and no exception is thrown when undefined). Default is false.
disableOpenEnumeration Enumeration types permit member addition. Set this option for non-extensible enumerations. Default is false.
additionalParameters List of additional parameters to be passed to the proxy class compiler. Default is none.

Parameters used in the additionalParameters property:

Parameter Description
-service <service-class> Service: The service class name. Defaults to the entity container name.
-reference <directory> Directory containing referenced schemas.
-X:Offline.ClientOnly Add this annotation to extra definitions. The default is false.
-internal Generate internal proxy classes.
-X:annotations CSDL XML file containing extra annotations.
-X:definitions CSDL XML file containing extra annotations.
-async:legacy Generate legacy-style async service methods. The default is false.
-async:none Don't generate async service class methods. The default is false.
-async:result Generate result-style async service methods. The default is false.
-kotlin The generated proxy classes are based on the Kotlin language. Default is Java language.
-ofline Generate "offline" mode service class. The default is false.
-olline Generate "online" mode service class. The default is false.
-parser:<PARSER_OPTION> Enable this option for metadata parsing.
Refer to the SDK documentation for the CsdlOption class. Use underscore-separated.
-prefix <class-prefix> Name prefix for generated classes.
-proxy:OPEN_ENUMERATIONS Additional options for proxy generation, enumeration classes allow "extra" values. The default is false.
-proxy:NO_COMPRESS_METADATA Additional options for proxy generation, disable compression of embedded metadata.< The default is false.
-proxy:NO_REFRESH_METADATA Additional options for proxy generation, less code; refreshMetadata not supported. The default is false.
-proxy:NO_SPARSE_ENTITIES Additional options for proxy generation, less code; sparse entities not supported. The default is false.
-proxy:NO_THROW_UNDEFINED Additional options for proxy generation, getters return null for undefined properties. The default is false.
-proxy:SPLIT_DATA_SERVICE Additional options for proxy generation, split service classes every <N> methods. The default is false.
-proxy:NO_DEFAULT_VALUES Additional options for proxy generation, property values are undefined by default. The default is false.

The following example shows some of the basic configuration elements for proxy class generation from a metadata file.

configure<com.sap.odata.android.gradle.ODataPluginExtension> {
    verbose = true
    services {
        create("products") {
            schemaFile = file("src/main/odata/productssvcmetadata.xml")
            packageName = "com.example.products"
            serviceClass = "ProductsService"
            // Enable retaining original text in the parsed CSDLDocument or not
            // additionalParameters = listOf("-parser:RETAIN_ORIGINAL_TEXT")
        }
        create("orders") {
            schemaFile = file("src/main/odata/orderssvcmetadata.xml")
            packageName = "com.example.orders"
            serviceClass = "OrdersService"
            // Enable retaining original text in the parsed CSDLDocument or not
            // additionalParameters = listOf("-parser:RETAIN_ORIGINAL_TEXT")
        }
    }
}

In some cases generation may fail and suggest internal options that can be provided to additionalParameters.

Example:

additionalParameters = listOf("-parser:ALLOW_CASE_CONFLICTS")

Using the OData Proxy Class Generator Command-Line Tool

You can also generate your proxy classes by running the OData Proxy Class Generator tool. Ensure you have a current Java installation and that it is in your system's path.

The proxygenerator uses the following options:

Options Description
-m Metadata: metadata file.
-np Nullable properties: All complex/entity properties are nullable. No exception is thrown when undefined. The default is false.
-p Package: The output package name. Defaults to the CSDL Schema Namespace.
-s Service: The service class name. Defaults to the entity container name.
-v Verbose: Verbose mode on. The default is false.
-proxy:OPEN_ENUMERATIONS Additional options for proxy generation, enumeration classes allow "extra" values. The default is false.
-r Directory containing referenced schemas.
-X:Offline.ClientOnly Add this annotation to extra definitions. The default is false.
-i Generate internal proxy classes.
-X:annotations CSDL XML file containing extra annotations.
-X:definitions CSDL XML file containing extra annotations.
-async:legacy Generate legacy-style async service methods. The default is false.
-async:none Don't generate async service class methods. The default is false.
-async:result Generate result-style async service methods. The default is false.
-k The generated proxy classes are based on the Kotlin language. Default is Java language.
-of Generate "offline" mode service class. The default is false.
-ol Generate "online" mode service class. The default is false.
-parser:<PARSER_OPTION> Enable this option for metadata parsing.
Refer to the SDK docs for the CsdlOption class. Use underscore-separated.
-pf Name prefix for generated classes.
-proxy:NO_COMPRESS_METADATA Additional options for proxy generation, disable compression of embedded metadata.< The default is false.
-proxy:NO_REFRESH_METADATA Additional options for proxy generation, less code; refreshMetadata not supported. The default is false.
-proxy:NO_SPARSE_ENTITIES Additional options for proxy generation, less code; sparse entities not supported. The default is false.
-proxy:NO_THROW_UNDEFINED Additional options for proxy generation, getters return null for undefined properties. The default is false.
-proxy:SPLIT_DATA_SERVICE Additional options for proxy generation, split service classes every <N> methods. The default is false.
-proxy:NO_DEFAULT_VALUES Additional options for proxy generation, property values are undefined by default. The default is false.
-no:pretty Use original CSDL names, defaults to "pretty" class/property names. The default is false.

To generate proxy classes using the OData Proxy Class Generator tool:

  1. Download the desired OData service metadata document from its URL and save it in a file (for example, MyMetadata.xml).
  2. Enter the following command in terminal to generate the Kotlin/Java proxy classes:
  3. For Mac:

        $SAP_ANDROID_HOME/tools/proxygenerator/bin/proxygenerator -m <path to MyMetadata.xml> -s <MyServiceName> \
            -p <Generated Proxy Class Package Name> -d <Generated Proxy Destination>
    
  4. For Windows:

        proxygenerator.bat -m <path to MyMetadata.xml> -s <MyServiceName> -p <Generated Proxy Class Package Name> `
            -d <Generated Proxy Destination>
    

    where:

    • SAP_ANDROID_HOME is environment variable set to point to the folder where SDK is unzipped.
    • MyMetadata.xml is the downloaded metadata document.
    • MyServiceName is the generated service class name.
  5. Find the generated .kt / .java file(s) by default in the current folder or whatever the -d option is set to.

Creating the Required Credentials of Technical Users for SAP Cloud Shipment

You can create technical users on SAP Repositories Management site

Procedure for Creating a Technical User

  1. In your browser, navigate to the SAP Repositories Management site

  2. Enter the page of User management, initial opening of the "User management" page will automatically prompt a box for creating a technical user. You have to fill a name for it being aware that the id of your company will be added as a prefix. The name can contain only uppercase and lowercase letters as well as numbers and should be between 3 and 10 symbols long, and then click "Submit" button.

  3. Successful creation will result in a success dialog which means that the technical user was created and distributed to the back-end systems, click "OK" button on this Success dialog.

!!! note "Note"

1
    More users can be added by clicking the button "Add" on the left of User management page bottom.
  1. Click "Download" button in the line of Basic Auth Password to download credential, which is save to a file on your local file system:

Download credentials

in the form username_credential_type:

Basic authentication credentials


Last update: July 23, 2026