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 top-level and module-level
build.gradle files manually to include all required repositories, dependencies, and settings.
The top-level file stores configuration options common to all sub-projects/modules. The module-level file stores options for your new app.
To generate proxy class 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 two build.gradle files to add the plugin as a dependency and configure it
as required. To use the Proxy Generator CLI tool, open a command prompt and enter the required command. See Using the
OData Proxy Class Generator Command-line
Tool for more information.
Prerequisites¶
You have run the installation script to install the SDK. See Installing the SAP BTP SDK for Android for more information.
Procedure¶
- 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.
-
From the project tool window, navigate to the appropriate folder and open the
build.gradlefile in the editor window.For the top-level file, go to <
yourproject> >gradle. For the module-level app, go to <yourproject> > app. -
Add the required dependencies to the project
- Generate OData proxy classes. See Using the Gradle Tool to Generate Proxy Classes for more information.
- To ensure you can debug your new project, enable trace logging for your project; see Debugging.
Adding Required Repositories to Your Project¶
Add all required repositories including the local Maven repository to your project by modifying the app module
build.gradle file for your project.
From Android Studio, open the top-level build.gradle file and add the following to all the repositories blocks:
buildscript {
repositories {
google()
mavenCentral()
mavenLocal()
}
}
allprojects {
repositories {
google()
mavenCentral()
mavenLocal()
}
}
Alternatively, we offer a better similar way to well-known public repositories such as Maven Central, Bintray and
JCenter: The SAP Cloud Shipment channel. In this very specific case of the Android SDK, we are talking about a
customer-facing Maven repository that you can configure in your projects to consume the SAP BTP SDK for Android
without any additional manual downloads. We finally publish Android SDK libraries via 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 Passwordfile. See Creating Required Credentials for further details. - Set the user credentials in
ENV(SAP_MAVEN_USER,SAP_MAVEN_PASSWORD) - Create a
$HOME/.gradle/init.gradlescript with the following contents:
allprojects {
ext.SAPRepoConfig = {
maven {
url "https://73555000100800001281.mavensrv.cdn.repositories.cloud.sap"
credentials {
username "$System.env.SAP_MAVEN_USER"
password "$System.env.SAP_MAVEN_PASSWORD"
}
}
}
buildscript.repositories SAPRepoConfig
repositories SAPRepoConfig
}
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
You can add the above Maven project to your project repositories in the app module build.gradle file, the
above settings can be maintained on the project level.
Adding Project Dependencies¶
Add one or more of the SDK for Android components as required for your mobile application. 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> |
Add the following SDK libraries as dependencies to your module-level build.gradle file:
dependencies {
def versions = [sapCloudAndroidSdk: '<version>']
implementation "com.sap.cloud.android:fiori:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:fiori-composable-theme:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:fiori-compose-card:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:fiori-compose-ui:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:foundation:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:odata:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:offline-odata:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:onboarding:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:flowsv2:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:google-vision:$versions.sapCloudAndroidSdk"
implementation "com.sap.cloud.android:chart:$versions.sapCloudAndroidSdk"
}
If you intend to enable application themes to download custom theming files at runtime, include fiori-compose-customization dependencies to this enclosure:
dependencies {
...
implementation("com.sap.cloud.android:fiori-compose-customization:$versions.sapCloudAndroidSdk")
}
Using these libraries will require multiDex. To enable this for your project, add the following to the defaultConfig
section of your module-level build.gradle file:
android {
defaultConfig {
...
multiDexEnabled true
}
...
}
Update the target SDK version and compatibility versions as follows to your module-level build.gradle file:
android {
compileSdkVersion 35
...
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
}
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:
-
ApplicationThis parameter represents the running Android app.
-
MobileService... servicesThis parameter represents all the services to be initialized in your application. Currently the following services are supported:
ClientResourceServiceto download client resources automatically.LoggingServiceto setup the log settings and upload logs automatically.ClientPolicyServiceto download client policies automatically.UsageServiceto leverage the auto session, auto upload, and other client usage features.UserServiceto retrieve user information.
This parameter takes a service object, which contains configuration properties for most of the services, as the value. For example, the
UsageServicecan configure auto session features and set the usage store name. If you want to use customized configurations, you can do so before calling thestartmethod.Please follow the links above to see the details.
-
API Key
This parameter represents the optional API key, which allows apps to interact with mobile services before authentication is performed. Each
MobileServicecan make use of the API key to interact with mobile services during the initialization process.This parameter will be saved to
SettingsParameterautomatically when the client code saves theSettingsParameterinstance intoSettingsProvider. The client code can then retrieve the API key fromSettingsParameter.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 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¶
To add the OData Gradle plugin to your project, edit the top-level build.gradle file of your new Android Studio
project with the following:
buildscript {
dependencies {
classpath 'com.sap.cloud.android:odata-android-gradle-plugin:${versions}'
}
}
Configuring the OData Gradle Plugin¶
To configure the plugin task for proxy class generation, add an odata closure to the module-level build.gradle file
as indicated in the example in this section.
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 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.
apply plugin: 'com.sap.odata.android'
odata {
verbose true
services {
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 "-parser:RETAIN_ORIGINAL_TEXT"
}
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 "-parser:RETAIN_ORIGINAL_TEXT"
}
}
}
In some cases generation may fail and suggest internal options that can be provided to additionalParameters.
Example:
additionalParameters = ["-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:
- Download the desired OData service metadata document from its URL and save it in a file (for example,
MyMetadata.xml). -
Enter the following command in terminal to generate the Java proxy classes:
-
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>` -
For Windows:
proxygenerator.bat -m <path to MyMetadata.xml> -s <MyServiceName> -p <Generated Proxy Class Package Name> ` -d <Generated Proxy Destination>
where:
1 2 3
* `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. -
-
Find the generated
.javafile(s) by default in the current folder or whatever the-doption 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¶
-
In your browser, navigate to the SAP Repositories Management site
-
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.
-
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
More users can be added by clicking the button "Add" on the left of User management page bottom.
-
Click "Download" button in the line of
Basic Auth Passwordto download credential, which is save to a file on your local file system:

in the form username_credential_type:
