Import and Use External Database in Android

This article explains the usage of an Android library which is helpful to import and use external SQLite database into your Android application. It has been a problem for Android developers to release an application with some existing rows of data in the database. For example if you are developing a static application which is used to display some tourist spots in your country, probably you need to release the database with predefined details about the tourist places inside it. However, there are no native ways to import external database easily into your Android application.


The Android SQLiteAssetHelper library allows you to build your SQLite database in your desktop computer, and to import and use it in your Android application. Let's create a simple application to demonstrate the application of this library.

Update: If you want to import database either from assets folder as described here or from an external location like SD card, a new approach is shared in Deploy and Upgrade Android Database From External Directory.

Step 1:
Create a database quotes.db using your favorite SQLite database application (DB Browser for SQLite is a portable cross platform freeware, which can be used to create and edit SQLite databases). Create a table 'quotes' with a single column 'quote'. Insert some random quotes into the table 'quotes'.


Step 2:
The database can be imported into project either directly as it is, or as a compressed file. The compressed file is recommended, if your database is too large in size. You can create either a ZIP compression or a GZ compression.

The file name of the compressed db file must be quotes.db.zip, if you are using ZIP compression or quotes.db.gz, if you are using GZ compression.

Step 3:
Create a new application “External Database Demo” with a package name “com.javahelps.com.javahelps.externaldatabasedemo”.

Step 4:
Open the build.gradle (Module: app) file and add the following dependency.
dependencies {
    compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
}


Once you have saved the build.gradle file click on the 'Sync Now' link to update the project. You can synchronize the build.gradle, by right clicking on the build.gradle file and selecting "Synchronize build.gradle' option as well.

Step 5:
Right click on the app folder and create new assets folder.


Step 6:
Create a new folder 'databases' inside the assets folder.


Step 7:
Copy and paste the  quotes.db.zip file inside the assets/databases folder.



Step 8:
Create a new class 'DatabaseOpenHelper'
package com.javahelps.externaldatabasedemo;

import android.content.Context;

import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;

public class DatabaseOpenHelper extends SQLiteAssetHelper {
    private static final String DATABASE_NAME = "quotes.db";
    private static final int DATABASE_VERSION = 1;

    public DatabaseOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
}
Notice that rather than extending SQLiteOpenHelper, the DatabaseOpenHelper extends  SQLiteAssetHelper class.

Step 9:
Create a new class DatabaseAccess and enter the code as shown below. More details about this class is available at Advanced Android Database tutorial.
package com.javahelps.externaldatabasedemo;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

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

public class DatabaseAccess {
    private SQLiteOpenHelper openHelper;
    private SQLiteDatabase database;
    private static DatabaseAccess instance;

    /**
     * Private constructor to aboid object creation from outside classes.
     *
     * @param context
     */
    private DatabaseAccess(Context context) {
        this.openHelper = new DatabaseOpenHelper(context);
    }

    /**
     * Return a singleton instance of DatabaseAccess.
     *
     * @param context the Context
     * @return the instance of DabaseAccess
     */
    public static DatabaseAccess getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseAccess(context);
        }
        return instance;
    }

    /**
     * Open the database connection.
     */
    public void open() {
        this.database = openHelper.getWritableDatabase();
    }

    /**
     * Close the database connection.
     */
    public void close() {
        if (database != null) {
            this.database.close();
        }
    }

    /**
     * Read all quotes from the database.
     *
     * @return a List of quotes
     */
    public List<String> getQuotes() {
        List<String> list = new ArrayList<>();
        Cursor cursor = database.rawQuery("SELECT * FROM quotes", null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            list.add(cursor.getString(0));
            cursor.moveToNext();
        }
        cursor.close();
        return list;
    }
}
In this class only the getQuotes method is implemented to read the data from the database. You have the full freedom to insert, update and delete any rows in the database as usual. For more details, follow this link Advanced Android Database.

All the database related setups are completed and now we need to create a ListView to display the quotes.

Step 10:
Add a ListView in your activity_main.xml.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
</FrameLayout>

Step 11:
Find the object of ListView in the onCreate method of MainActivity and feed the quotes which are read form the database.
package com.javahelps.externaldatabasedemo;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.List;


public class MainActivity extends ActionBarActivity {
    private ListView listView;

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

        this.listView = (ListView) findViewById(R.id.listView);
        DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
        databaseAccess.open();
        List<String> quotes = databaseAccess.getQuotes();
        databaseAccess.close();

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, quotes);
        this.listView.setAdapter(adapter);
    }
}

