Page updated Nov 11, 2023

Integrate your app

Next you'll use the generated model to read and write data. In this section you'll initialize DataStore, and create and query for Todo items.

Configure Amplify and DataStore

First, you'll add the DataStore plugin and configure Amplify.

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

Configure the new class in New Java Class:

  • Enter MyAmplifyApp in the Name field

  • Press OK

  • Extend MyAmplifyApp from android.app.Application by adding extends Application to your class

Add the following import statements at the top of the file:

1import android.app.Application;
2import android.util.Log;
3import com.amplifyframework.AmplifyException;
4import com.amplifyframework.core.Amplify;
5import com.amplifyframework.datastore.AWSDataStorePlugin;

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

1public void onCreate() {
2 super.onCreate();
3
4 try {
5 Amplify.addPlugin(new AWSDataStorePlugin());
6 Amplify.configure(getApplicationContext());
7 Log.i("Tutorial", "Initialized Amplify");
8 } catch (AmplifyException error) {
9 Log.e("Tutorial", "Could not initialize Amplify", error);
10 }
11}

Configure the new class in New Kotlin Class/File:

  • Enter MyAmplifyApp in the Name field

  • Press enter

  • Extend MyAmplifyApp from android.app.Application by adding : Application() to your class

Add the following import statements at the top of the file:

1import android.app.Application
2import android.util.Log
3import com.amplifyframework.AmplifyException
4import com.amplifyframework.core.Amplify
5import com.amplifyframework.datastore.AWSDataStorePlugin

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

1override fun onCreate() {
2 super.onCreate()
3
4 try {
5 Amplify.addPlugin(AWSDataStorePlugin())
6 Amplify.configure(applicationContext)
7
8 Log.i("Tutorial", "Initialized Amplify")
9 } catch (error: AmplifyException) {
10 Log.e("Tutorial", "Could not initialize Amplify", error)
11 }
12}

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 an android:name attribute with the value of your new class name:

1<?xml version="1.0" encoding="utf-8"?>
2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools">
4
5 <!-- Add the android:name attribute to the application node -->
6 <application
7 android:name=".MyAmplifyApp"
8 <!-- ... -->
9 </application>
10</manifest>

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

1com.example.MyAmplifyApp I/MyAmplifyApp: Initialized Amplify

To make this easier to find, enter the string MyAmplifyApp into the search field

Manipulating data

Create a Todo

Next, you'll create a Todo and save it to DataStore.

  1. Open MainActivity and add the following import statements at the top of the file:
1import android.util.Log;
2import com.amplifyframework.AmplifyException;
3import com.amplifyframework.core.Amplify;
4import com.amplifyframework.core.model.temporal.Temporal;
5import com.amplifyframework.datastore.AWSDataStorePlugin;
6import com.amplifyframework.datastore.generated.model.Priority;
7import com.amplifyframework.datastore.generated.model.Todo;
8import java.util.*;
9import java.util.concurrent.TimeUnit;
1import android.util.Log
2import com.amplifyframework.AmplifyException
3import com.amplifyframework.core.Amplify
4import com.amplifyframework.core.model.temporal.Temporal
5import com.amplifyframework.datastore.AWSDataStorePlugin
6import com.amplifyframework.datastore.generated.model.Priority
7import com.amplifyframework.datastore.generated.model.Todo
8import java.util.*
9import java.util.concurrent.TimeUnit
  1. In the same file ( MainActivity ), add the following code to the bottom of the onCreate() method:
1Todo item = Todo.builder()
2 .name("Build Android application")
3 .priority(Priority.NORMAL)
4 .build();
5
6Amplify.DataStore.save(item,
7 success -> Log.i("Tutorial", "Saved item: " + success.item().getName()),
8 error -> Log.e("Tutorial", "Could not save item to DataStore", error)
9);
1val item = Todo.builder()
2 .name("Build Android application")
3 .priority(Priority.NORMAL)
4 .build()
5
6Amplify.DataStore.save(item,
7 { Log.i("Tutorial", "Saved item: ${item.name}") },
8 { Log.e("Tutorial", "Could not save item to DataStore", it) }
9)

