Last July, I started writing a series focused on how the Salesforce platform can be utilized in a manner without a traditional Salesforce client. Here are links to the other articles in the series:
A graphical representation of the series is shown below:
The illustration above shows how various client frameworks can access the Salesforce data without actually utilizing clients provided by the Salesforce ecosystem.
Recently, I started a new series to demonstrate the Salesforce Mobile SDK, which harnesses the power of the Salesforce platform within standalone mobile apps.
A graphical representation of this new series is shown below:
“Exploring the Salesforce Mobile SDK Using React Native” was the first article in this Mobile SDK series. In this article, I will focus on using Android Studio to produce the same application.
The Salesforce Mobile SDK provides several benefits for software engineers:
If your application landscape utilizes Salesforce for key aspects of business operability, then consider leveraging the Salesforce Mobile SDK. By doing so, you can integrate data maintained by Salesforce into key component locations, allowing you to make strong business decisions.
If your client base requires support for Android devices and you wish to use Android Studio for app development, then you’ll find value in the forcedroid
CLI for getting started quickly with Salesforce functionality.
Key features for teams employing Android Studio include:
Now that we’re ready to dive in, let’s briefly review our use case.
Having a son (Finny) born with special needs introduced a personal desire to gain an understanding and appreciation of the products we use in our daily life. Years before Finny was born, my wife (Nicole) and I lived a healthy lifestyle. However, as Nicole began deep-diving into the ingredients in the foods that made up our daily diet, we received a much-needed wake-up call.
Fast-forward to today, our diet consists of few processed foods, no gluten, low sugar, and very little dairy. As much as possible, our protein originates from grass-fed sources, and we always favor organic options. Don’t get me started on GMO.
For this series, our Finny’s Foods application provides a simple list of meals that are both acceptable to us and favored by Finny. For now, we will include two simple attributes for each meal:
Over time, I plan to introduce other attributes (such as summary, ingredients, directions, and even a photo), but let’s walk before we run.
In addition to installing git
and npm
on my MacBook Pro, I made sure my Android Studio version was up to date. Next, I visited the following URL to make sure everything was set up and configured as expected:
Set Up Your Android Development Environment
These steps include installing Android Studio, the Android SDKs, and at least one Android emulator (AVD) and the forcedroid
CLI.
Next, I executed forcedroid
from a terminal session with the following options:
forcedroid create
Enter your application type (native_kotlin or native, leave empty for native_kotlin): native
Enter your application name: finnys-foods-android
Enter your package name: com.gitlab.johnjvester.finnysfoods.android
Enter your organization name (Acme, Inc.): JVC
Enter output directory for your app (leave empty for the current directory):
Once completed, I started Android Studio and imported the new finnys-foods-android project as documented in the following URL:
Before I could begin creating a new application in Android, I needed to establish the Meal object in Salesforce.
I already had a Developer org that I could use. (You can create a new one here.) So, I simply logged in using my email address and password for that org. Next, I navigated to the Apps | App Manager and the Setup perspective in Salesforce.
I created a new Lightning App called Meal:
On the remaining setup screens, I selected all the default settings and granted access to all Salesforce User Profiles.
Next, I visited the Objects & Fields | Object Manager menu option in the Salesforce Settings. Once I located the newly-created Meal item, I used the drop-down component to Edit the object.
I switched from the Details submenu to the Fields & Relationships option. I quickly realized I did not need to create a Name property for my Meal object since Salesforce already took care of that for me. I just needed to add the Rating field.
Using the New button, I selected the number field type and populated Step Two as noted below:
I used the default values and saved my new field. Now, I can use both the name and rating fields in my Android application.
Using the Salesforce client, I populated some source data to develop the application in Android Studio. Below is a summary of the submitted values:
Based upon the sample data, Finny always prefers ”Pizza” over “Chicken & Rice”.
With the source object and data configured, I used my IntelliJ IDEA application to open the ./finnys-foods-android
project for the first time.
For simplicity, the source code for my Android application will exist in the ./android/MainActivity.java
file. Feature developers building business applications should consider adopting design principles for their Android applications. The “Organizing your Source Files” article by the CodePath team provides some excellent information on this topic.
The MainActivity.java
file was already populated with enough information to connect to Salesforce and make things quite easy to build upon. I first introduced a SOQL static string to house the simple query to access the Meal__c object
:
private static final String SOQL = "SELECT Name, Rating__c FROM Meal__c ORDER BY Name ASC";
Instead of pushing a button to see data in the app, I updated the onResume(RestClient client)
method to call the sendRequest()
method to request data from Salesforce:
@Override
public void onResume(RestClient client) {
this.client = client;
try {
sendRequest();
} catch (UnsupportedEncodingException e) {
Toast.makeText(MainActivity.this,
MainActivity.this.getString(R.string.sf__generic_error,
e.toString()), Toast.LENGTH_LONG).show();
}
// Show everything
findViewById(R.id.root).setVisibility(View.VISIBLE);
}
I updated the sendRequest()
method to not only retrieve data from Salesforce but to provide a visual representation of the rating for each item:
private void sendRequest() throws UnsupportedEncodingException {
RestRequest restRequest = RestRequest.getRequestForQuery(
ApiVersionStrings.getVersionNumber(this), SOQL);
client.sendAsync(restRequest, new AsyncRequestCallback() {
@Override
public void onSuccess(RestRequest request, final RestResponse result) {
result.consumeQuietly(); // consume before going back to main thread
runOnUiThread(() -> {
try {
listAdapter.clear();
JSONArray records = result.asJSONObject().getJSONArray("records");
for (int i = 0; i < records.length(); i++) {
listAdapter.add(records.getJSONObject(i).getString("Name") + " "
+ getRating(records.getJSONObject(i).getInt("Rating__c")));
}
} catch (Exception e) {
onError(e);
}
});
}
@Override
public void onError(final Exception exception) {
runOnUiThread(() -> Toast.makeText(MainActivity.this,
MainActivity.this.getString(
R.string.sf__generic_error, exception.toString()),
Toast.LENGTH_LONG).show());
}
private String getRating(int rating) {
switch (rating) {
case 5:
return "* * * * *";
case 4:
return "* * * *";
case 3:
return "* * *";
case 2:
return "* *";
default:
return "*";
}
}
});
}
For simplicity, I decided to show a five-star rating item using the asterisk symbol. So a five-star item will appear as shown below:
Pizza * * * * *
I added an issue to my GitLab repository to replace the asterisks with star-based icons—like those provided by Font Awesome—so that empty stars will display when the rating is less than a five.
Instead of relying on the default design of the ListView
component, I decided to create my own text view to display the data within the live view containing the list of meals in Salesforce.
Inside the ./app/res/layout
folder, I created a new XML file, called custom_text_vew.xml
and included the following information:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:fontFamily="sans-serif"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:paddingLeft="1dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="9pt" ></TextView>
I was able to set the font and placement information to match my expectations.
With the XML in place, all I needed to do was reference the custom text view with the following update:
listAdapter = new ArrayAdapter<>(this, R.layout.custom_text_view, new ArrayList<>());
Since I wanted to match the React Native version of my application, I made the following updates to the ./app/res/layout/header.xml
file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginTop="5pt"
android:layout_marginBottom="0pt"
android:padding="3dp" >
<TextView
android:id="@+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textSize="12pt"
android:fontFamily="sans-serif"
android:textFontWeight="600"
android:layout_marginLeft="3dp"
android:paddingBottom="0pt"
android:paddingLeft="7pt"
></TextView>
<View
android:layout_below="@id/text_title"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="5pt"
android:background="@android:color/darker_gray" ></View>
</RelativeLayout>
Finally, I reviewed the ./finnysfoods/android/MainActivity.java
file and removed all of the unused methods as a result of updating the header.xml file. Android Studio, like IntelliJ IDEA, is great at changing the color of unused method names, which can be removed without impacting the run-time functionality of the application.
Using Android Studio, I used the Run menu option and selected the Run ‘app’ option, which also maps to the Shift-F10 shortcut.
First-time use will automatically redirect to a Salesforce login screen, where I used the same email address and password to access my Developer org. After signing in, the Finny’s Foods application appeared, including the five-star rating value for each item.
In a matter of minutes, we were able to create an Android application using Android Studio and the Salesforce Mobile SDK.
In this article, I introduced a custom mobile application that deploys natively from the Android store and uses source code written in Java and basic XML. Along the way, we gained a basic understanding of how Android-based applications are structured.
Starting in 2021, I have been trying to live by the following mission statement, which I feel can apply to any IT professional:
“Focus your time on delivering features/functionality which extends the value of your intellectual property. Leverage frameworks, products, and services for everything else.”
- J. Vester
The Salesforce Mobile SDK certainly adheres to my personal mission statement, which will benefit any feature team that requires Salesforce functionality as part of custom mobile applications running on Android devices. Software engineers in this realm of development should certainly consider adding the Salesforce Mobile SDK as a project dependency.
If you wish to see the full source code for this article, simply navigate to the following project on GitLab:
https://gitlab.com/johnjvester/finnys-foods-android
In the final article of the series, I plan to use the Salesforce Mobile SDK with xCode to create a native application for iOS devices.
Have a really great day!
Also Published Here