Creating an Android application with Vertabelo Mobile ORM

1. Introduction

In this tutorial you will learn how to develop your first database-based Android application from scratch with Vertabelo Mobile ORM. Next sections show in several simple steps how to create Android application using IDE (in our case this will be Android Studio but you can choose other enviroment), design database schema using Vertabelo, generate O/R Maping with Gradle plugin and finally, integrate Android app with SQLite database. During this tutorial we'll develop simple Contact Book application which will be able to insert contacts into database and display them all.

Before you start you need:

  • Android Studio 1.3 or newer
  • Gradle 2.5 or newer
  • Vertabelo account, at least basic or trial plan.

So let's get started!

2. New Android project

First, create blank Android project in your IDE. In Android Studio click File->New Project and follow the project creator. If you're using other IDE, make sure that your project is built with Gradle.

3. Database schema design with Vertabelo

Log into your Vertabelo account and create new database model.

On the next screen, name your model, choose SQLite database engine and click Start Modeling.

Now you should see schema diagram creator. In our example we need database with one table, contact and four columns: id, first_name, last_name and number where id is a primary key. You should achieve the following effect:

4. Generating Vertabelo Mobile ORM

4.1. Generating ORM in Vertabelo

Now it's time to generate O/R mapping for the model which we have created. The simpliest way to do that is to use a button in Vertabelo itself. Click on the button shown below, set proper package name and download .zip file.

Now you should unpack content of the archive into app/src directory of your project. After doing so, project file tree has to look similar to that:

And that's it, now you can start using Vertabelo Mobile ORM!

4.2. Generating ORM using Gradle plugin

There is also alternative way of generating Vertabelo Mobile ORM - using our Gradle plugin. To do that, first we need to generate and download XML file which represents database schema.

Create assets directory in app/src/main/ folder in your app's file tree, click XML button on Vertabelo and save the file in the created folder.

Now we should modify build.gradle files. Note that there are two of them - one in main project directory and one in app folder. Make the first one look like this:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
        classpath 'com.mobiorm.gradle:mobiorm:1.0.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}


allprojects {
    repositories {
        jcenter()
    }
}
            

Here we added only one line in the build.dependencies section: classpath 'com.mobiorm.gradle:mobiorm:1.0.1'.

Now open the one in app folder and add the following lines to it:

apply plugin: 'mobiorm'

mobiorm {
    modelFile = 'app/src/main/assets/Tutorial_2015-09-09_11-02.xml'
    destDir = 'app/src/main/java'
    packageName = 'pl.epoint.mobiorm.tutorial.orm'
}
            

We did two things:

  • added apply plugin: 'mobiorm' in the second line
  • at the end of the script we set three options of the plugin:
    • modelFile is a path to XML file which we downloaded from Vertabelo
    • destDir is a directory where generated file will be unpacked, in most cases it should be src/main/java
    • packageName is a package name for newly generated Java classes

Now we have to execute orm-generate gradle task in app directory. We can do that through Android Studio. At a right panel of IDE find gradle button. You should see Gradle projects menu. Now click Execute Gradle Task button, choose :app project, write orm-generate in command line field and click OK.

If everything went right, you will find freshly generated O/R mapping sources in your src/main/java directory.

4.2.1. Executing Gradle task from command line

If you're using Linux or OS X, you can also generate Vertabelo Mobile ORM code from command line. To do so, get into the main project directory and execute Gradle task with following comand:

$ gradle :app:orm-generate
              

4.3. Generating with Gradle plugin using Vertabelo API

We can make using Vertabelo Mobile ORM Gradle plugin even easier using Vertabelo API. To do so, we don't have to download XML file. Instead of that, let's make mobiorm section in app/build.gradle file look similar to that:

mobiorm {
    vertabelo.modelId = 'LuRb3otRU6xRERA45nm5gM6FXhTX3H6YVgyVteeYuKzXk81LdTUCDrU4ZqSCJHeh'
    vertabelo.apiToken = 'VenmtiFCpW1K3d8fHAw8ABPBMtKGEdZp6EOIVWxms4Jk7Gmx0Jz0HwMXeVXGkMd4'
    destDir = 'app/src/main/java'
    packageName = 'pl.epoint.mobiorm.tutorial.orm'
}
            

