Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Amplify project setup

We recommend that you use the latest version for project setup for your chosen framework or language.

This page is a reference for those who need the previous version and includes all project setup content for that version. Selecting the navigation menu will take you back to the current version by default.

Amplify Android v1 is deprecated as of June 1st, 2024. No new features or bug fixes will be added. Dependencies may become outdated and potentially introduce compatibility issues.

Please use the latest version (v2) of Amplify Library for Android to get started. Refer to the upgrade guide for instructions on upgrading your application to the latest version.

Amplify libraries should be used for all new cloud connected applications. If you are currently using the AWS Mobile SDK for Android, you can access the documentation here.

Before you begin, make sure you have the following installed:

  • Node.js v14.x or later
  • npm v6.14.4 or later
  • git v2.14.1 or later

Configure the Amplify CLI

To set up the Amplify CLI on your local machine, you have to configure it to connect to your AWS account.

Note: If you already have an AWS profile with credentials on your machine, you can skip this step.

Configure Amplify by running the following command:

Terminal
amplify configure

The configure command only supports creating AWS profiles that use permanent credentials. If you are using an IAM role or IAM Identity Center (previously AWS SSO), learn how to configure Amplify CLI manually

amplify configure will ask you to sign into the AWS Console.

Once you're signed in, Amplify CLI will ask you to use the AWS Identity and Access Management (IAM) to create an IAM user.

Terminal
Specify the AWS Region
? region: # Your preferred region
Follow the instructions at
https://docs.amplify.aws/cli/start/install/#configure-the-amplify-cli
to complete the user creation in the AWS console
https://console.aws.amazon.com/iamv2/home#/users/create

Navigate to the IAM User creation page if it's not already open.

Enter a User name and select Next. You can name the user anything but we'll call it "amplify-dev".

First step of creating an IAM user. Specifying user details.

Select Attach policies directly and select AdministratorAccess-Amplify as the Permissions policy. Select Next.

Second step of creating an IAM user. Setting permissions.

On the Review page, check that everything looks good and select Create user.

Third and final step of creating an IAM user. Reviewing and creating.

This will redirect to the users list page. Select the user you just created.

New user being shown in the Users table.

On the user details page, navigate to the Security credentials tab, scroll down to Access keys and select Create access keys.

Security credentials tab of the newly created user.

On the next page, select Command Line Interface, acknowledge the warning, and select Next.

Command Line Interface option selected on the options list.

On the next page select Create access key. You'll then see a page with the access keys for the user. Use the copy icon to copy these values to your clipboard, then return to the Amplify CLI.

Retrieve access keys page with access key and secret access key copy buttons circled.

Enter the values you just copied into the corresponding CLI prompts.

Terminal
Enter the access key of the newly created user:
? accessKeyId: # YOUR_ACCESS_KEY_ID
? secretAccessKey: # YOUR_SECRET_ACCESS_KEY
This would update/create the AWS Profile in your local machine
? Profile Name: # (default)
Successfully set up the new user.

Manually configure the Amplify CLI

If you are using an IAM role or IAM Identity Center (previously AWS SSO), you can configure your local machine for use with Amplify CLI by creating AWS profile entries manually rather than the amplify configure wizard.

To create an AWS profile locally using IAM Identity Center, you can use the AWS CLI wizard, aws configure sso, or write to ~/.aws/config directly:

~/.aws/config
[profile my-sso-profile]
sso_session = my-sso
sso_account_id = 123456789011
sso_role_name = AdministratorAccess-Amplify
region = us-west-2
output = json
[sso-session my-sso]
sso_region = us-east-1
sso_start_url = https://my-sso-portal.awsapps.com/start
sso_registration_scopes = sso:account:access

Currently, the Amplify CLI requires a workaround for use with IAM Identity Center due to an issue in how it resolves credentials.

