Front-End Web & Mobile
Building an Android app with AWS Amplify – Part 1
This post has been deprecated. Instead, please see the new Amplify Android Getting Started tutorial to learn how to build Android mobile applications using AWS Amplify.
This walkthrough is part 1 of a two-part series on how to build an AWS cloud-enabled Android mobile app with the AWS Amplify toolchain.
Suppose that you want to build a native Android app to display a list of pets. You want to set up APIs to enable listing, creating, and storing pet data—but you don’t want to manage the backend infrastructure. You want to focus on building an Android app. You also want to enable user authentication so that each user can add their own pet. In this post, we go through detailed step-by-step instructions to build this Android app.
We cover how to do the following:
- Add a GraphQL API that’s backed by AWS AppSync.
- Add a user authentication mechanism through Amazon Cognito.
- Enable querying and displaying the list of pets in a RecyclerView.
- Enable adding new pet data and persisting data in the backend.
Getting started – Setting up a new Android project
Prerequisites
To get started, you need to have Java JDK installed on your work station. Download and install Android Studio, and download the Android 6.0 SDK (API Level 23 or above) in the Android SDK Manager .
Also, download an emulator image. To do so, choose AVD Manager in Android Studio. Choose + Create Virtual Device, and then follow instructions to complete setup.
Create a new Android project
To get started, we first need to create a new Android . Go ahead and create a new Android project as shown in the following :
Select Phone and Tablet, choose API 23: Android 6.0 (Marshmallow), and click Next.
On the Add an Activity to Mobile screen, choose Basic Activity. Choose Next, keep the default values, and choose Finish to finish project setup.
Import the AWS AppSync SDK and configure the app
To use AWS AppSync in our new Android project, modify the project‘s build.gradle file, and add the following dependency in the build script:
Next, in the app‘s build.gradle, add in a plugin of apply plugin: 'com.amazonaws.appsync' and dependencies for AWS AppSync and MqttServices.
As a result, your build.gradle should look like this:
Finally, update your AndroidManifest.xml with updates to <uses-permissions> for network calls and offline states. Also, add a <service> entry under <application> for MqttService so we can use subscriptions:
Build your project and ensure that there are no issues.
Installing the AWS Amplify CLI and initializing a new AWS Amplify project
Now let’s install the AWS Amplify CLI and integrate it with our Android project so we can take full advantage of the Amplify CLI toolchain.
Install the AWS Amplify CLI
Open your terminal, and run the following at the command line. If you already have it installed, run the command again to get the latest updates.
Initialize the AWS Amplify project
Next, let’s initialize a new AWS Amplify project for your Android app.
cd into your Android Studio project root in a terminal window, and run the following:
Enter the following for each item:
- Choose your default editor: Visual Studio Code (or your favorite editor)
- Please choose the type of app that you’re building: android
- Where is your Res directory: (app/src/main/res): Press Enter to accept the default.
- Do you want to use an AWS profile? Y
- Please choose the profile you want to use: default
AWS CloudFormation the initial infrastructure to support your app. After it’s done, the AWS Amplify CLI toolchain has initialized a new project, and you see a couple of new files and folders in your app’s project directory: amplify and .amplifyrc. These files hold your project’s configuration.
Adding a GraphQL API, adding authentication, and generating client code
The AWS Amplify toolchain provides us with a streamlined process for creating an API, adding authentication, and generating client code. Let’s start by running the following command in your app’s root directory:
Enter the following for each item:
- Please select from one of the above mentioned services: GraphQL
- Provide API name: AmplifyAndroid
- Choose an authorization type for the API: Amazon Cognito User Pool
- Do you want to use the default authentication and security configuration? Yes, use the default configuration.
- Do you have an annotated GraphQL schema? N
- Do you want a guided schema creation? Y
- What best describes your project: (e.g. “Todo” with ID, name, description)
- Do you want to edit the schema now? (Y/n) Y
When prompted, update the schema to the following:
Go back to the terminal, and press Enter to continue.
Next, let’s push the configuration to your AWS account by running:
You’re prompted with your added changes:
| Category | Resource name | Operation | Provider plugin | | -------- | ---------------------- | --------- | ----------------- | | Auth | cognito12345678 | Create | awscloudformation | | Api | AmplifyAndroidWorkshop | Create | awscloudformation |
- Are you sure you want to continue? (Y/n) Y
Now you’re prompted to generate code for your brand new API:
- Do you want to generate code for your newly created GraphQL API (Y/n) Y
- Enter the file name pattern of queries, mutations and subscriptions (app/src/main/graphql/**/*.graphql): Press Enter to accept the default.
- Do you want to generate/update all possible GraphQL operations – queries, mutations and subscriptions (Y/n) Y
AWS CloudFormation runs again to update the newly created API and authentication mechanism to your AWS account. This process might take a few minutes.
To view the new AWS AppSync API at any time after its creation, go to the dashboard at https://console.aws.amazon.com/appsync. Also, be sure that your AWS Region is set correctly.
To view the new Amazon Cognito user authentication at any time after its creation, go to the dashboard at https://console.aws.amazon.com/cognito/. Also, be sure that your AWS Region is set correctly.
After AWS CloudFormation completes updating resources in the cloud, you’re given a GraphQL API endpoint, and generated GraphQL statements are available in your project.
Although it’s transparent to you and we can start consuming the API right away, you can always examine the newly generated GraphQL queries, mutations, and subscriptions in Android Studio under app/src/main/graphql/com/amazonaws/amplify/generated/graphql.
Building the Android app
Our backend is ready. Now let’s start using it in our Android app!
Before you start, if you haven’t already, you should turn on auto import. We’re using a lot of libraries! To do so, open Preferences -> Editor -> General -> Auto import. Then, select Add unambiguous imports on the fly.
Build and run your project to kick off the client code generation process. This gradle build process creates all the native object types, which you can use right away. You should be able to see a blank app as shown in the following screenshot:
If you’re curious, you can switch to the Project view, and browse to app/build/generated/source/appsync/com/amazonaws/amplify/generated/graphql/ to examine all the generated object types, queries, mutations, and subscriptions Java classes.
Add authentication
Because we earlier configured the app to use an Amazon Cognito user pool for authentication, we need to integrate authentication to our app. For simplicity, we’re going to leverage the AWS Mobile library’s built-in sign-in UI for Amazon Cognito authentication.
Open your app’s build.gradle and add the following dependencies:
Right-click your app directory, and choose New -> Activity -> Empty Activity. Name your activity AuthenticationActivity, select the Launcher Activity check box, and click Finish.
In the AuthenticationActivity.java class, modify the class to be the following:
Now let’s make sure that the AuthenticationActivity is our launcher activity. Open AndroidManifest.xml, and ensure that the <intent-filter> block is specified for the AuthenticationActivity as follows. You must remove the <intent-filter> and android:theme for MainActivity.
Lastly, let’s modify activity_main.xml and MainActivity.java, and delete the code related to the AppBarLayout so they look like this:
activity_main.xml:
MainActivity.java:
Build and start your app in your emulator. The sign-in UI should show up as follows:
Now let’s add a user. In your emulator, choose Create New Account. Enter the user name, and choose a complex password. The password needs to be at least 8 characters long, and can include uppercase letters, lowercase letters, special characters, and numbers. Enter a valid email so you can receive the verification code.
Choose Sign Up.
If you see an error such as Unable to resolve host "cognito-idp.us-east-1.amazonaws.com", double check that your emulator has internet connectivity. Restart the emulator if needed.
Your confirmation code should arrive shortly in your specified email inbox. Enter that code into the next screen, and choose Confirm to complete the sign-up process:
After you successfully sign in, you should see a successful message, and then be directed back to the same blank screen, which is our MainActivity.
To view the new user that was created in the Amazon Cognito user pool, go back to the dashboard at https://console.aws.amazon.com/cognito/. Also, be sure that your AWS Region is set correctly.
Create the AWS AppSync client
We now need to create an AWSAppSyncClient to perform API calls. Add a new ClientFactory.java class in your package:
This ClientFactory class supplies an AppSync client, which we can leverage to perform data access activities.
Query for data
We don’t have any data in our list yet, but let’s build the capacity to display them when we do have data.
Add a RecyclerView to display a list of items
Now let’s start building our app to enable the display of items.
We’re using RecyclerView to display data. Open src/res/layout/content_main.xml, switch to Text view, and replace the <TextView> with the following:
Now let’s define what each item in our list looks like. Right-click your res/layout folder, add a new Layout resource file. Let’s call it recyclerview_row.xml. Change the Root element to LinearLayout, keep the rest as default, and choose OK.
Switch to the Text view of recyclerview_row.xml, and modify the layout as follows:
Because we’re using a RecyclerView, we need to provide an adapter for it. Add a new Java class MyAdapter.java, which extends RecyclerView.Adapter:
Note the class-level variable mData. It’s a list of type ListPetsQuery.Item, which is a generated GraphQL type that’s based on our schema.
We have also exposed a setItems method, to allow outside resetting of our dataset.
Build the screen to populate the RecyclerView
Open MainActivity.java, modify the class to implement a query method, and populate the RecyclerView:
The appSyncClient is responsible for querying the AWS AppSync GraphQL endpoint. We chose to use the CACHE_AND_NETWORK mode because it retrieves the data in the local cache first, while reaching out to the network for latest data. After the fetch is complete, queryCallback is invoked again, and our dataset is updated with the latest data. There are other cache or network-only/first modes that you can use, depending on your app data fetching needs.
Build your app again to ensure that there are no errors. A blank screen still displays, but you should be able to see the log in the Logcat window. This indicates that a query has finished successfully, similar to the following:
09-28 10:32:16.789 11605-11699/com.example.demo.mypetapp I/MainActivity: Retrieved list items: []
Add a pet
Now let’s add the ability to add a pet.
Add a new Empty Activity by choosing New -> Activity -> Empty Activity. Name the activity AddPetActivity, and choose Finish.
Open the layout file activity_add_pet.xml, and add the following layout inside of your existing <android.support.constraint.ConstraintLayout>:
This gives us basic input fields for the names and descriptions of our pets.
Open AddPetActivity.java, and add the following code to read the text inputs. Create a new mutation, which adds a new pet.
Now let’s connect the AddPetActivity to our MainActivity.
Open the layout file activity_main.xml, and replace the floating button after the RecyclerView with the following:
Open MainActivity.java again, and modify the existing code in onCreate to start the AddPetActivity when the addPetbutton is pressed:
Now let’s build and start the project, and then test out the adding functionality.
Sign in with your previously created user name and password if you’re prompted again. Then, in the empty screen, choose the “+” button:
You should then see the screen that prompts you to enter a name and a description. Enter some test values as below to add our first pet.
Choose Save to send the mutation along to create a pet. The creation should be successful, and you should see our first created item displayed in the list. This is because we previously specified in onResume() that we do a “re-fetch”, so that we have the most up-to-date data.
There you go—you’ve created an Android app that shows you a list of pets and lets you add pets!
Give us feedback
We’re excited that you’ve created this Android app. Check out part 2 of this blog series – You’ll be able to add offline support, real-time subscriptions, and object storage to your Android app. As always, let us know how we’re doing, and submit any requests in the AWS Amplify CLI repository. You can read more about AWS Amplify on the AWS Amplify website.
Jane Shen is an AWS Professional Services Application Architect based in Toronto, Canada.