Technical Articles
Creating a Corporate Directory App with SAP’s Cloud Platform SDK for Android – Part 2
In our previous post, we described the example Corporate Directory app that we built using the SAP Cloud Platform for Android SDK. Now let’s take a look at how we started the project in SAP’s Cloud Portal, and how we used the SAP Cloud Platform SDK for Android Wizard to generate an Android Studio project.
Getting Started
First we confirmed our SAP Cloud Platform account was set up and working from the work we did on the iOS app, and installed the SAP Cloud Platform SDK for Android (this requires a computer with the latest version of Android Studio installed). Then, we confirmed that the mobile destination we set up for the iOS app was still in place (to see how we set that up, refer to our blog post “Creating a Corporate Directory App with SAP’s Cloud Platform SDK for iOS – Part 2”).
Starting the Android Studio project
Once we confirmed the destination in the portal, we used the SAP Cloud Platform SDK for Android Wizard to generate an Android Studio project. This is a really powerful feature of the SDK – the Wizard is an Android Studio plug-in which will: create boilerplate code for the selected model entities, build code to pull data from an SAP Cloud Platform instance, and build a skeleton user interface to display the selected entities. While this generated code will not be what we would ultimately want to ship to users, it saves a lot of time and simplifies the development process.
To start the Wizard, we selected “Start a new SAP Cloud Platform Android project” from the Android Studio start screen (alternatively, you can select “New SAP Cloud Platform Android Project…” from the File | New menu option).
This starts a series of screens to collect information about the app to be generated. In the first step, Server Connection, we specify our SAP Cloud Platform account information, including the account name and URLs, authentication type, and username/password:
In the second step, Cloud Configuration, we were able to select the application ID we created previously for our iOS app. Note that this ID is for the application as defined in the SAP Cloud Platform, so that destinations, access control, security, and other features can be attached to it. This is not the same as a bundle ID (for iOS apps) or applicationId (for Android apps) that is used to uniquely identify an app in the iOS App Store or Google Play Store.
Next, in the OData Services step, we selected the destination that we created for our iOS app. This destination was set up to provide access to the Success Factors User Management entities we would need to build the app.
In the Android Studio Project step, we specified the project name, project namespace, filesystem location, and our desired target language (we’re excited that Kotlin is supported in version 2 of the SDK!). The project namespace provided will be used as the unique applicationId for the Android project, and as the root package context for new project classes to be generated within.
Finally in the Project Features step we specified some options for the generated project; specifically we kept the default Online OData option, ensured that the option to generate a sample user interface was selected for our destination, and enabled logging.
We selected Finish, and after a few moments, the Wizard had created an Android Studio project for us.
After some trial and error, and discussion with SAP technical resources, we discovered that two minor adjustments were required to the generated code in order to access the destination we created correctly. Both adjustments were to the OData loading process.
The first adjustment was to the default sort attribute for the User entity in the UserViewModel. When first attempting to load the User list with the generated code, we received an error message indicating that addressLine1 (which was defaulted by the generated code) was not valid for sorting. We changed the sort attribute to lastName like so in UserViewModel:
class UserViewModel(application: Application): EntityViewModel<User>(application, EntitySets.user, User.lastName) {
The second adjustment was selecting a specific set of attributes for each entity, instead of selecting all as defaulted by the generated code. When attempting to load the list of Users, we received an error message, so we needed to specify the attributes desired for both the User and UserPermissions entities. To do this we updated the Repository to accept a set of attributes:
class Repository<T : EntityValue>(
private val entityContainer: EntityContainer,
private val entitySet: EntitySet,
private val orderByProperty: Property?,
private val propertySet: Set<Property> = emptySet()) {
We updated the Repository to use the passed in set of attributes in both the initialRead() and read() functions when building the query:
var dataQuery = DataQuery()
.select(*propertySet.toTypedArray())
.from(entitySet)
.top(1000)
Then we updated the RepositoryFactory to pass in the selected attributes for each entity. For example, this is what we specified for the User entity:
EntitySets.user.localName -> Repository<User>(entityContainer!!, EntitySets.user, orderByProperty, setOf(
User.userID,
User.username,
User.firstName,
User.lastName,
User.jobTitle,
User.title,
User.email,
User.businessPhone,
User.dateOfBirth,
User.department,
User.division,
User.location,
User.addressLine1,
User.addressLine2,
User.addressLine3,
User.city,
User.state,
User.zipCode,
User.country,
User.status,
User.hireDate,
User.gender
))
Running the app with those changes looks like this:
The user can select an entity, and then see a list of instances.
The user can select a User from the list to view details:
Clearly this was not what we would like to present to users; but all the “plumbing” was in place so we only needed to update the user interface to our design before adding more advanced features like Search.
Customizing the First Screen
Since we want the app to start with the list of employees, we can skip the entity selection screen altogether. To skip the Entity selection and go directly to the User list, we changed the generated LogonActivity to present the newly created EmployeeListActivity instead of the generated EntitySetListActivity. To do that, we modified the finishLogonActivity() function in LogonActivity to call a new function called startEmployeeListActivity() when the app is not resuming, and we removed the generated function called startEntitySetListActivity() since it was no longer needed.
Customizing the List View
The generated UserListActivity contained a lot of extra functionality that we didn’t need in our app, so we decided to create a new activity for the list of employees / users called EmployeeListActivity. This new activity utilized a RecyclerView, which presented Fiori ObjectCell instances. With some minor updates we were quickly displaying the user’s name, title, and avatar; and a header with company info at the top of the list.
Once the list was working, we added a SearchView to the menu bar and connected it to filter the list of users by first or last name from the entered search term, and update the displayed list.
Customizing the Detail View
The generated detail view (UserDetailActivity and UserDetailFragment) contained support for editing, which we did not want to include in our app. We decided to build a simpler version of the activity (EmployeeActivity) to display the subset of attributes that we desired. With some simple, standard customizations and styling we were easily able to display a Fiori Profile Header for the user, with buttons to initiate a call, text message, or email; and a table below to display the user’s attributes.
Summary
With the SAP Cloud Platform and SDK for Android, we were able to quickly build a custom, native, high quality Android app that met our business and design requirements. It was a solid benefit to be able to reuse some of the work we did on the SAP Cloud Platform side for our iOS app. Based on our experience with both the iOS Assistant and the Android Wizard generating model code, data access code, and a scaffolded user interface – it’s clear that we are able to build a non-trivial, functional app for both iOS and Android quickly and cost effectively. We are excited to continue exploring building apps for SAP.
We would be happy to chat about what we did, and learn what you think would be valuable in a mobile app built with SAP’s Cloud Platform SDK for iOS or Android. Contact us at https://martiancraft.com.