ActiveAndroid – Create and manipulate a database in Android within 1 music note

Hello everyone, its a very long time to return Blog tutorial on Android. Last time I had written 5 picture database trong android. Really it is a series of very dedicated his, however after much work with the database, recognize their common usage so it is too hard to 1 £, not to mention a database with multiple tables. Therefore disease arises lazy and think whether there is something or some way that just “1 music note” also create a complex database. And I have found it – ActiveAndroid.

ActiveAndroid homepage here: http://www.activeandroid.com/
However I just read on their github severance, you can see here: https://github.com/pardom/ActiveAndroid

In this article, I will guide you to make an application for friend lists (save names Friend) simply build a database with Android Studio ActiveAndroid 2.0

friendlist_activeandroid

1. Configuring build.gradle

We configure the following:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.nguyenvanquan7826.friendlist"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    // for activeandroid
    repositories {
        mavenCentral()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:design:23.3.0'
    compile 'com.android.support:cardview-v7:23.3.0'
    compile 'com.android.support:recyclerview-v7:23.3.0'

    // for activeandroid
    compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
}

In noting that the line to load the library activeandroid

repositories {
    mavenCentral()
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'

2. Configuration manifest

In the application's AndroidManifest.xml card you add the following attributes:

<application
    android:name="com.activeandroid.app.Application"
    ...
    
    <meta-data
        android:name="AA_DB_NAME"
        android:value="friendlist.db" />
    <meta-data
        android:name="AA_DB_VERSION"
        android:value="1" />
    <meta-data
        android:name="AA_MODELS"
        android:value="com.nguyenvanquan7826.friendlist.Friend" />
    
    ...
</application>

In this you pay attention:

  • AA_DB_NAME is keyword identification database name (friendlist.db)

  • AA_DB_VERSION is keyword identification database version (Current version 1), later upgraded database you just fix here alone

  • AA_MODELS the keywords that the database tables. These tables are our classes (enclosed package), little while I'll say more. Normally we do not need meta-data of AA_MODELS, but to process structured database load faster and if desired for Android 6 run you let on. In the case of multiple tables, the way you record a comma as follows:
    com.nguyenvanquan7826.friendlist.Friend, com.nguyenvanquan7826.friendlist.Lover

  • android:name=”com.activeandroid.app.Application” Here is the declaration for our application using Application know of activeandroid. If you are using an Application of other libraries that you can use legacy Application com.activeandroid.app.Application. Or if you do not want to inherit from, you can custom com.activeandroid.app.Application Application your current file as follows:

public class MyApplication extends SomeLibraryApplication {
    @Override
    public void onCreate() {
        super.onCreate();
        Configuration dbConfiguration = new Configuration.Builder(this).setDatabaseName("xxx.db").create();
        ActiveAndroid.initialize(dbConfiguration);
    }
}

3. Interface Design

Defined color in the file res/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <color name="white">#FFFFFF</color>
    <color name="black">#000000</color>
    <color name="background_activity">#F5F5F5</color>
    <color name="transparent">#00000000</color>
</resources>

Define the strings in files res/values/strings.xml

<resources>
    <string name="app_name">FriendList</string>
    <string name="action_settings">Settings</string>

    <string name="name">Name</string>
    <string name="phone">Phone</string>
    <string name="add">Add</string>
    <string name="update">Update</string>
    <string name="edit">Edit</string>
    <string name="delete">Delete</string>

    <string name="delete_success">Delete success</string>
    <string name="delete_fail">Delete fail</string>

    <string name="save_success">Save success</string>
    <string name="save_fail">Save fail</string>

    <string name="update_success">Update success</string>
    <string name="update_fail">Update fail</string>

    <string name="please_enter_name">Please enter name</string>
    <string name="please_enter_phone">Please enter phone</string>
</resources>

The main layout definition. Our main layout included 2 file (Android Studio spontaneously to us when creating Project). If you do not like it absolutely can be grouped into 1 file.

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.nguyenvanquan7826.friendlist.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

</android.support.design.widget.CoordinatorLayout>

res/layout/content_main.xml This file contains the main content of the interface

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.nguyenvanquan7826.friendlist.MainActivity"
    tools:showIn="@layout/activity_main">

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/editName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/name"
            android:singleLine="true" />

    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/editPhone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/phone"
            android:inputType="phone"
            android:singleLine="true" />

    </android.support.design.widget.TextInputLayout>

    <Button
        android:id="@+id/btnAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@string/add" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

res/layout/item_friend.xml the interface file 1 item in the list

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="4dp"
    android:background="@color/white"
    android:foreground="?android:attr/selectableItemBackground"
    card_view:cardCornerRadius="2dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="4dp">

        <ImageView
            android:id="@+id/icFriend"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_centerVertical="true"
            android:layout_marginRight="4dp"
            android:src="@drawable/ic_friend" />

        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/icFriend"
            android:text="@string/name"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tvPhone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tvName"
            android:layout_toRightOf="@+id/icFriend"
            android:text="@string/phone" />

        <ImageView
            android:id="@+id/btnMore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:src="@drawable/ic_more" />
    </RelativeLayout>
</android.support.v7.widget.CardView>

4. Creating a data layer – class Friend

The creation of this very important class Friend, it is not only the class to create objects Friend Friend but also our table in the database.
We created the following class:

package com.nguyenvanquan7826.friendlist;

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

@Table(name = "tbFriend")
public class Friend extends Model {

    public static final String NAME = "name";
    public static final String PHONE = "phone";

    @Column(name = NAME)
    private String name;

    @Column(name = PHONE)
    private String phone;


    public String getName() {
        return name;
    }

    public Friend setName(String name) {
        this.name = name;
        return this;
    }

    public String getPhone() {
        return phone;
    }

    public Friend setPhone(String phone) {
        this.phone = phone;
        return this;
    }
}

In this class you pay attention:

  • class Friend inherited from class Model of com.activeandroid, we need to inherit it can create data tables and queries using commands for this class Friend.

  • @Table(name = “tbFriend”) definition is the table name tbFriend in the database. This command writes the name of the class on the table you want it.

  • @Column(name = PHONE) defined column phone in the table tbFriend

5. create adapter

In this section we need to create 1 adapter so that each item are 1 menu button (knot 3 dot). This button to display 1 menu (edit, delete) when clicking on. To achieve this we need to create 1 PopupMenu từ file menu.

res/menu/menu_item_friend.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.nguyenvanquan7826.friendlist.MainActivity">
    <item
        android:id="@+id/menu_edit"
        android:orderInCategory="100"
        android:title="@string/edit"
        app:showAsAction="never" />
    <item
        android:id="@+id/menu_delete"
        android:orderInCategory="100"
        android:title="@string/delete"
        app:showAsAction="never" />
</menu>

Next to start the event for the edit and delete menu may be we need to create 1 interface to transmit information on the treatment MainActivity.

AdapterFriend.java

package com.nguyenvanquan7826.friendlist;

import android.content.Context;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

public class AdapterFriend extends RecyclerView.Adapter<AdapterFriend.RecyclerViewHolder> {
    private List<Friend> list;
    private Context context;

    public AdapterFriend(Context context, List<Friend> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
        View itemView = inflater.inflate(R.layout.item_friend, viewGroup, false);
        return new RecyclerViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder viewHolder, int position) {
        Friend friend = list.get(position);
        viewHolder.tvName.setText(friend.getName());
        viewHolder.tvPhone.setText(friend.getPhone());
    }


    public class RecyclerViewHolder extends RecyclerView.ViewHolder {

        public TextView tvName;
        public TextView tvPhone;

        // for show menu edit and delete
        private PopupMenu popupMenu;

        public RecyclerViewHolder(View itemView) {
            super(itemView);

            tvName = (TextView) itemView.findViewById(R.id.tvName);
            tvPhone = (TextView) itemView.findViewById(R.id.tvPhone);
            itemView.findViewById(R.id.btnMore).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    popupMenu.show();
                }
            });
            setPopup(itemView);
        }

        /*
        * when show popup menu, we can click edit or delete menu item.
        * so we need create a interface to sent position for main activity process
        * */
        private void setPopup(View view) {
            popupMenu = new PopupMenu(context, view);
            popupMenu.getMenuInflater().inflate(R.menu.menu_item_friend, popupMenu.getMenu());
            popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.menu_edit:
                            if (listener != null) {
                                listener.edit(getAdapterPosition());
                            }
                            break;
                        case R.id.menu_delete:
                            if (listener != null) {
                                listener.del(getAdapterPosition());
                            }
                            break;
                    }
                    return true;
                }
            });
        }
    }

    public interface AdapterFriendListener {
        void del(int position);

        void edit(int position);
    }

    private AdapterFriendListener listener;

    public AdapterFriend setListener(AdapterFriendListener listener) {
        this.listener = listener;
        return this;
    }
}

