Exploring the Salesforce Mobile SDK Using Android Studio
Tags: webdev, tutorial, mobile, android
Published: 2022-03-26 15:12:54

![Article Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17ntl4xam8jatu7bz986.jpg)

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:

* Leveraging Salesforce Using Spring Boot
* Leveraging Salesforce Using a Client Written In Svelte
* Leveraging Salesforce Using a Client Written In Vue.js
* Leveraging Salesforce Using Mobile Applications Written (Once) In React Native
* Leveraging Salesforce Using a Client Written In Angular

A graphical representation of the series is shown below:

![Leveraging Salesforce](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anf766e6y7xsrfq0gqbm.png)

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](https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/intro.htm), which harnesses the power of the Salesforce platform within standalone mobile apps.

A graphical representation of this new series is shown below:

![Salesforce Mobile SDK](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhu6de2nz7i6m9adf4bx.png)

“[Exploring the Salesforce Mobile SDK Using React Native](https://dev.to/johnjvester/exploring-the-salesforce-mobile-sdk-using-react-native-2b33)” was the first article in this Mobile SDK series. In this article, I will focus on using Android Studio to produce the same application.

## Benefits of the Salesforce Mobile SDK

The Salesforce Mobile SDK provides several benefits for software engineers:

* Allows custom mobile device applications to utilize Salesforce features and functionality
* Full access to Salesforce functionality (no need to reinvent the wheel)
* Applications can be distributed using the application store of the native device
* Processing push notifications from Salesforce
* The ability to work with Salesforce data in an offline mode

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.

## Benefits of Using Android Studio

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:

* Uses Java or Kotlin as the base programming language
* Provides 100% native support for features and functionality on Android devices
* Allows experienced Android developers to quickly leverage Salesforce Mobile SDK functionality
* The long-term roadmap of features/functionality—along with the quality of ongoing support—tends to favor Android Studio over React Native

Now that we’re ready to dive in, let’s briefly review our use case.

## Finny’s Foods: An Example 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:

* Name of the meal
* Rating (1 to 5, where a rating of 5 is an absolute favorite for Finny)

Over time, I plan to introduce other attributes (such as summary, ingredients, directions, and even a photo), but let’s walk before we run.

## Getting Started with Android Studio

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](https://trailhead.salesforce.com/en/content/learn/projects/mobilesdk_setup_dev_tools/mobilesdk_setup_android)

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:

https://developer.salesforce.com/docs/atlas.en-us.noversion.mobile_sdk.meta/mobile_sdk/android_new_project.htm

## Creating the Meal Object in Salesforce

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:

![New Lightning App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ll8o3rygoe81lqti31y9.png)

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:

![Rating field](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yqcfcnf8lss0bptm2b1d.png)

I used the default values and saved my new field. Now, I can use both the name and rating fields in my Android application.

![Meal Object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/poqxwf4t3vddd7ty0l31.png)

Using the Salesforce client, I populated some source data to develop the application in Android Studio. Below is a summary of the submitted values:

![Sample Data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3ma3vwv3hfp6dp6pwc6.png)

Based upon the sample data, Finny always prefers ”Pizza” over “Chicken & Rice”.

## Adding Meal Functionality in Android Studio

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](https://guides.codepath.com/android/Organizing-your-Source-Files)” article by the [CodePath](https://guides.codepath.com/android) team provides some excellent information on this topic.

The `MainActivity.jav`a 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.

### Introducing a Custom Text View

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<>());
```

### Some Final Clean-Up and Styling

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.

## Finny’s Foods in Action

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.

![Finny's Foods in Action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynuvledmwvg33mgn33d5.png)

In a matter of minutes, we were able to create an Android application using Android Studio and the Salesforce Mobile SDK.

## Conclusion

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!