This code creates a Todo item with two properties: a name, and a priority, and then calls Amplify.DataStore.save() in order to store it on DataStore.

  1. After making the preceding updates to the MainActivity file, your code should look like the following:
1package com.example.todo;
2
3import androidx.appcompat.app.AppCompatActivity;
4import android.os.Bundle;
5import android.util.Log;
6import com.amplifyframework.core.Amplify;
7import com.amplifyframework.core.model.query.Where;
8import com.amplifyframework.core.model.temporal.Temporal;
9import com.amplifyframework.datastore.AWSDataStorePlugin;
10import com.amplifyframework.datastore.generated.model.Priority;
11import com.amplifyframework.datastore.generated.model.Todo;
12import java.util.*;
13import java.util.concurrent.TimeUnit;
14
15public class MainActivity extends AppCompatActivity {
16
17 @Override
18 protected void onCreate(Bundle savedInstanceState) {
19 super.onCreate(savedInstanceState);
20 setContentView(R.layout.activity_main);
21
22 Todo item = Todo.builder()
23 .name("Build Android application")
24 .priority(Priority.NORMAL)
25 .build();
26
27 Amplify.DataStore.save(item,
28 success -> Log.i("Tutorial", "Saved item: " + success.item().getName()),
29 error -> Log.e("Tutorial", "Could not save item to DataStore", error)
30 );
31 }
32}
1package com.example.todo
2
3import androidx.appcompat.app.AppCompatActivity
4import android.os.Bundle
5import android.util.Log
6import com.amplifyframework.core.Amplify
7import com.amplifyframework.core.model.query.Where
8import com.amplifyframework.core.model.temporal.Temporal
9import com.amplifyframework.datastore.AWSDataStorePlugin
10import com.amplifyframework.datastore.generated.model.Priority
11import com.amplifyframework.datastore.generated.model.Todo
12import java.util.*
13import java.util.concurrent.TimeUnit
14
15class MainActivity : AppCompatActivity() {
16 override fun onCreate(savedInstanceState: Bundle?) {
17 super.onCreate(savedInstanceState)
18 setContentView(R.layout.activity_main)
19
20 val item = Todo.builder()
21 .name("Build Android application")
22 .priority(Priority.NORMAL)
23 .build()
24
25 Amplify.DataStore.save(item,
26 { Log.i("Tutorial", "Saved item: ${item.name}") },
27 { Log.e("Tutorial", "Could not save item to DataStore", it) }
28 )
29 }
30}
  1. Build and run the application. In logcat, you'll see an indication that the item was saved successfully:
1com.example.todo I/Tutorial: Initialized Amplify
2com.example.todo I/Tutorial: Saved item: Build Android application
  1. Replace the item with a new Todo to save an additional item. Let's change the name and priority, and add a completedAt:
1Date date = new Date();
2int offsetMillis = TimeZone.getDefault().getOffset(date.getTime());
3int offsetSeconds = (int) TimeUnit.MILLISECONDS.toSeconds(offsetMillis);
4Temporal.DateTime temporalDateTime = new Temporal.DateTime(date, offsetSeconds);
5Todo item = Todo.builder()
6 .name("Finish quarterly taxes")
7 .priority(Priority.HIGH)
8 .completedAt(temporalDateTime)
9 .build();
1val date = Date()
2val offsetMillis = TimeZone.getDefault().getOffset(date.time).toLong()
3val offsetSeconds = TimeUnit.MILLISECONDS.toSeconds(offsetMillis).toInt()
4val temporalDateTime = Temporal.DateTime(date, offsetSeconds)
5val item = Todo.builder()
6 .name("Finish quarterly taxes")
7 .priority(Priority.HIGH)
8 .completedAt(temporalDateTime)
9 .build()
  1. Build and run the application. In logcat, you'll see an indication that the item was saved successfully:
