Android Dictionary Application with Search Suggest and Text to Speech Feature

Android Dictionary Application with Search Suggest and Text to Speech Feature

In this android tutorial we are going to learn how to create an android dictionary application with Search Suggest and Text to Speech feature. The android application can be used in defining terms or words use in a particular field.

You can found an example of Biology Dictionary I built in one of my apps in the Google Play Store.

The app will consist of different words and their meaning. When a word is selected, it will display the definition or meaning of the word with an option to convert it to speech.

The app will also has a search functionality with integrated search suggestion. When a user type in two characters the search box will display all the words that contain the type in characters.

If you still don’t understand what search suggest means you can read my post on Android ListView with EditText Search Filter

We will start by designing android SQLITE database that will house our data. There are different ways we can use to create our database. In this tutorial, I am going to use a SQLITE Manager to create and manager the database file.

The database will be create using SQLite Expert Professional Manager which is a paid software but there are many free to use SQLite Manager you can get online and use.

I will go ahead and create a database called dictionary. Now, we have to create a table inside our database called dictionary. The table will have three columns – id, word and meaning. The SQLite code for the table is shown below.

Create Table [dictionary] (

[_id] INTEGER PRIMARY KEY,

[word] TEXT,

[meaning] TEXT

);

Before we start, the first thing I will do is to list the environment and tools I used in this android tutorial but feel free to use whatever environment or tools you are familiar with.

Windows 7

Android Studio

Samsung Galaxy Fame Lite

Min SDK 14

Target SDK 19

To create a new android application project, following the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidDictionaryApplication

Package: com.inducesmile.androiddictionaryapplication

Keep other default selections.

Continue to click on next button until Finish button is active, then click on Finish Button

Once you are done with creating your project, make sure you change the package name if you did not use the same package.

SQLITE Database

We will start from the backend and build the application to finish. The first thing we will do is to create a folder called databases inside assets folder. Since we created our SQLite database file using SQLite database manager, we will drag and drop the file inside the databases folder and zip.

We are preparing our database file this way since we are going to use a third party library called android sqlite asset helper. This library will help us to create and manage your database file. You can read more about this library here

The next to do is the import the library to our project. Since the library makes use of gradle, just open your build.gradle file and copy and paste the code below under the dependence section.

compile ‘com.readystatesoftware.sqliteasset:sqliteassethelper:+’

Now you can build your project and the library will be added automatically to your project. If you are using Eclipse for you android development, you can search on how to import library inside android project.

We will go ahead with the SQLite database code now that we have finished setting up our database library.

We will create three different files – DictionaryDatabase.java, DatabaseObject.java and DbBackend.java.

The DictionaryDatabase java class will inherit from SQLiteAssetHelper which is a class from our imported library. We will define our database name and version. The version number is use to control our application database update. Whenever there is a change in the database file, the version number will be updated. The code sample is shown below. Copy and paste it to your project file.

package inducesmile.com.androiddictionaryapplication;
import android.content.Context;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;

public class DictionaryDatabase extends SQLiteAssetHelper {

private static final String DATABASE_NAMES = "quiz";

private static final int DATABASE_VERSION = 5;

public DictionaryDatabase(Context context) {

super(context, DATABASE_NAMES, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
}

We are going to establish a connection for our database and return the instance of our database in DatabaseObject.java file.

An instance of the DictionaryDatabase is created and the getReadableDatabase of the class is used to get the connection object.

The getter and close methods in the class is used to return and close the database connection. The code for this class is shown below.

package inducesmile.com.androiddictionaryapplication;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

public class DbObject {

private static DictionaryDatabase dbHelper;
private SQLiteDatabase db;

public DbObject(Context context) {

dbHelper = new DictionaryDatabase(context);

this.db = dbHelper.getReadableDatabase();

}

public SQLiteDatabase getDbConnection(){

return this.db;

}

public void closeDbConnection(){

if(this.db != null){

this.db.close();

}
}
}

Finally, to finish up with our backend, will create two queries in DbBackend.java file which will be use to retrieve data from our SQLite database. The code is shown below.

package inducesmile.com.androiddictionaryapplication;

import android.content.Context;

import android.database.Cursor;

import java.util.ArrayList;

public class DbBackend extends DbObject{

public DbBackend(Context context) {

super(context);

}

public String[] dictionaryWords(){

String query = "Select * from dictionary";

Cursor cursor = this.getDbConnection().rawQuery(query, null);

ArrayList<String> wordTerms = new ArrayList<String>();

if(cursor.moveToFirst()){

do{

String word = cursor.getString(cursor.getColumnIndexOrThrow("word"));

wordTerms.add(word);

}while(cursor.moveToNext());

}

cursor.close();

String[] dictionaryWords = new String[wordTerms.size()];

dictionaryWords = wordTerms.toArray(dictionaryWords);

return dictionaryWords;

}

public QuizObject getQuizById(int quizId){

QuizObject quizObject = null;

String query = "select * from dictionary where _id = " + quizId;

Cursor cursor = this.getDbConnection().rawQuery(query, null);

if(cursor.moveToFirst()){

do{

String word = cursor.getString(cursor.getColumnIndexOrThrow("word"));

String meaning = cursor.getString(cursor.getColumnIndexOrThrow("meaning"));

quizObject = new QuizObject(word, meaning);

}while(cursor.moveToNext());

}

cursor.close();

return quizObject;

}

}

 Activity_Main.xml

The back-end code for database interaction is done, we will move ahead to create our main application. The main layout of our application will contain a ListView and an EditText.

You can drag and drop the View controls to the project activity_main.xml. The xml code snippet for the layout is shown below.

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:paddingBottom="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

<EditText

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:id="@+id/editText"

android:layout_marginLeft="20dp"

android:layout_marginRight="20dp"

android:layout_alignParentTop="true"

android:layout_alignParentLeft="true"

android:layout_alignParentStart="true" />

<ListView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/listView"

android:layout_marginRight="20dp"

android:layout_marginTop="10dp"

android:layout_below="@+id/editText"

android:layout_alignLeft="@+id/editText"

android:layout_alignStart="@+id/editText" />

</RelativeLayout>

Some string associated with the View names are placed in the string.xml file. The updated code is shown below.

<resources>

<string name="app_name">AndroidDictionaryApplication</string>

<string name="hello_world">Hello world!</string>

<string name="action_settings">Settings</string>

<string name="title_activity_dictionary">DictionaryActivity</string>

<string name="text_to_speech">Convert Text to Speech</string>

</resources>

 MainActivity.java

In the MainActivity.java file, we will get the instances of our View controls (ListView and EditText Views).

We create an object of the DbBackend class and call its method dictionaryWords() which will return all the words stored in the database.

We create an ArrayAdapter and pass String array as parameter, the android default ListView layout.

The ListView instance uses the ArrayAdapter class for its own adapter.

ItemClickListener event listener is attached to the ListView so that when a ListView item is clicked, it will transfer its id value to DictionaryActivity class.

The code of the MainActivity.java is shown below.

package inducesmile.com.androiddictionaryapplication;

import android.content.Intent;

import android.os.Bundle;

import android.support.v7.app.ActionBarActivity;

import android.text.Editable;

import android.text.TextWatcher;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private EditText filterText;

private ArrayAdapter<String> listAdapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

filterText = (EditText)findViewById(R.id.editText);

ListView itemList = (ListView)findViewById(R.id.listView);

DbBackend dbBackend = new DbBackend(MainActivity.this);

String[] terms = dbBackend.dictionaryWords();

listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, terms);

itemList.setAdapter(listAdapter);

itemList.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

// make Toast when click

Toast.makeText(getApplicationContext(), "Position " + position, Toast.LENGTH_LONG).show();

Intent intent = new Intent(MainActivity.this, DictionaryActivity.class);

intent.putExtra("DICTIONARY_ID", position);

startActivity(intent);

}

});

filterText.addTextChangedListener(new TextWatcher() {

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override

public void onTextChanged(CharSequence s, int start, int before, int count) {

MainActivity.this.listAdapter.getFilter().filter(s);

}

@Override

public void afterTextChanged(Editable s) {

}

});

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.menu_main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// Handle action bar item clicks here. The action bar will

// automatically handle clicks on the Home/Up button, so long

// as you specify a parent activity in AndroidManifest.xml.

int id = item.getItemId();

//noinspection SimplifiableIfStatement

if (id == R.id.action_settings) {

return true;

}

return super.onOptionsItemSelected(item);

}

}

 Activity_Dictionary.xml

Just like in our main layout, we are going to add three View Controls in our activity_dictionary.xml file.

1. A TextView that will hold the word we will look-up its meaning

2. A View that we will use to create a horizontal demarcation line

3. A TextView that will hold the meaning of our search word.

4. A Button View for word to speech conversion.

The xml code is shown below.

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:paddingBottom="@dimen/activity_vertical_margin"

tools:context="inducesmile.com.androiddictionaryapplication.DictionaryActivity">

<TextView

android:id="@+id/word"

android:text="@string/hello_world"

android:layout_width="wrap_content"

android:textSize="16sp"

android:textStyle="bold"

android:layout_height="wrap_content" />

<View

android:id="@+id/seperator"

android:layout_width="match_parent"

android:layout_height="1dp"

android:layout_alignLeft="@+id/word"

android:layout_below="@+id/word"

android:layout_marginBottom="10dp"

android:layout_marginRight="10dp"

android:layout_marginTop="10dp"

android:background="#000000" />

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="New Text"

android:id="@+id/dictionary"

android:layout_below="@+id/seperator"

android:layout_alignParentLeft="true"

android:layout_marginTop="20dp"

android:layout_alignParentStart="true" />

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/text_to_speech"

android:id="@+id/button"

android:layout_below="@+id/dictionary"

android:layout_centerHorizontal="true"

android:layout_marginTop="30dp" />

</RelativeLayout>

 DictionaryActivity.java

We will finish up the project by writing the code that will let us display the terms and the definition of the terms.

We will follow the steps we used in MainActivity.java file by getting the instances of our View controls.

We have to create an instance of the TextToSpeed class which implements onInit callback method that signify when the TextToSpeech engine is ready to be used.

The TextToSpeech object is instantiated inside the button’s event listener and the speak method is called on the object.

The code for the class is shown below.

package inducesmile.com.androiddictionaryapplication;

import android.annotation.TargetApi;

import android.content.Intent;

import android.os.Build;

import android.os.Bundle;

import android.speech.tts.TextToSpeech;

import android.support.v7.app.ActionBarActivity;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import java.util.Locale;

public class DictionaryActivity extends ActionBarActivity {

private TextView wordMeaning;

private TextToSpeech convertToSpeech;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_dictionary);

Intent intent = getIntent();

Bundle bundle = intent.getExtras();

int dictionaryId = bundle.getInt("DICTIONARY_ID");

int id = dictionaryId + 1;

TextView word = (TextView)findViewById(R.id.word);

wordMeaning = (TextView)findViewById(R.id.dictionary);

Button textToSpeech = (Button)findViewById(R.id.button);

DbBackend dbBackend = new DbBackend(DictionaryActivity.this);

QuizObject allQuizQuestions = dbBackend.getQuizById(id);

word.setText(allQuizQuestions.getWord());

wordMeaning.setText(allQuizQuestions.getDefinition());

textToSpeech.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

final String convertTextToSpeech = wordMeaning.getText().toString();

convertToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

@Override

public void onInit(int status) {

if(status != TextToSpeech.ERROR){

convertToSpeech.setLanguage(Locale.US);

convertToSpeech.speak(convertTextToSpeech, TextToSpeech.QUEUE_FLUSH, null, null);

}

}

});

}

});

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.menu_dictionary, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// Handle action bar item clicks here. The action bar will

// automatically handle clicks on the Home/Up button, so long

// as you specify a parent activity in AndroidManifest.xml.

int id = item.getItemId();

//noinspection SimplifiableIfStatement

if (id == R.id.action_settings) {

return true;

}

return super.onOptionsItemSelected(item);

}

@Override

protected void onPause() {

if(convertToSpeech != null){

convertToSpeech.stop();

convertToSpeech.shutdown();

}

super.onPause();

}

}

Save the file and run your project. If everything works for you, the project will appear like this in your device.

Android Dictionary Application with Search Suggest and Text to Speech

Android Dictionary Application with Search Suggest and Text to Speech

You can download the code for this tutorial below. If you are having hard time downloading the tutorials, kindly contact me.

Remember to subscribe with your email so that you will be among the first to receive our new post once it is published

 

Check out my complete android dictionary app for 5$ here

OTHER INTERESTING POSTS:

59 Comments

    • Henry
  1. Henry
      • Henry
    • Henry
        • Henry
        • Henry
    • Henry
        • Henry
    • Henry
    • Henry
        • Henry
    • Henry
    • Henry
        • Henry
    • Henry

Add a Comment