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:
import android.app.Application;import android.util.Log;import com.amplifyframework.AmplifyException;import com.amplifyframework.core.Amplify;import com.amplifyframework.datastore.AWSDataStorePlugin;
Initialize Amplify by adding an onCreate
method with the following code:
public void onCreate() { super.onCreate();
try { Amplify.addPlugin(new AWSDataStorePlugin()); Amplify.configure(getApplicationContext()); Log.i("Tutorial", "Initialized Amplify"); } catch (AmplifyException error) { Log.e("Tutorial", "Could not initialize Amplify", error); }}
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:
import android.app.Applicationimport android.util.Logimport com.amplifyframework.AmplifyExceptionimport com.amplifyframework.core.Amplifyimport com.amplifyframework.datastore.AWSDataStorePlugin
Initialize Amplify by adding an onCreate
method with the following code:
override fun onCreate() { super.onCreate()
try { Amplify.addPlugin(AWSDataStorePlugin()) Amplify.configure(applicationContext)
Log.i("Tutorial", "Initialized Amplify") } catch (error: AmplifyException) { Log.e("Tutorial", "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 an 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" xmlns:tools="http://schemas.android.com/tools">
<!-- Add the android:name attribute to the application node --> <application android:name=".MyAmplifyApp" <!-- ... --> </application></manifest>
Build and run the application. In logcat, you'll see a log line indicating success:
com.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.
- Open
MainActivity
and add the following import statements at the top of the file:
import android.util.Log;import com.amplifyframework.AmplifyException;import com.amplifyframework.core.Amplify;import com.amplifyframework.core.model.temporal.Temporal;import com.amplifyframework.datastore.AWSDataStorePlugin;import com.amplifyframework.datastore.generated.model.Priority;import com.amplifyframework.datastore.generated.model.Todo;import java.util.*;import java.util.concurrent.TimeUnit;
import android.util.Logimport com.amplifyframework.AmplifyExceptionimport com.amplifyframework.core.Amplifyimport com.amplifyframework.core.model.temporal.Temporalimport com.amplifyframework.datastore.AWSDataStorePluginimport com.amplifyframework.datastore.generated.model.Priorityimport com.amplifyframework.datastore.generated.model.Todoimport java.util.*import java.util.concurrent.TimeUnit
- In the same file (
MainActivity
), add the following code to the bottom of theonCreate()
method:
Todo item = Todo.builder() .name("Build Android application") .priority(Priority.NORMAL) .build();
Amplify.DataStore.save(item, success -> Log.i("Tutorial", "Saved item: " + success.item().getName()), error -> Log.e("Tutorial", "Could not save item to DataStore", error));
val item = Todo.builder() .name("Build Android application") .priority(Priority.NORMAL) .build()
Amplify.DataStore.save(item, { Log.i("Tutorial", "Saved item: ${item.name}") }, { Log.e("Tutorial", "Could not save item to DataStore", it) })
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.
- After making the preceding updates to the
MainActivity
file, your code should look like the following:
package com.example.todo;
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import com.amplifyframework.core.Amplify;import com.amplifyframework.core.model.query.Where;import com.amplifyframework.core.model.temporal.Temporal;import com.amplifyframework.datastore.AWSDataStorePlugin;import com.amplifyframework.datastore.generated.model.Priority;import com.amplifyframework.datastore.generated.model.Todo;import java.util.*;import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
Todo item = Todo.builder() .name("Build Android application") .priority(Priority.NORMAL) .build();
Amplify.DataStore.save(item, success -> Log.i("Tutorial", "Saved item: " + success.item().getName()), error -> Log.e("Tutorial", "Could not save item to DataStore", error) ); }}
package com.example.todo
import androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.util.Logimport com.amplifyframework.core.Amplifyimport com.amplifyframework.core.model.query.Whereimport com.amplifyframework.core.model.temporal.Temporalimport com.amplifyframework.datastore.AWSDataStorePluginimport com.amplifyframework.datastore.generated.model.Priorityimport com.amplifyframework.datastore.generated.model.Todoimport java.util.*import java.util.concurrent.TimeUnit
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
val item = Todo.builder() .name("Build Android application") .priority(Priority.NORMAL) .build()
Amplify.DataStore.save(item, { Log.i("Tutorial", "Saved item: ${item.name}") }, { Log.e("Tutorial", "Could not save item to DataStore", it) } ) }}
- Build and run the application. In logcat, you'll see an indication that the item was saved successfully:
com.example.todo I/Tutorial: Initialized Amplifycom.example.todo I/Tutorial: Saved item: Build Android application
- Replace the item with a new Todo to save an additional item. Let's change the name and priority, and add a completedAt:
Date date = new Date();int offsetMillis = TimeZone.getDefault().getOffset(date.getTime());int offsetSeconds = (int) TimeUnit.MILLISECONDS.toSeconds(offsetMillis);Temporal.DateTime temporalDateTime = new Temporal.DateTime(date, offsetSeconds);Todo item = Todo.builder() .name("Finish quarterly taxes") .priority(Priority.HIGH) .completedAt(temporalDateTime) .build();
val date = Date()val offsetMillis = TimeZone.getDefault().getOffset(date.time).toLong()val offsetSeconds = TimeUnit.MILLISECONDS.toSeconds(offsetMillis).toInt()val temporalDateTime = Temporal.DateTime(date, offsetSeconds)val item = Todo.builder() .name("Finish quarterly taxes") .priority(Priority.HIGH) .completedAt(temporalDateTime) .build()
- Build and run the application. In logcat, you'll see an indication that the item was saved successfully:
com.example.todo I/Tutorial: Initialized Amplifycom.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.
- Edit your
onCreate
method to remove anything related to DataStore and replace it with the following code:
Amplify.DataStore.query(Todo.class, todos -> { while (todos.hasNext()) { Todo todo = todos.next();
Log.i("Tutorial", "==== Todo ===="); Log.i("Tutorial", "Name: " + todo.getName());
if (todo.getPriority() != null) { Log.i("Tutorial", "Priority: " + todo.getPriority().toString()); }
if (todo.getCompletedAt() != null) { Log.i("Tutorial", "CompletedAt: " + todo.getCompletedAt().toString()); } } }, failure -> Log.e("Tutorial", "Could not query DataStore", failure));
Amplify.DataStore.query(Todo::class.java, { todos -> while (todos.hasNext()) { val todo: Todo = todos.next() Log.i("Tutorial", "==== Todo ====") Log.i("Tutorial", "Name: ${todo.name}") todo.priority?.let { todoPriority -> Log.i("Tutorial", "Priority: $todoPriority") } todo.completedAt?.let { todoCompletedAt -> Log.i("Tutorial", "CompletedAt: $todoCompletedAt") } } }, { Log.e("Tutorial", "Could not query DataStore", it) })
- Run the application. In logcat, you'll see both items returned:
com.example.todo I/Tutorial: Initialized Amplifycom.example.todo I/Tutorial: ==== Todo ====com.example.todo I/Tutorial: Name: Build Android applicationcom.example.todo I/Tutorial: Priority: NORMALcom.example.todo I/Tutorial: ==== Todo ====com.example.todo I/Tutorial: Name: Finish quarterly taxescom.example.todo I/Tutorial: Priority: HIGHcom.example.todo I/Tutorial: CompletedAt: <DateTime>
- 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:
Amplify.DataStore.query(Todo.class, Where.matches(Todo.PRIORITY.eq(Priority.HIGH)), todos -> { while (todos.hasNext()) { Todo todo = todos.next();
Log.i("Tutorial", "==== Todo ===="); Log.i("Tutorial", "Name: " + todo.getName());
if (todo.getPriority() != null) { Log.i("Tutorial", "Priority: " + todo.getPriority().toString()); }
if (todo.getCompletedAt() != null) { Log.i("Tutorial", "Description: " + todo.getCompletedAt().toString()); } } }, failure -> Log.e("Tutorial", "Could not query DataStore", failure));
Amplify.DataStore.query( Todo::class.java, Where.matches(Todo.PRIORITY.eq(Priority.HIGH)), { todos -> while (todos.hasNext()) { val todo: Todo = todos.next() Log.i("Tutorial", "==== Todo ====") Log.i("Tutorial", "Name: ${todo.name}") todo.priority?.let { todoPriority -> Log.i("Tutorial", "Priority: $todoPriority") } todo.completedAt?.let { todoCompletedAt -> Log.i("Tutorial", "CompletedAt: $todoCompletedAt") } } }, { failure -> Log.e("Tutorial", "Could not query DataStore", failure) })
In the above code, notice the addition of the predicate parameter as the second argument.
- Run the application. In logcat, you'll see only the high priority item returned:
com.example.todo I/Tutorial: Initialized Amplifycom.example.todo I/Tutorial: ==== Todo ====com.example.todo I/Tutorial: Name: Finish quarterly taxescom.example.todo I/Tutorial: Priority: HIGHcom.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.
- Edit your
onCreate
method to remove anything related to DataStore and replace it with the following code:
Amplify.DataStore.query(Todo.class, Where.matches(Todo.NAME.eq("Finish quarterly taxes")), matches -> { if (matches.hasNext()) { Todo todo = matches.next(); Todo updatedTodo = todo.copyOfBuilder() .name("File quarterly taxes") .build(); Amplify.DataStore.save(updatedTodo, updated -> Log.i("Tutorial", "Updated item: " + updatedTodo.getName()), failure -> Log.e("Tutorial", "Update failed.", failure) ); } }, failure -> Log.e("Tutorial", "Query failed.", failure) );
Amplify.DataStore.query(Todo::class.java, Where.matches(Todo.NAME.eq("Finish quarterly taxes")), { matches -> if (matches.hasNext()) { val todo = matches.next() val updatedTodo = todo.copyOfBuilder() .name("File quarterly taxes") .build() Amplify.DataStore.save(updatedTodo, { Log.i("Tutorial", "Updated item: ${updatedTodo.name}") }, { Log.e("Tutorial", "Update failed.", it) } ) } }, { Log.e("Tutorial", "Query failed", it) })
-
Build and run the application. In your logcat, you'll see an indication that the item was updated successfully:
Initialized AmplifyUpdated item: File quarterly taxes
Delete a Todo
To round out CRUD operations, we'll query for a record and then delete it from DataStore.
- Edit your
onCreate()
method to remove anything related to DataStore and replace it with the following code:
Amplify.DataStore.query(Todo.class, Where.matches(Todo.NAME.eq("File quarterly taxes")), matches -> { if (matches.hasNext()) { Todo toDeleteTodo = matches.next(); Amplify.DataStore.delete(toDeleteTodo, deleted -> Log.i("Tutorial", "Deleted item: " + toDeleteTodo.getName()), failure -> Log.e("Tutorial", "Delete failed.", failure) ); } }, failure -> Log.e("Tutorial", "Query failed.", failure));
Amplify.DataStore.query(Todo::class.java, Where.matches(Todo.NAME.eq("File quarterly taxes")), { matches -> if (matches.hasNext()) { val toDeleteTodo = matches.next() Amplify.DataStore.delete(toDeleteTodo, { Log.i("Tutorial", "Deleted item: ${toDeleteTodo.name}") }, { Log.e("Tutorial", "Delete failed.", it) } ) } }, { Log.e("Tutorial", "Query failed.", it) } )
- Build and run the application. In the console output, you'll see an indication that the item was deleted successfully:
Initialized AmplifyDeleted 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.