Building an Android app with AWS Amplify – Part 2
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 is part 2 of a two-part series of walkthroughs on how to build an AWS cloud-enabled Android mobile app with the AWS Amplify toolchain.
In this post, we continue from part 1 and add more advanced features to our Android app. We cover the following:
- Using optimistic updates: AWS AppSync API offline support
- Using subscriptions on data changes (mutations)
- Enabling object storage through Amazon S3
To create an Android project, you need to have the Java JDK installed on your work station. Download and install Android Studio, and then download the Android 6.0 SDK (API level 23 or higher) 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 the instructions to complete setup.
Continuing from part 1
At the end of the last post, we had created an Android app that displays a list of pets, and lets you add new pets. After adding a new pet, the app looks like this:
Optimistic updates and offline support
With the optimistic update functionality, you can provide a more responsive end user experience. You configure the UI so that it behaves as if the server will eventually return the data we expect. It’s being optimistic that the update is successful.
In this section, we create the data that we expect to be returned in memory after the mutation, and write it to the persistent SQL store that the Android device manages. Then when the server update returns, the SDK consolidates the data for you.
This approach works well with the scenario where internet connectivity is cut off while you’re trying to modify data. The AWS AppSync SDK automatically reconnects and sends the mutation when the app goes online.
Now let’s try it out. Open
AddPetActivity.java, and add the offline support at the end of
Now let’s add the
addPetOffline method. We check for connectivity after writing to the local cache, and close the activity as if the addition was successful.
We don’t need to change
MainActivity because its
query() method uses the
CACHE_AND_NETWORK approach. It reads from the local cache first while making a network call. Our previously added pet already exists in the local cache because of optimistic update.
Build and run the app. After you sign in, turn on Airplane mode:
Go back to the app and try adding a new item. The UI experience should be the same as when you were online before. Enter a name and description:
Choose SAVE. The app should display the second item in the list.
Now turn Airplane mode off. The items should be automatically saved. You can verify that the save is successful by closing and reopening the app, and then confirming that you still see the same two items being displayed.
With AWS AppSync, you can use subscriptions for real-time notifications.
In this section, we use a subscription to let us know right away when someone else adds a new pet. To do this, let’s add the following block at the end of the
Then let’s modify the
onResume method to call
subscribe at the end, to subscribe to new pet creations. We also need to make sure that we unsubscribe when we’re done with the activity.
Now let’s test it out. Build and run our app on your emulator.
Let’s then start up a second emulator. To start a second emulator, make sure that you have the default unselected. (Choose Run, choose Edit configurations. Under Android App, choose app, and clear the Use same device for future launches check box).
Also make sure that you have a different emulator device type in the AVD Manager. Run the app, choose your second emulator device, and have the app running side by side in these two emulators. Make sure that you sign into both so that you’re looking at the list of pets on both devices.
Add another pet in one of the apps, and watch it appear in the other app. Viola!
Working with storage
With AWS Amplify, you can easily add object storage support by using Amazon S3. AWS Amplify manages the bucket provision and permission configuration for you automatically.
Update AWS Amplify
To get started, let’s modify the local schema in
./amplify/backend/api/<PROJECTNAME>/schema.graphql to add a photo string property:
Next, go to our root directory, and run the following at the command line:
Answer the following questions:
- Please select from one of the below mentioned services: Content (Images, audio, video, etc.)
- Please provide a friendly name for your resource that will be used to label this category in the project: MyPetAppResources
- Please provide bucket name: mypetapp1246e0cde8074f78b94363dbe73f8adfdsfds (or something unique)
- Who should have access: Auth users only
- What kind of access do you want for Authenticated users: read/write
Choose Y when you’re asked whether you want to update code and regenerate GraphQL statements. Choose Enter, and wait for AWS CloudFormation updates to finish. This takes a couple of minutes.
Add storage dependencies
Meanwhile, let’s update our front-end client code.
AndroidManifest.xml, and add the
TransferService in our
Open your app’s
build.gradle, and add the dependency for Amazon S3:
Add photo selection code
AddPetActivity.java, and add the photo selection code:
We need to call the upload photo from the UI. Open
activity_add_pet.xml, and add a button before the Save button:
Now let’s connect this button to our
choosePhoto() method. Go back to
AddPetActivity.java, and modify
onCreate to attach a click listener to the Save button:
Build and run the app to confirm that the photo selection button works:
Choose ADD PHOTO. You should be able to select a photo from your gallery. (If there’s no photo in the emulator, open the browser and download some photos from the internet.)
After you select a photo, you should be redirected back to the ADD screen.
Add Amazon S3 photo uploading code
Now that the photo can be selected, we need to make sure that the photo gets uploaded and stored in the backend. We’ll use
TransferUtility to handle the Amazon S3 file upload and download. Let’s add its initialization code to our
Next, let’s add code to upload the photo by using the
TransferUtility in our
Save photo in mutation
Because we’ve added a new property to the Pet object, we need to modify our code to accommodate it. In
AddPetActivity.java, extract the following method to produce different types of
CreatePetInputs, depending on whether a photo has been selected:
Next, we modify our
save() to call the extracted method:
Because we changed the
CreatePet mutation, we need to modify the
addPetOffline code as well:
Then we can create a new method,
uploadAndSave(), to handle both the photo and no-photo saves:
Now we can call our
uploadAndSave() functions when the Save button is chosen:
We also have to update the subscription callback in
MainActivity.java because of the newly added
Download and display photos
Now that we’ve implemented the ability to save photos, let’s make sure that they get downloaded and displayed.
recyclerview_row.xml, add an
<ImageView>, and modify the layout as follows:
MyAdapter.java. Add code to correspond to the photo property, and to download the photo if one exists.
Because we’re downloading photos, we need to make sure that permissions can be granted. Go to
MainActivity.java, and add the permission-seeking block in
Now we’re finally done! Build and run the app again. Check to see if you can add a photo and see your lovely pet! Your app should look something like this:
There are other enhancements that we can make to the app. Try to work on the following as practice for yourself:
- Add the capability to update a pet’s information.
- Add the ability to delete a pet.
- Subscribe to update and delete mutations.
Give us feedback
We’re excited that you’ve created this Android app and have added more advanced features to it. 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 new AWS Amplify website.
Jane Shen is an AWS Professional Services Application Architect based in Toronto, Canada.