Now let's take a look where to get these vertabelo.modelId and vertabelo.apiToken parameterers from. Go your My account page in Vertabelo.

Find Settings area and enable API access. Copy API token and use it as vertabelo.apiToken parameter.

Now go back to your Dashboard, find your model and to to its Details section.

Find identifier of the model, copy it and use as vertabelo.modelId parameter.

Now we can genertate ORM code like in the previous paragraph, but this time we use vertabelo-orm-generate command instead of orm-generate.

5. Creating SQLite database

In order to create SQLite database on Android, first we need to obtain SQL script which can do it. Luckily, Vertabelo can generate it for us. Next to XML button is an SQL button. Click it, then click generate, save the file in app/src/main/res/raw directory and rename it to tutorial_create.sql. If raw directory doesn't exist, create it.

To make use of Vertabelo Mobile ORM, we have to create SQLite database first. Usually in Android we need to extend SQLiteOpenHelper class. Vertabelo Mobile ORM provides easier and faster way to do that, using SimpleSQLiteOpenHelper. All we have to do is to provide database name and version number and implement configure method which specifies which scripts should be run on creation and migration time. In our case we have only one creation script: tutorial_create, but we could specify any number of them, calling addCreationScript method multiple times.

public class TutorialSQLiteOpenHelper extends SimpleSQLiteOpenHelper {

    private static final String DATABASE_NAME = "tutorial";

    private static final int DATABASE_VERSION = 1;

    public TutorialSQLiteOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void configure() {
        addCreationScript(R.raw.tutorial_create);
    }
}
            

If you want to understand how SimpleSQLiteOpenHelper works deeper, here you can find more info about mechanism behind that.

6. Activity inserting data into database

Now, to see Vertabelo Mobile ORM in action we'll create two activities:

  • MainActivity, which is already created by IDE but it's blank yet, it will display list of all contacts in the database
  • AddContactActivity, used to add new contact into database

Let's start from the second one. Open the activity_add_contact.xml in design mode and add the following elements:

  • three EditText fields:
    • firstNameEditText
    • lastNameEditText
    • numberEditText
  • button called insertContactButton.

Final result should look similar to that:

Now add the following method to AddContactActivity:

public void addContact(View view) {
        TextView firstNameView = (TextView)findViewById(R.id.firstNameEditText);
        TextView lastNameView = (TextView)findViewById(R.id.lastNameEditText);
        TextView numberView = (TextView)findViewById(R.id.numberEditText);

        String firstName = firstNameView.getText().toString();
        String lastName = lastNameView.getText().toString();
        String number = numberView.getText().toString();

        Contact contact = new Contact();
        contact.setFirstName(firstName);
        contact.setLastName(lastName);
        contact.setNumber(number);

        SimpleSQLiteOpenHelper helper = new TutorialSQLiteOpenHelper(this.getApplicationContext());
        ContactDAO contactDAO = new ContactDAOImpl(helper);

        contactDAO.insert(contact);

        finish();
    }
            

Set the above method as an insertContactButton.onClick attribute. To do so, click on Component tree button on the right, find onclick attribute and set it to addContact, jut like at the following pictures:

As you can see, this method inserts contact into database according to values in EditText fields of the activity. This is the first time we used Vertabelo Mobile ORM to perform database operation. Let's take a look at these lines:

SimpleSQLiteOpenHelper helper = new TutorialSQLiteOpenHelper(this.getApplicationContext());
ContactDAO contactDAO = new ContactDAOImpl(helper);
contactDAO.insert(contact);
            

To perform any database operation, e.g. insert, select or delete some records we need to obtain DAO (Data Access Object). You can read more about it here. For every table in database there is a DAO interface, in this case ContactDAO and its implementation - ContactDAOImpl.

Every DAO object needs to get SQLiteDataSource in its constructor. SQLiteDataSource is an interface providing access to SQLite database. In our example we used previously created TutorialSQLiteOpenHelper extending SimpleSQLiteOpenHelper which implements this interface.

7. Activity displaying selected data

Now let's add a button to MainActivity to transit to AddContactActivity. Let new button be called addContactButton and set its onClick method to the following one:

public void addContact(View view) {
    Intent intent = new Intent(MainActivity.this, AddContactActivity.class);

    startActivity(intent);
}
            

As you can see, this method does nothing but transition between screens.

It's time to display contacts which we already can insert into database. To do that, we will add ListView element to the main activity. Open activity_main.xml in Design mode. Find ListView in containers and add it to the activity. Let's name it contactListView.

Now we need one more thing: layout of the single element of the list. Create my_list_item.xml file in res/layout directory and copy the following content to it:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/tv"
          android:textColor="@android:color/black"
          android:padding="5sp"
          android:layout_width="fill_parent"
          android:background="@android:color/white"
          android:singleLine="true"
          android:gravity="center"
          android:layout_height="fill_parent"/>
            

Finally, we can modify MainActivity so that it displays all contacts in database. New version of the class looks as follows:

public class MainActivity extends AppCompatActivity {

    private ContactDAO contactDAO;

    private List contactList = new LinkedList();

    private ArrayAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        contactDAO = new ContactDAOImpl(new TutorialSQLiteOpenHelper(this.getApplicationContext()));

        ListView listView = (ListView) findViewById(R.id.contactListView);
        adapter = new ArrayAdapter(this.getApplicationContext(),
                R.layout.my_list_item, contactList);
        listView.setAdapter(adapter);
    }

    @Override
    protected void onResume() {
        super.onResume();

        contactList.clear();
        contactList.addAll(contactDAO.getContactList());
        adapter.notifyDataSetChanged();
    }

    public void addContact(View view) {
        Intent intent = new Intent(MainActivity.this, AddContactActivity.class);

        startActivity(intent);
    }
}
            

In onCreate method we set the ArrayAdapter to contactListView and create DAO object which we use to select data from database in onResume. Take a look at the line:

contactList.addAll(contactDAO.getContactList());
            

Here we call getContactList() method, which returns all rows from database in form of a list containing Contact objects. When we call

adapter.notifyDataSetChanged();
            

contactListView displays already selected contacts' toString() methods. Now we can run our application, insert some contacts and see the result similar to that:

Well, as you can see, Vertabelo Mobile ORM works! Now we can insert contacts and see them. But, maybe that's not exactly what we expected to see because toString() methods are not very readable by default. To repair this, we can write custom adapter. Add class TutorialArrayAdapter to the project:

public class TutorialArrayAdapter extends ArrayAdapter {

    public TutorialArrayAdapter(Context context, int resource, List objects) {
        super(context, resource, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView textView = (TextView) super.getView(position, convertView, parent);
        Contact contact = (Contact) getItem(position);
        textView.setText(contact.getFirstName() + " " + contact.getLastName() + " - " + contact.getNumber());
        return textView;
    }

}
            

Now we should change ArrayAdapter to our newly created class in MainActivity:

public class MainActivity extends AppCompatActivity {

    private ContactDAO contactDAO;

    private List contactList = new LinkedList();

    private TutorialArrayAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        contactDAO = new ContactDAOImpl(new TutorialSQLiteOpenHelper(this.getApplicationContext()));

        ListView listView = (ListView) findViewById(R.id.contactListView);
        adapter = new TutorialArrayAdapter(this.getApplicationContext(),
                R.layout.my_list_item, contactList);
        listView.setAdapter(adapter);
    }

    @Override
    protected void onResume() {
        super.onResume();

        contactList.clear();
        contactList.addAll(contactDAO.getContactList());
        adapter.notifyDataSetChanged();
    }

    public void addContact(View view) {
        Intent intent = new Intent(MainActivity.this, AddContactActivity.class);

        startActivity(intent);
    }
}
            

We changed two lines:

private TutorialArrayAdapter adapter;
            

And:

adapter = new TutorialArrayAdapter(this.getApplicationContext(),
                R.layout.my_list_item, contactList);
            

Now the final effect looks much better:

8. Summary

Now we have small application which performs elementary database operation using Vertabelo Mobile ORM. If you want to know what more Vertabelo Mobile ORM can do, take a look at DAO Guide and Query Language Guide.