Step 12:
Save all the changes and run the application.


This library also allows you to upgrade the database using an external SQL script. For more details about this library, visit to its official page.

Find the project at Git Hub.

Update: To store images in this database, read Import Database with Images in Android
Read More

Thread Synchronization in Java

Multi-thread applications are useful to execute more than one operations simultaneously. However, if more than one threads are accessing a shared resource, there is a high risk of data corruption or unexpected result. This article explains the reason for the unexpected results and the possible solution to avoid it.

Even though threads are considered to be executing simultaneously, actually they are executed one after another using time-sharing mechanism of the underlying operating system. (For more details visit to this link). Consider a sample code as shown below.
public class ConcurrencyProblem {
    static int[] array = {0};

    public static void main(String[] args) throws InterruptedException {
        Thread a = new Thread() {
            public void run() {
                for(int i = 1; i <= 1000; i++) {
                    increase();
                }
            }
        };

        Thread b = new Thread() {
            public void run() {
                for(int i = 1; i <= 1000; i++) {
                    decrease();
                }
            }
        };

        a.start();
        b.start();
        a.join();
        b.join();
        System.out.println(array[0]);
    }

    public static void increase() {
        array[0]++;
    }

    public static void decrease() {
        array[0]--;
    }
}
In this code thread A is increasing the value of first element of the array by one. At the same time thread B is decreasing the value of first element of the array by one. Both threads are executing these operations 1000 times. So ideally the final result should be 0 since thread A increases the value 1000 times and thread B decreases the value 1000 times. However, when you run this application, sometimes you may get an outputs other than 0. If you run this application again and again, you will get different outputs on each execution.
Read More

Serving Dynamic Content - CGI vs Servlets

Note: This article focuses OCEWCD students, and the term server refers the combination of web server and Servlet container like Apache Tomcat.
In a web application, clients send request to the servers and servers return a response to the client. Once the client receives the response, connection between client and server will get lost. So even if the same client makes another request, server receives it as a new request from a new user, in other words server does not remember the client or the history of transactions with that client. If the request is for a static content like an HTML file or media file, server is much happy with that request and return the file as the response. If the request is for a dynamic content like a web page which contains weather details on that day, or current time (Notice that these details cannot be hard coded in a static HTML file. They have to be generated on runtime) a web server cannot handle that request; it has to be handled by any other helper applications. The helper application can be either a Common Gateway Interface (CGI) or Servlet.
Read More

Java Web Application - Hello World

This tutorial shows you the way to create your first Hello World web application in Java. You need to have Eclipse IDE for Java EE Developers and Apache Tomcat, in order to develop this application. If you have not configured the Apache Tomcat in Eclipse, follow this tutorial and configure it first.

Step 1:
Go to File → New → Project.

Step 2:
Under the Web category, select the Dynamic Web Project option and click on Next.

Step 3:
Give the project name 'Hello World' and click on the Finish button.

Step 4:
Right click on the src folder of 'Hello World' project and select New → Servlet.

Step 5:
Give a package name 'com.javahelps.helloworld' and class name 'HelloWorldServlet' as shown in the screenshot.
Click on the Finish button to create the Servlet.

Step 6:
Modify the Servlet class code as provided below.
package com.javahelps.helloworld;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloWorldServlet
 */
@WebServlet("/saytime")
public class HelloWorldServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloWorldServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.print("<html><body><h1 align='center'>" +
        new Date().toString() + "</h1></body></html>");
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}
Here the @WebServlet annotation defines the URL of this Servlet. The doGet method is used to serve the GET requests and doPost method is used to serve the POST requests. According to this code, this Servlet can accept both GET and POST requests but it produces the output only for GET requests. Any POST requests will cause to a blank screen in the browser. PrintWriter is used to write the current time as an HTML content to the response.

Step 7:
Right click on the WebContent folder and create a new HTML file index.html.


Step 8:
Modify the HTML file as shown below.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<a href="saytime">Click Here</a>
</body>
</html>
The hyperlink reference is pointing to the sayhello URL which is defined in the HelloWorldServlet class.

Step 9:
After saving all the changes, right click on the project and select Run As → Run on Server.

Step 10:
Select the Tomcat server and click on the Finish button to run the application.

Now your first application is available at the following link:
http://localhost:8080/Hello_World/



Find the project at Git Hub.
Read More

Contact Form

Name

Email *

Message *