1com.example.todo I/Tutorial: Initialized Amplify
2com.example.todo I/Tutorial: Saved item: Finish quarterly taxes

Query Todos

Now that you have some data in DataStore, you can run queries to retrieve those records.

  1. Edit your onCreate method to remove anything related to DataStore and replace it with the following code:
1Amplify.DataStore.query(Todo.class,
2 todos -> {
3 while (todos.hasNext()) {
4 Todo todo = todos.next();
5
6 Log.i("Tutorial", "==== Todo ====");
7 Log.i("Tutorial", "Name: " + todo.getName());
8
9 if (todo.getPriority() != null) {
10 Log.i("Tutorial", "Priority: " + todo.getPriority().toString());
11 }
12
13 if (todo.getCompletedAt() != null) {
14 Log.i("Tutorial", "CompletedAt: " + todo.getCompletedAt().toString());
15 }
16 }
17 },
18 failure -> Log.e("Tutorial", "Could not query DataStore", failure)
19);
1Amplify.DataStore.query(Todo::class.java,
2 { todos ->
3 while (todos.hasNext()) {
4 val todo: Todo = todos.next()
5 Log.i("Tutorial", "==== Todo ====")
6 Log.i("Tutorial", "Name: ${todo.name}")
7 todo.priority?.let { todoPriority -> Log.i("Tutorial", "Priority: $todoPriority") }
8 todo.completedAt?.let { todoCompletedAt -> Log.i("Tutorial", "CompletedAt: $todoCompletedAt") }
9 }
10 },
11 { Log.e("Tutorial", "Could not query DataStore", it) }
12)
  1. Run the application. In logcat, you'll see both items returned:
1com.example.todo I/Tutorial: Initialized Amplify
2com.example.todo I/Tutorial: ==== Todo ====
3com.example.todo I/Tutorial: Name: Build Android application
4com.example.todo I/Tutorial: Priority: NORMAL
5com.example.todo I/Tutorial: ==== Todo ====
6com.example.todo I/Tutorial: Name: Finish quarterly taxes
7com.example.todo I/Tutorial: Priority: HIGH
8com.example.todo I/Tutorial: CompletedAt: <DateTime>
  1. Queries can also contain predicate filters. These will query for specific objects matching a certain condition.

The following predicates are supported:

Strings

eq ne le lt ge gt contains notContains beginsWith between

Numbers

eq ne le lt ge gt between

Lists

contains notContains

To use a predicate, pass an additional argument into your query. For example, the following code queries for all high priority items:

1Amplify.DataStore.query(Todo.class,
2 Where.matches(Todo.PRIORITY.eq(Priority.HIGH)),
3 todos -> {
4 while (todos.hasNext()) {
5 Todo todo = todos.next();
6
7 Log.i("Tutorial", "==== Todo ====");
8 Log.i("Tutorial", "Name: " + todo.getName());
9
10 if (todo.getPriority() != null) {
11 Log.i("Tutorial", "Priority: " + todo.getPriority().toString());
12 }
13
14 if (todo.getCompletedAt() != null) {
15 Log.i("Tutorial", "Description: " + todo.getCompletedAt().toString());
16 }
17 }
18 },
19 failure -> Log.e("Tutorial", "Could not query DataStore", failure)
20);
1Amplify.DataStore.query(
2 Todo::class.java, Where.matches(Todo.PRIORITY.eq(Priority.HIGH)),
3 { todos ->
4 while (todos.hasNext()) {
5 val todo: Todo = todos.next()
6 Log.i("Tutorial", "==== Todo ====")
7 Log.i("Tutorial", "Name: ${todo.name}")
8 todo.priority?.let { todoPriority -> Log.i("Tutorial", "Priority: $todoPriority") }
9 todo.completedAt?.let { todoCompletedAt -> Log.i("Tutorial", "CompletedAt: $todoCompletedAt") }
10 }
11 },
12 { failure -> Log.e("Tutorial", "Could not query DataStore", failure) }
13)

In the above code, notice the addition of the predicate parameter as the second argument.

  1. Run the application. In logcat, you'll see only the high priority item returned:
1com.example.todo I/Tutorial: Initialized Amplify
2com.example.todo I/Tutorial: ==== Todo ====
3com.example.todo I/Tutorial: Name: Finish quarterly taxes
4com.example.todo I/Tutorial: Priority: HIGH
5com.example.todo I/Tutorial: CompletedAt: <DateTime>

Update a Todo

You may want to change the contents of a record. Below, we'll query for a record, create a copy of it, modify it, and save it back to DataStore.

  1. Edit your onCreate method to remove anything related to DataStore and replace it with the following code:
1Amplify.DataStore.query(Todo.class, Where.matches(Todo.NAME.eq("Finish quarterly taxes")),
2 matches -> {
3 if (matches.hasNext()) {
4 Todo todo = matches.next();
5 Todo updatedTodo = todo.copyOfBuilder()
6 .name("File quarterly taxes")
7 .build();
8 Amplify.DataStore.save(updatedTodo,
9 updated -> Log.i("Tutorial", "Updated item: " + updatedTodo.getName()),
10 failure -> Log.e("Tutorial", "Update failed.", failure)
11 );
12 }
13 },
14 failure -> Log.e("Tutorial", "Query failed.", failure)
15 );
1Amplify.DataStore.query(Todo::class.java, Where.matches(Todo.NAME.eq("Finish quarterly taxes")),
2 { matches ->
3 if (matches.hasNext()) {
4 val todo = matches.next()
5 val updatedTodo = todo.copyOfBuilder()
6 .name("File quarterly taxes")
7 .build()
8 Amplify.DataStore.save(updatedTodo,
9 { Log.i("Tutorial", "Updated item: ${updatedTodo.name}") },
10 { Log.e("Tutorial", "Update failed.", it) }
11 )
12 }
13 },
14 { Log.e("Tutorial", "Query failed", it) }
15)
  1. Build and run the application. In your logcat, you'll see an indication that the item was updated successfully:

    1Initialized Amplify
    2Updated item: File quarterly taxes

Delete a Todo

To round out CRUD operations, we'll query for a record and then delete it from DataStore.

  1. Edit your onCreate() method to remove anything related to DataStore and replace it with the following code:
1Amplify.DataStore.query(Todo.class, Where.matches(Todo.NAME.eq("File quarterly taxes")),
2 matches -> {
3 if (matches.hasNext()) {
4 Todo toDeleteTodo = matches.next();
5 Amplify.DataStore.delete(toDeleteTodo,
6 deleted -> Log.i("Tutorial", "Deleted item: " + toDeleteTodo.getName()),
7 failure -> Log.e("Tutorial", "Delete failed.", failure)
8 );
9 }
10 },
11 failure -> Log.e("Tutorial", "Query failed.", failure)
12);
1Amplify.DataStore.query(Todo::class.java, Where.matches(Todo.NAME.eq("File quarterly taxes")),
2 { matches ->
3 if (matches.hasNext()) {
4 val toDeleteTodo = matches.next()
5 Amplify.DataStore.delete(toDeleteTodo,
6 { Log.i("Tutorial", "Deleted item: ${toDeleteTodo.name}") },
7 { Log.e("Tutorial", "Delete failed.", it) }
8 )
9 }
10 },
11 { Log.e("Tutorial", "Query failed.", it) }
12 )
  1. Build and run the application. In the console output, you'll see an indication that the item was deleted successfully:
1Initialized Amplify
2Deleted item: File quarterly taxes

Almost done

We just reached a very cool checkpoint. We have a fully featured CRUD application that saves and retrieves data in the local device, which means the app works without an AWS account and even without internet connection.

Next, let's connect it to AWS and make sure the data available in the cloud.