6. Write handled in MainActivity

In MainActivity we 3 Key tasks include Add to handle, Repair, Erase. Adding and editing are very similar, if we add a new creation, if we consider the correct position to be modified over 1 turn positionEdit.

MainActivity.java

package com.nguyenvanquan7826.friendlist;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.activeandroid.query.Select;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MainActivity extends AppCompatActivity implements AdapterFriend.AdapterFriendListener {

    private Context context;

    private EditText editName;
    private EditText editPhone;
    private Button btnAdd;

    private AdapterFriend adapter;
    private ArrayList<Friend> list;

    /*
    * index of item need edit
    * if positionEdit = -1 then we not need edit item, so when click btnAdd we insert into database
    * if positionEdit >= 0  then we need eidt item, so when click btnAdd we update item inti database
    * */
    private int positionEdit = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;

        setContentView(R.layout.activity_main);
        connectView();
        reloadData();
    }

    private void connectView() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv);
        recyclerView.setHasFixedSize(false);
        LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new AdapterFriend(context, list = new ArrayList<>());
        adapter.setListener(this);
        recyclerView.setAdapter(adapter);

        editName = (EditText) findViewById(R.id.editName);
        editPhone = (EditText) findViewById(R.id.editPhone);
        btnAdd = (Button) findViewById(R.id.btnAdd);
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                add();
            }
        });
    }

    private void add() {
        String name = editName.getText().toString().trim();
        String phone = editPhone.getText().toString().trim();

        if (TextUtils.isEmpty(name)) {
            editName.requestFocus();
            Toast.makeText(context, R.string.please_enter_name, Toast.LENGTH_SHORT).show();
            return;
        }
        if (TextUtils.isEmpty(phone)) {
            editPhone.requestFocus();
            Toast.makeText(context, R.string.please_enter_phone, Toast.LENGTH_SHORT).show();
            return;
        }
        Friend friend;
        // we not need edit
        if (positionEdit < 0) {
            friend = new Friend();
        } else { // we need edit
            friend = list.get(positionEdit);
        }

        friend.setName(name).setPhone(phone).save();
        reloadData();

        editName.setText("");
        editPhone.setText("");
        btnAdd.setText(R.string.add);
        editName.requestFocus();

        Toast.makeText(context, R.string.save_success, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void del(int position) {
        Friend.delete(Friend.class, list.get(position).getId());
        reloadData();
        Toast.makeText(context, R.string.delete_success, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void edit(int position) {
        positionEdit = position;
        editName.setText(list.get(position).getName());
        editPhone.setText(list.get(position).getPhone());
        btnAdd.setText(R.string.update);
        editName.requestFocus();
    }

    private void reloadData() {
        List<Friend> ls = new Select().from(Friend.class).execute();
        list.clear();
        list.addAll(ls);
        Collections.reverse(list);
        adapter.notifyDataSetChanged();
    }
}

In the code on your attention:

  • To save or insert 1 records (1 object) we just need to call the method save()

  • To retrieve a list of items we use new Select().from(Friend.class).execute()

  • To delete a record we use methods delete.

These are very basic instructions to use his ActiveAndroid database manipulation within “a musical note”. To be able to understand and implement many other things you see Their wiki

You can Project download friend lists here

Posts made in the tutorial Database trong Android by nguyenvanquan7826

Having fun.