Storing data is a basic and very common need in mobile apps. The Android application framework provides several storage options, one of which is SQLite databases.
In this tutorial you will see a simple Android database example. The example is based on the Android ListView Tutorial and the Android AsyncTask Tutorial, however these tutorials are not mandatory for the purpose of understanding the principles of proper Android database usage.
2. Android Database Tutorial
Storing data is a basic and very common need in mobile apps. The Android application framework provides several storage options, one of which is SQLite
databases.
In this tutorial you will see a simple Android database example. The example is based on the Android ListView Tutorial and the Android AsyncTask Tutorial,
however these tutorials are not mandatory for the purpose of understanding the principles of proper Android database usage.
The usage of Android SQLite databases is simplified using the SQLiteOpenHelper class. In this example we will use the a SQLite database for storing the
number of user clicks on each of the ListView items from the Android ListView Tutorial, and each time the user return to the app, the list items will be
ordered according to his preferences.
Because loading data from the database and sorting it takes time, we will use an AsyncTask for loading and sorting in a background thread, as shown in
the Android AsyncTask Tutorial.
Please note that the icon set for this example was created by Design Deck.
The example for this tutorial is contains the following components:
● Entity Class - the class used for describing objects that are stored in the database.
● Database Helper - the SocialItemsDatabaseHelper that extends the SQLiteOpenHelper class.
● ListView Item - the class used for ListView items. This is the same class used in the Android ListView Tutorial.
● List Adapter - This class is based on the list adapter from the Android ListView Tutorial.
3. Entity Class
The SocialItem class below contains a String for the title and a long for the number of user clicks in the list item. It also implements the Comparable interface for sorting the
items:
1. public class SocialItem implements Comparable<SocialItem> {
2. public final String title; // the text for the ListView item title
3. private long numClicks; // the number of user clicks on this item
4.
5. public SocialItem(String title) {
6. this.title = title;
7. numClicks = 0;
8. }
9. public SocialItem(String title, long numClicks) {
10. this.title = title;
11. this.numClicks = numClicks;
12. }
4. Database Helper
the SocialItemsDatabaseHelper below extends the SQLiteOpenHelper and is used for send SQLite queries to the database for loading,
storing and updating data:
1. public class SocialItemsDatabaseHelper extends SQLiteOpenHelper {
2. // Database Version
3. private static final int DATABASE_VERSION = 1;
4. // Database Name
5. private static final String DATABASE_NAME = "database_tutorial";
6. // Table name
7. private static final String SOCIAL_ITEMS = "social_items";
8.
5. Database Helper
1. @Override
2. public void onCreate(SQLiteDatabase db) {
3. db.execSQL("CREATE TABLE " + SOCIAL_ITEMS + "("
4. + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
5. + COLUMN_TITLE + " TEXT UNIQUE NOT NULL,"
6. + COLUMN_NUM_CLICKS + " LONG NOT NULL" + ")");
7. }
8.
9. @Override
10. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
11. // simple database upgrade operation:
12. // 1) drop the old table
13. db.execSQL("DROP TABLE IF EXISTS " + SOCIAL_ITEMS);
14. // 2) create a new database
15. onCreate(db);
16. }
6. Database Helper
1. // retrieve all items from the database
2. public List<SocialItem> getAllItems() {
3. // initialize the list
4. List<SocialItem> items = new ArrayList<SocialItem>();
5. // obtain a readable database
6. SQLiteDatabase db = getReadableDatabase();
7. // send query
8. Cursor cursor = db.query(SOCIAL_ITEMS, new String[] {
9. COLUMN_TITLE,
10. COLUMN_NUM_CLICKS },
11. null, null, null, null, null, null); // get all rows
12.
13. if (cursor != null) {
14. // add items to the list
15. for(cursor.moveToFirst(); cursor.isAfterLast() == false; cursor.moveToNext()) {
16. items.add(new SocialItem(cursor.getString(0), Long.parseLong(cursor.getString(1))));
17. }
18.
19. // close the cursor
20. cursor.close();
21. }
22.
23. // close the database connection
24. db.close();
25. // return the list
26. return items;
7. Database Helper
1. /**
2. * Add items to the list
3. */
4. public void addItems(List<SocialItem> items) {
5. if(items != null && items.size() > 0) {
6. // obtain a readable database
7. SQLiteDatabase db = getWritableDatabase();
8.
9. for(SocialItem item : items) {
10. addItem(db, item);
11. }
12.
13. // close the database connection
14. db.close();
15. }
16. }
8. Database Helper
1. // update an existing item
2. public void updateItem(SocialItem item) {
3. if(item != null) {
4. // obtain a readable database
5. SQLiteDatabase db = getWritableDatabase();
6. // prepare values
7. ContentValues values = new ContentValues();
8. values.put(COLUMN_NUM_CLICKS, item.getNumClicks());
9. // send query for the row id
10. Cursor cursor = db.query(SOCIAL_ITEMS, new String[] {COLUMN_ID},
11. COLUMN_TITLE + "=?", new String[] {item.title},
12. null, null, null, null);
13.
14. if(cursor != null) {
15. if(cursor.moveToFirst()) {
16. // update the row
17. db.update(SOCIAL_ITEMS, values, COLUMN_ID + "=?",
18. new String[] {cursor.getString(0)});
19. }
20.
21. cursor.close();
22. }
23.
24. db.close(); // close the database connection
25. }
26. }
10. List Adapter
The SocialItemsListAdapter class below contains a list List of SocialItems and a HashMap for mapping the title to the icon:
1. public class SocialItemsListAdapter extends ArrayAdapter<ListViewItem> {
2. private List<SocialItem> mSocialItems;
3. private Map<String, Drawable> mIconsMap;
4.
5. public SocialItemsListAdapter(Context context, List<SocialItem> socialItems, Map<String, Drawable> iconsMap) {
6. super(context, R.layout.listview_item);
7. mSocialItems = socialItems;
8. mIconsMap = iconsMap;
9. }
10.
11. @Override
12. List Adapter
1. /**
2. * The view holder design pattern prevents using findViewById()
3. * repeatedly in the getView() method of the adapter.
4. *
5. * @see http://developer.android.com/training/improving-layouts/smooth-
scrolling.html#ViewHolder
6. */
7. private static class ViewHolder {
8. ImageView ivIcon;
9. TextView tvTitle;
10. TextView tvDescription;
11. }
13. DatabaseDemoFragment
The fragment that contains the ListView. This class uses an AsyncTask for loading the items from the database and sorting them according
to the user’s preferences:
1. public class DatabaseDemoFragment extends ListFragment {
2. // database helper
3. private SocialItemsDatabaseHelper mDatabaseHelper;
4.
5. // database items list
6. private List<SocialItem> mSocialItems;
7.
8. // list adapter
9. private SocialItemsListAdapter mAdapter;
10.
14. DatabaseDemoFragment
1. @Override
2. public void onCreate(Bundle savedInstanceState) {
3. super.onCreate(savedInstanceState);
4. // initialize the database helper
5. mDatabaseHelper = new SocialItemsDatabaseHelper(getActivity());
6.
7. // initialize the icons map
8. Map<String, Drawable> iconsMap = new HashMap<String, Drawable>();
9. Resources resources = getResources();
10. iconsMap.put(getString(R.string.aim), resources.getDrawable(R.drawable.aim));
11. :
12. iconsMap.put(getString(R.string.youtube), resources.getDrawable(R.drawable.youtube));
13.
14. // initialize the items list
15. mSocialItems = mDatabaseHelper.getAllItems();
16.
17. // initialize and set the list adapter
18. mSocialItems = new ArrayList<SocialItem>();
19. mAdapter = new SocialItemsListAdapter(getActivity(), mSocialItems, iconsMap);
20. setListAdapter(mAdapter);
21.
22. // start an AsyncTask for loading the items from the database
23. AsyncTask<String, Integer, List<SocialItem>> loader = new AsyncTask<String, Integer, List<SocialItem>>() {
24.
25.