~/.aws/config
[profile my-sso-profile]
sso_session = my-sso
sso_account_id = 123456789011
sso_role_name = AdministratorAccess-Amplify
region = us-west-2
output = json
+ credential_process = aws configure export-credentials --profile my-sso-profile
[sso-session my-sso]
sso_region = us-east-1
sso_start_url = https://my-sso-portal.awsapps.com/start
sso_registration_scopes = sso:account:access

Using the example above, when creating a new app or pulling an existing app, specify my-sso-profile as the AWS profile you'd like to use with the Amplify app.

To create an AWS profile locally using an IAM role, assign the AdministratorAccess-Amplify permissions set to the role and set the role in your ~/.aws/config file:

~/.aws/config
[profile amplify-admin]
role_arn = arn:aws:iam::123456789012:role/amplify-admin
source_profile = amplify-user
[profile amplify-user]
region=us-east-1

Using the example above, when creating a new app or pulling an existing app, specify amplify-admin as the AWS profile you'd like to use with the Amplify app

Next, you'll set up the app and initialize Amplify!

Create your application

For this section you will set up a skeleton project so that Amplify categories can be added to it.

1. Create a new project

Open Android Studio. Select + Create New Project.

Shows the Android studio welcome window

In Select a Project Template, select Empty Activity. Press Next.

Shows Android studio new project window

Next, configure your project:

  • Enter MyAmplifyApp in the Name field
  • Select either Java or Kotlin from the Language dropdown menu
  • Select API 16: Android 4.1 (Jelly Bean) from the Minimum SDK dropdown menu
  • Press Finish

Shows Android studio configure project window

Android Studio will open your project with a tab opened to either MainActivity.java or MainActivity.kt depending upon if you created a Java or Kotlin project respectively.

Shows Android studio successfully setup with the editor open

You now have an empty Android project into which you'll add Amplify in the next steps.

2. Install Amplify Libraries

Amplify for Android is distributed as Apache Maven packages. In this section, you'll add the packages and other required directives to your build configuration.

Under Gradle Scripts, open build.gradle (Module :app).

Add the following lines:

android {
compileOptions {
// Support for Java 8 features
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// Amplify core dependency
implementation 'com.amplifyframework:core:ANDROID_V1_VERSION'
// Support for Java 8 features
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
  • Set coreLibraryDesugaringEnabled, sourceCompatibility, and targetCompatibility to allow your application to make use of Java 8 features like Lambda expressions
  • Add Amplify Core and Desugaring libraries to the dependencies block

Amplify Android supports API levels 16 and higher. If your are supporting a min SDK less than 21, follow Android's documentation on adding multidex support.

Run Gradle Sync

Android Studio requires you to sync your project with your new configuration. To do this, click Sync Now in the notification bar above the file editor.

Screenshot with an arrow pointing to the Sync Now button in the file's notification bar

When complete, you will see CONFIGURE SUCCESSFUL in the output in the Build tab at the bottom of your screen.

Shows Android studio gradle sync successful

3. Provision the backend with Amplify CLI

To start provisioning resources in the backend, change directories to your project directory and run amplify init:

amplify init

Enter the following when prompted:

? Enter a name for the project
`MyAmplifyApp`
? Initialize the project with the above configuration?
`No`
? Enter a name for the environment
`dev`
? Choose your default editor:
`Android Studio`
? Choose the type of app that you're building
`android`
? Where is your Res directory:
`app/src/main/res`
? Select the authentication method you want to use:
`AWS profile`
? Please choose the profile you want to use
`default`

Upon successfully running amplify init, you will see a configuration file created in ./app/src/main/res/raw/ called amplifyconfiguration.json.

This file will be bundled into your application so that the Amplify libraries know how to reach your provisioned backend resources at runtime.

4. Initialize Amplify in the application

Create an Application class and add the Amplify initialization into its onCreate() to initialize Amplify once in your application.

Right-click on your namespace (e.g. com.example.MyAmplifyApp), click New, and click Java Class or Kotlin File/Class depending on which language you choose.

Configure the new class in New Java Class:

  • Enter MyAmplifyApp in the Name field
  • Press enter
  • Extend MyAmplifyApp from android.app.Application by adding extends Application to your class

Initialize Amplify by adding an onCreate method with the following code:

public void onCreate() {
super.onCreate();
try {
Amplify.configure(getApplicationContext());
Log.i("MyAmplifyApp", "Initialized Amplify");
} catch (AmplifyException error) {
Log.e("MyAmplifyApp", "Could not initialize Amplify", error);
}
}

Configure the new class in New Kotlin File/Class:

  • Enter MyAmplifyApp in the Name field
  • Press enter
  • Extend MyAmplifyApp from android.app.Application by adding : Application() to your class

Initialize Amplify by adding an onCreate method with the following code:

override fun onCreate() {
super.onCreate()
try {
Amplify.configure(applicationContext)
Log.i("MyAmplifyApp", "Initialized Amplify")
} catch (error: AmplifyException) {
Log.e("MyAmplifyApp", "Could not initialize Amplify", error)
}
}

This overrides the onCreate() to initialize Amplify when your application is launched.

Next, configure your application to use your new custom Application class. Open manifests > AndroidManifest.xml, and add a android:name attribute with the value of your new class name:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.MyAmplifyApp">
<!-- Add the android:name attribute to the application node -->
<application
android:name=".MyAmplifyApp"
...
</application>
</manifest>

Next, build and run the application. In logcat, you'll see a log line indicating success:

com.example.MyAmplifyApp I/MyAmplifyApp: Initialized Amplify

Next steps

Congratulations! You've created a skeleton app and are ready to start adding Amplify categories to your application. The following are some categories that you can start to build into your application:

  • Analytics - for logging metrics and understanding your users
  • API (GraphQL) - for adding a GraphQL endpoint to your app
  • API (REST) - for adding a REST endpoint to your app
  • Authentication - for managing your users
  • DataStore - for making it easier to program for a distributed data store for offline and online scenarios
  • Geo - to use location data and map UI components.
  • Predictions - to detect text, images, and more!
  • Storage - store complex objects like pictures and videos to the cloud.

Further customization

Async Programming Model

Most functionalities in Amplify Android are exposed as asynchronous functions. These functions return immediately, returning a result at a later time:

val post = Post.builder()
.title("My First Post")
.build()
// Time 0: save() is called.
Amplify.DataStore.save(post,
{
// Time 2, later: a result or error is emitted
Log.i("MyAmplifyApp", "Saved a post")
},
{
// Time 2, later: a result of error is emitted
Log.e("MyAmplifyApp", "Save failed", it)
}
)
// Time 1: save() yields execution to following lines,
// but no result available, yet.

This is a familiar pattern to many Android developers, and so is the default way of interacting with Amplify Android.

However, this development model has some challenges. Let's say you need to wait for an operation to complete, so that you can perform additional logic that depends on its result. This can quickly become unmaintainable, resulting in a situation known as "callback hell":

Consider a relational model where the creation of a Post also requires the creation of a User for the editor, and a PostEditor object to link the two together:

Post post = Post.builder()
.title("My First Post")
.build();
User editor = User.builder()
.username("Nadia")
.build();
PostEditor postEditor = PostEditor.builder()
.post(post)
.user(editor)
.build();

Using callbacks, you can save these objects via:

Amplify.DataStore.save(post,
{
Log.i("MyAmplifyApp", "Post saved")
Amplify.DataStore.save(editor,
{
Log.i("MyAmplifyApp", "Editor saved")
Amplify.DataStore.save(postEditor,
{ Log.i("MyAmplifyApp", "PostEditor saved") },
{ Log.e("MyAmplifyApp", "PostEditor not saved", it) }
)
},
{ Log.e("MyAmplifyApp", "Editor not saved", it) }
)
},
{ Log.e("MyAmplifyApp", "Post not saved", it) }
)

After three calls, you're no longer writing down the page, you're writing down-and-right. As your program grows, this may become difficult to scale.

There are a variety of different technologies that aim to solve this particular problem: Promises/Futures, RxJava, Kotlin Coroutines, and more.

Amplify Android includes optional support for Kotlin Coroutines and RxJava.

Kotlin Coroutines support

Amplify provides an optional and separate API surface which is entirely focused on using Kotlin's coroutines and flows.

To use it, import Amplify facade from core-kotlin instead of from core. See the Installation notes below for more details.

With the Coroutines APIs, most Amplify functions are expressed as suspend functions. Suspending functions can be launched using one of the lifecycle-aware coroutine scopes in the Android Architecture components:

import com.amplifyframework.kotlin.core.Amplify
// ...
val post = Post.builder()
.title("My First Post")
.build()
lifecycleScope.launch {
try {
Amplify.DataStore.save(post) // This is suspending function!
Log.i("AmplifyKotlinDemo", "Saved a post")
} catch (failure: DataStoreException) {
Log.e("AmplifyKotlinDemo", "Save failed", failure)
}
}

Coroutines can greatly improve the readability of dependent, asynchronous calls. Moreover, you can use scopes, dispatchers, and other Kotlin coroutine primitives to get more control over your execution context.

Let's consider what happens when you have three dependent operations. You want to save a Post, then an Editor, and finally a PostEditor. With Amplify's coroutines interface, you can write these operations sequentially:

lifecycleScope.launch {
try {
listOf(post, editor, postEditor)
.forEach { Amplify.DataStore.save(it) }
Log.i("AmplifyKotlinDemo", "Post, Editor, and PostEditor saved")
} catch (failure: DataStoreException) {
Log.e("AmplifyKotlinDemo", "An item failed to save", failure)
}
}

In Amplify's vanilla APIs, this would have created a large block of code with three nested callbacks.

Install coroutine support

Amplify's coroutine support is included in an optional module, core-kotlin.

  1. Under Gradle Scripts, open build.gradle (Module :app), and add the following line in dependencies:

    dependencies {
    // Add the below line in `dependencies`
    implementation 'com.amplifyframework:core-kotlin:ANDROID_V1_KOTLIN_VERSION'
    }
  2. Wherever you use the Amplify facade, import com.amplifyframework.kotlin.core.Amplify instead of com.amplifyframework.core.Amplify:

    import com.amplifyframework.kotlin.core.Amplify

Using Kotlin primitives

Amplify tries to map the behavior of your callback-based APIs to Kotlin primitives in an intuitive way. Functions whose callbacks emit a single value (or error) are now expressed as suspending functions, returning the value instead. Functions whose callbacks emit a stream of values will now return Kotlin Flows, instead.

Special cases with Kotlin

Some APIs return an operation which can be cancelled. Examples include realtime subscriptions to an API, and uploading/downloading objects from Storage.

API subscriptions with Kotlin

The API category's subscribe() function uses both a suspend function and a Flow. The function suspends until the API subscription is established. Then, it starts emitting values over the Flow.

lifecycleScope.async {
try {
Amplify.API.subscribe(request) // Suspends until subscription established
.catch { Log.e("AmplifyKotlinDemo", "Error on subscription", it) }
.collect { Log.i("AmplifyKotlinDemo", "Data on subscription = $it") }
} catch (error: ApiException) {
Log.e("AmplifyKotlinDemo", "Failed to establish subscription", error)
}
}

Storage upload and download operations with Kotlin

The Storage category's downloadFile() and uploadFile() functions are bit more complex. These APIs allow you to observe transfer progress, and also to obtain a result. Progress results are delivered over a Flow, returned from the progress() function. Completion events are delivered by a suspending result() function.

// Download
val download = Amplify.Storage.downloadFile(remoteKey, localFile)
lifecycleScope.async {
download
.progress()
.collect { Log.i("AmplifyKotlinDemo", "Download progress = $it") }
}
lifecycleScope.async {
try {
val result = download.result()
Log.i("AmplifyKotlinDemo", "Download finished! ${result.file.path}")
} catch (failure: StorageException) {
Log.e("AmplifyKotlinDemo", "Download failed", failure)
}
}
// Upload
val upload = Amplify.Storage.uploadFile(remoteKey, localFile)
lifecycleScope.async {
upload
.progress()
.collect { Log.i("AmplifyKotlinDemo", "Upload progress = $it") }
}
lifecycleScope.async {
try {
val result = upload.result()
Log.i("AmplifyKotlinDemo", "Upload finished! ${result.key}")
} catch (failure: StorageException) {
Log.e("AmplifyKotlinDemo", "Upload failed", failure)
}
}

Using RxJava with Amplify

Amplify also provides a set of APIs that expose Reactive Extensions, a cross-platform library for asynchronous and event-based programs.

To use it, you'll interact with the RxAmplify facade instead of the default Amplify facade.

import com.amplifyframework.rx.RxAmplify;
// ...
Post post = Post.builder()
.title("My First Post")
.build();
RxAmplify.DataStore.save(post)
.subscribe(
() -> Log.i("RxAmplifyDemo", "Saved a post"),
failure -> Log.e("RxAmplifyDemo", "Save failed", failure)
);

Compared to the traditional callback API, this doesn't make a big difference when used for a single method call.

However, it greatly improves readability when chaining asynchronous calls. Moreover, you can use standard RxJava operators to compose other complex functionality into readable chunks.

Let's revisit your nested example where you saved Post, Editor, and PostEditor. With Amplify's RxJava interface you can merge these operations together.

Completable.mergeArray(
RxAmplify.DataStore.save(post),
RxAmplify.DataStore.save(editor)
).andThen(
RxAmplify.DataStore.save(postEditor)
).subscribe(
() -> Log.i("RxAmplifyDemo", "Post, Editor, and PostEditor saved"),
failure -> Log.e("RxAmplifyDemo", "One or more items not saved", failure)
);

Compared to nesting these dependent calls in callbacks, this provides a much more readable pattern.

Install RxJava support

Amplify's RxJava support is included in an optional module, rxbindings. To start using the Rx APIs, add the following dependency to your application's Gradle file:

Under Gradle Scripts, open build.gradle (Module :app).

Add the following line in dependencies:

dependencies {
// Add the below line in `dependencies`
implementation 'com.amplifyframework:rxbindings:ANDROID_V1_VERSION'
}

Using Rx primitives

Amplify tries to map the behavior of your callback-based APIs to well-known Rx primitives in an intuitive way. Functions whose callbacks emit a single value (or error) will now return Rx Singles, instead. Functions whose callbacks emit no particular value will now return Rx Completables, instead. Lastly, functions whose callbacks emit a stream of values will now return Observables, instead.

Special cases with RxJava

Some APIs return an operation which can be cancelled. Examples include subscribing to an API or uploading or downloading objects from Storage.

API subscriptions with RxJava

The API category's subscribe() method exposes two Observables: one for subscription data, and one for connection state. You can access these Observables using observeConnectionState() and observeSubscriptionData() on the returned operation:

RxSubscriptionOperation<? extends GraphQLResponse<?>> subscription =
RxAmplify.API.subscribe(request);
subscription
.observeConnectionState()
.subscribe(
connectionStateEvent -> Log.i("RxAmplifyDemo", String.valueOf(connectionStateEvent))
);
subscription
.observeSubscriptionData()
.subscribe(
data -> Log.i("RxAmplifyDemo", "Data on subscription = " + data),
failure -> Log.e("RxAmplifyDemo", "Subscription failed", failure),
() -> Log.i("RxAmplifyDemo", "Subscription completed")
);

Storage upload and download operations with RxJava

The Storage category's downloadFile() and uploadFile() work largely the same way. uploadFile() and downloadFile() both return an operation containing a Single and an Observable. The Single can be used to obtain the result of the download, and the Observable can be used to monitor download/upload progress.

// Download
RxProgressAwareSingleOperation<StorageDownloadFileResult> download =
RxAmplify.Storage.downloadFile(remoteKey, localFile);
download
.observeProgress()
.subscribe(
progress -> Log.i("RxAmplifyDemo", "Download progress = " + progress.toString())
);
download
.observeResult()
.subscribe(
result -> Log.i("RxAmplifyDemo", "Download finished! " + result.getFile().getPath()),
failure -> Log.e("RxAmplifyDemo", "Download failed", failure)
);
// Upload
RxProgressAwareSingleOperation<StorageUploadFileResult> upload =
RxAmplify.Storage.uploadFile(remoteKey, localFile);
upload
.observeProgress()
.subscribe(
progress -> Log.i("RxAmplifyDemo", "Upload progress = " + progress.toString())
);
upload
.observeResult()
.subscribe(
result -> Log.i("RxAmplifyDemo", "Upload finished! " + result.getKey()),
failure -> Log.e("RxAmplifyDemo", "Upload failed", failure)
);

Use existing AWS resources

An application’s backend is built with cloud resources such as AWS AppSync GraphQL APIs, Amazon S3 storage, and Amazon Cognito authentication. The Amplify CLI simplifies the provisioning of new backend resources across these different categories. However, you can alternatively use the Amplify libraries to add or re-use existing AWS resources that you provisioned without the CLI. The Amplify libraries support configuration through the amplifyconfiguration.json file which defines all the regions and service endpoints for your backend AWS resources.

Add an existing AWS resource to an Android application

Before you can add an existing AWS resource to an Android application, the application must have the Amplify libraries installed. For detailed instructions, see Install Amplify Libraries.

1. Manually create the Amplify configuration file for your Android project

First, locate your project’s res folder. For example, if the name of your project is MyAmplifyApp, you can find the res folder at the following location, MyAmplifyApp/app/src/main/res:

Screenshot of the res folder in Android Studio's project explorer, from the path mentioned above

Next, in your project’s res folder, create a new folder named raw.

Finally, in the raw folder, create a file named amplifyconfiguration.json. At this point the contents of your amplifyconfiguration.json file can be an empty object, {}.

2. Initialize Amplify in your application

To initialize Amplify when your application is launched, you will need to create a new Application class and override its onCreate() method.

First, locate your application’s namespace where you will create the new application class. For example, if your application is named MyAmplifyApp, navigate to either MyAmplifyApp/app/src/main/java/com.example.MyAmplifyApp or MyAmplifyApp/app/src/main/kotlin/com.example.MyAmplifyApp depending on the programming language you are using.

From the Android Studio main menu, choose File -> New and select either Java Class or Kotlin File/Class depending your programming language.

Select Class, and specify a name for your new class in the Name field.

Paste the following code for the onCreate() method inside your new class:

public void onCreate() {
super.onCreate();
try {
Amplify.configure(getApplicationContext());
Log.i("MyAmplifyApp", "Initialized Amplify");
} catch (AmplifyException e) {
Log.e("MyAmplifyApp", "Could not initialize Amplify", e);
}
}
override fun onCreate() {
super.onCreate()
try {
Amplify.configure(applicationContext)
Log.i("MyAmplifyApp", "Initialized Amplify")
} catch (error: AmplifyException) {
Log.e("MyAmplifyApp", "Could not initialize Amplify", error)
}
}

Next, configure your application to use your new custom Application class. Open the AndroidManifest.xml file located in your project directory at app/src/main/AndroidManifest.xml.

Add the android:name attribute to the application node. For example, if the application name is MyAmplifyApp and the new class is named MyAmplifyApplication, the update to the AndroidManifest.xml file looks as follows:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.MyAmplifyApp">
<!-- Add the android:name attribute to the application node -->
<application
android:name=".MyAmplifyApplication"
...
</application>
</manifest>

3. Edit your configuration file to use an existing AWS resource

Now you’re ready to customize your application’s amplifyconfiguration.json file to specify an existing AWS resource to use.

Note that before you can add an AWS resource to your application, the application must have the Amplify libraries installed. If you need to perform this step, see Install Amplify Libraries.

Select a category from the following list to view an example amplifyconfiguration.json file you can use as a template to author your own amplifyconfiguration.json file: