Sorry if I repeat my question but I have still had no clues of what to do and how to deal with the question.
My app is a dictionary. I assume that users will need to add words that they want to memorise to a Favourite list. Thus, I created a Favorite button that works on two phases:
short-click to save the currently-view word into the Favourite list;
and long-click to view the Favourite list so that users can click on any words to look them up again.
I go for using a SQlite database to store the favourite words but I wonder how I can do this task. Specifically, my questions are:
Should I use the current dictionary SQLite database or create a new SQLite database to favorite words?
In each case, what codes do I have to write to cope with the mentioned task?
Could anyone there kindly help?
Here is the dictionary code:
package mydict.app;
import java.util.ArrayList;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;
public class DictionaryEngine {
static final private String SQL_TAG = "[MyAppName - DictionaryEngine]";
private SQLiteDatabase mDB = null;
private String mDBName;
private String mDBPath;
//private String mDBExtension;
public ArrayList<String> lstCurrentWord = null;
public ArrayList<String> lstCurrentContent = null;
//public ArrayAdapter<String> adapter = null;
public DictionaryEngine()
{
lstCurrentContent = new ArrayList<String>();
lstCurrentWord = new ArrayList<String>();
}
public DictionaryEngine(String basePath, String dbName, String dbExtension)
{
//mDBExtension = getResources().getString(R.string.dbExtension);
//mDBExtension = dbExtension;
lstCurrentContent = new ArrayList<String>();
lstCurrentWord = new ArrayList<String>();
this.setDatabaseFile(basePath, dbName, dbExtension);
}
public boolean setDatabaseFile(String basePath, String dbName, String dbExtension)
{
if (mDB != null)
{
if (mDB.isOpen() == true) // Database is already opened
{
if (basePath.equals(mDBPath) && dbName.equals(mDBName)) // the opened database has the same name and path -> do nothing
{
Log.i(SQL_TAG, "Database is already opened!");
return true;
}
else
{
mDB.close();
}
}
}
String fullDbPath="";
try
{
fullDbPath = basePath + dbName + "/" + dbName + dbExtension;
mDB = SQLiteDatabase.openDatabase(fullDbPath, null, SQLiteDatabase.OPEN_READWRITE|SQLiteDatabase.NO_LOCALIZED_COLLATORS);
}
catch (SQLiteException ex)
{
ex.printStackTrace();
Log.i(SQL_TAG, "There is no valid dictionary database " + dbName +" at path " + basePath);
return false;
}
if (mDB == null)
{
return false;
}
this.mDBName = dbName;
this.mDBPath = basePath;
Log.i(SQL_TAG,"Database " + dbName + " is opened!");
return true;
}
public void getWordList(String word)
{
String query;
// encode input
String wordEncode = Utility.encodeContent(word);
if (word.equals("") || word == null)
{
query = "SELECT id,word FROM " + mDBName + " LIMIT 0,15" ;
}
else
{
query = "SELECT id,word FROM " + mDBName + " WHERE word >= '"+wordEncode+"' LIMIT 0,15";
}
//Log.i(SQL_TAG, "query = " + query);
Cursor result = mDB.rawQuery(query,null);
int indexWordColumn = result.getColumnIndex("Word");
int indexContentColumn = result.getColumnIndex("Content");
if (result != null)
{
int countRow=result.getCount();
Log.i(SQL_TAG, "countRow = " + countRow);
lstCurrentWord.clear();
lstCurrentContent.clear();
if (countRow >= 1)
{
result.moveToFirst();
String strWord = Utility.decodeContent(result.getString(indexWordColumn));
String strContent = Utility.decodeContent(result.getString(indexContentColumn));
lstCurrentWord.add(0,strWord);
lstCurrentContent.add(0,strContent);
int i = 0;
while (result.moveToNext())
{
strWord = Utility.decodeContent(result.getString(indexWordColumn));
strContent = Utility.decodeContent(result.getString(indexContentColumn));
lstCurrentWord.add(i,strWord);
lstCurrentContent.add(i,strContent);
i++;
}
}
result.close();
}
}
public Cursor getCursorWordList(String word)
{
String query;
// encode input
String wordEncode = Utility.encodeContent(word);
if (word.equals("") || word == null)
{
query = "SELECT id,word FROM " + mDBName + " LIMIT 0,15" ;
}
else
{
query = "SELECT id,content,word FROM " + mDBName + " WHERE word >= '"+wordEncode+"' LIMIT 0,15";
}
//Log.i(SQL_TAG, "query = " + query);
Cursor result = mDB.rawQuery(query,null);
return result;
}
public Cursor getCursorContentFromId(int wordId)
{
String query;
// encode input
if (wordId <= 0)
{
return null;
}
else
{
query = "SELECT id,content,word FROM " + mDBName + " WHERE Id = " + wordId ;
}
//Log.i(SQL_TAG, "query = " + query);
Cursor result = mDB.rawQuery(query,null);
return result;
}
public Cursor getCursorContentFromWord(String word)
{
String query;
// encode input
if (word == null || word.equals(""))
{
return null;
}
else
{
query = "SELECT id,content,word FROM " + mDBName + " WHERE word = '" + word + "' LIMIT 0,1";
}
//Log.i(SQL_TAG, "query = " + query);
Cursor result = mDB.rawQuery(query,null);
return result;
}
public void closeDatabase()
{
mDB.close();
}
public boolean isOpen()
{
return mDB.isOpen();
}
public boolean isReadOnly()
{
return mDB.isReadOnly();
}
}
And here is the code below the Favourite button to save to and load the Favourite list:
btnAddFavourite = (ImageButton) findViewById(R.id.btnAddFavourite);
btnAddFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Add code here to save the favourite, e.g. in the db.
Toast toast = Toast.makeText(ContentView.this, R.string.messageWordAddedToFarvourite, Toast.LENGTH_SHORT);
toast.show();
}
});
btnAddFavourite.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// Open the favourite Activity, which in turn will fetch the saved favourites, to show them.
Intent intent = new Intent(getApplicationContext(), FavViewFavourite.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
return false;
}
});
}
You need to have two tables
words
favorites
Words(id, word, meaning,...)
Favorites(id, word_id)
In the Favorites table have a foreign key that points the word from the Words Table.
I have only addressed the way you need to structure the table.
*EDITED*
words(id, name, meaning, timestamp)
favortie(id, word_id)
Related
I'm getting many time repeating data from Sqlite / Android database. I want to get recode without repeating in Android cursor.
Here's my query:
public Cursor getQuizQuiestion(String cat, String level, String questionNo) {
String QUERY_SELECT_QUIESTION = "SELECT * FROM " +TABLE_QUIESTION +" WHERE "+COL_CAT+ " = '" +cat+"' AND "
+COL_LEVEL+ " = " +level+" ORDER BY RANDOM() LIMIT 1";
Cursor cursor = db.rawQuery(QUERY_SELECT_QUIESTION, null);
return cursor;
}
I Have Simple Example if I Used In My Project I think MayBe IT's Help You;
public ArrayList<ModelRandomList> getRandomData(String city){
ArrayList<ModelRandomList> modelRandomListArrayListLists = new ArrayList<ModelRandomList>();
String queryRandomData ="SELECT DISTINCT * FROM "+TABLE_NAME+" WHERE "+COL_CITY + "=?"+ "Order BY RANDOM()";
Cursor cursor = db.rawQuery(queryRandomData,new String[] { String.valueOf(city) });
if(cursor.getCount() != 0){
while (cursor.moveToNext()){
/*mName =cursor.getString(0);
mCity = cursor.getString(1);
Log.d(TAG,mName +" City "+mCity );*/
ModelRandomList modelRandomList = new ModelRandomList();
modelRandomList.setUserName(cursor.getString(0));
modelRandomList.setUserCity(cursor.getString(1));
modelRandomListArrayListLists.add(modelRandomList);
}
Random random = new Random();
Collections.shuffle(modelRandomListArrayListLists,random);
}
Log.d(TAG, "Get Random Totla No of Recode Found "+cursor.getCount());
return modelRandomListArrayListLists;
}
and in Your Activity
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private SqlLiteDataBaseHelper sqlLiteDataBaseHelper;
private Button btGetRandomData;
private ArrayList<ModelRandomList> modelRandomLists;
private Button btSingleRandomData;
private int position = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
modelRandomLists = new ArrayList<ModelRandomList>();
sqlLiteDataBaseHelper = new SqlLiteDataBaseHelper(MainActivity.this);
try{
if(sqlLiteDataBaseHelper.checkDataBase()){
Log.e(TAG, "Data Base Already Exists");
}else {
sqlLiteDataBaseHelper.CopyDataBaseFromAsset();
}
sqlLiteDataBaseHelper.openDataBase();
try {
Log.e(TAG, "No Of Racode In DataBase " + sqlLiteDataBaseHelper.getDataCount());
}catch (Exception e){
e.printStackTrace();
}
}catch (Exception e){
e.printStackTrace();
}
init();
}
private void init() {
btGetRandomData = (Button)findViewById(R.id.btRandomData);
btSingleRandomData = (Button)findViewById(R.id.btSingleRandomData);
}
#Override
protected void onResume() {
super.onResume();
btGetRandomData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
modelRandomLists = sqlLiteDataBaseHelper.getRandomData("A");
for (ModelRandomList crt : modelRandomLists) {
Log.e(TAG, " " + crt.getUserName());
Log.e(TAG, " " + crt.getUserCity());
}
}
});
btSingleRandomData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
Log.d(TAG,modelRandomLists.get(position).getUserName());
position ++;
}catch (Exception e){
e.printStackTrace();
position =0;
}
}
});
}
}
You would have to keep a track of what questions have been seen before. What about this:
private List<Integer> seenQuestions = new ArrayList<>();
public Cursor getUseenQuizQuestion(String cat,String level,String questionNo) {
Cursor cursor = getQuizQuiestion(cat, level, questionNo);
while(cursor == null) { // This could be an infinite loop!!
cursor = getQuizQuiestion(cat, level, questionNo);
}
return cursor;
}
private Cursor getQuizQuiestion(String cat,String level,String questionNo){
String QUERY_SELECT_QUIESTION = "SELECT * FROM " +TABLE_QUIESTION +" WHERE "+COL_CAT+ " = '" +cat+"' AND "
+COL_LEVEL+ " = " +level+" ORDER BY RANDOM() LIMIT 1";
Cursor cursor = db.rawQuery(QUERY_SELECT_QUIESTION, null);
if(cursor.moveToFirst()) {
int resultId = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
if(seenQuestions.contains(resultId)) {
cursor.close();
return null;
}
seenQuestions.add(resultId);
}
return cursor;
}
^ the code sample above has many flaws and could loop infinitely.
But the point is you need to keep track of what has been returned and query again if you have seen it.
Alternatively, you could allow your DB query to return all data and then use a Random value to select one of the items.
There is no way to create unique results if you are querying over and over again.
Since you are not using the questionNo parameter and return a cursor anyway: why not just remove the limit 1 and add the distinct clause to your statement?
If you do it that way, you can use your cursor to iterate over the unique questions:
String QUERY_SELECT_QUIESTION = "SELECT DISTINCT * FROM " +TABLE_QUIESTION +" WHERE "+COL_CAT+ " = '" +cat+"' AND "
+COL_LEVEL+ " = " +level+" ORDER BY RANDOM()";
Then you can iterate over the questions until you have none or whatever your conditions are:
Cursor cursor = db.rawQuery(QUERY_SELECT_QUIESTION, null);
try {
while (cursor.moveToNext()) {
//display question or copy them to a member or whatever
}
} finally {
cursor.close();
}
How I can get a different values from a column with the same name (like the photo)?
In the photo, "test" have a 3 differents values, how I can load them to a ListView or a Spinner?
I have this code, works, but don't get the 3 values, only first value:
MainActivity
public void lookupProduct (View view) {
DatabaseHandler dbHandler = new DatabaseHandler(getApplicationContext());
Name name = dbHandler.findProduct(spinner.getSelectedItem().toString());
Toast.makeText(this, spinner.getSelectedItem().toString(), Toast.LENGTH_LONG).show();
Intent j = new Intent(view.getContext(), SubActivity.class);
Bundle dados = new Bundle();
if (name != null) {
inputLabel.setText(String.valueOf(name.getName()));
values.setText(String.valueOf(name.getValue()));
// Passar para SubActivity
dados.putString("name", String.valueOf(name.getName()));
dados.putString("value", String.valueOf(name.getValue()));
} else {
inputLabel.setText("No Match Found");
dados.putString("name","No Match Found" );
dados.putString("value", "No Match Found");
}
j.putExtras(dados);
startActivity(j);
}
DatabaseHelper
public Name findProduct(String name) {
String query = "Select * FROM " + TABLE_LABELS + " WHERE " + KEY_NAME + " = \"" + name + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Name names = new Name();
if (cursor.moveToFirst()) {
cursor.moveToFirst();
names.setID(Integer.parseInt(cursor.getString(0)));
names.setName(cursor.getString(1));
names.setValue(cursor.getString(2));
cursor.close();
} else {
names = null;
}
db.close();
return names;
}
NameClass
public class Name {
private int _id;
private String _name;
private String _value;
public Name() {
}
public Name(int id, String name, String value) {
this._id = id;
this._name = name;
this._value = value;
}
public Name(String name, String value) {
this._name = name;
this._value = value;
}public String getName() {
return this._name;
}
public String getValue() {
return this._value;
}
Try this
Name names = new Name();
ArrayList<Name > listaName= new ArrayList<>();//create an arraylist of your
custom objects
if (cursor.moveToFirst()) {
do {
names.setID(Integer.parseInt(cursor.getString(0)));
names.setName(cursor.getString(1));
names.setValue(cursor.getString(2));
listaName.add(names);//add your object to arraylist(you were overriding the object.)
} while (cursor.moveToNext());
cursor.close();
//AND ALSO CLOSE DB:
db.close
EDIT 2: Try this and change your --> String Query = "Select * from "+TABLE_NAME;
for ( int i= 1; i< listaName.size(); i++ ) {
System.out.println(listaName.get(i).getName());
}
Your problem:
public Name findProduct(String name) {
String query = "Select * FROM " + TABLE_LABELS + " WHERE " + KEY_NAME + " = \"" + name + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Name names = new Name();
if (cursor.moveToFirst()) {
cursor.moveToFirst(); // this is not necessary because on the top line,
you put it in that position
names.setID(Integer.parseInt(cursor.getString(0)));
names.setName(cursor.getString(1));
names.setValue(cursor.getString(2));
cursor.close(); // You should not close until it is
completely used
} else {
names = null;
}
db.close();
return names;
}
And to read all the cursor is necessary to use a do-while method
If you have any problems, you can ask me again
Though not yet tested, you can try this:
// fetch data from DB
public ArrayList<Name> findProduct(String name) {
String query = "Select * FROM " + TABLE_LABELS + " WHERE " + KEY_NAME + " = \"" + name + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
ArrayList<Name> listOfNames= new ArrayList<>();
if (cursor.moveToFirst()) {
do {
listOfNames.add(new Name(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2)));
} while (cursor.moveToNext());
cursor.close();
db.close
return listOfNames;
}
// add data on spinner
public void addItemsOnSpinner() {
Spinner mSpinner = (Spinner) findViewById(R.id.mSpinner);
ArrayList<String> list = new ArrayList<String>();
for(Name name: findProduct("test")){
list.add(name.getValue());
}
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(dataAdapter);
}
I am working on a code snippet where i am storing my json encoded data into a txt file,and using following method to separate all parts and adding them into database.
public boolean addAnswersFromJSONArray() {
boolean flag = false;
Answer answer = new Answer();
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, "user_live.txt");
FileReader fr;
JsonReader reader;
try {
fr = new FileReader(file);
reader = new JsonReader(fr);
reader.beginArray();
reader.setLenient(true);
while (reader.hasNext()) {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("product_name")) {
answer.setProductName(reader.nextString());
} else if (name.equals("subject")) {
answer.setSubject(reader.nextString());
} else if (name.equals("month")) {
answer.setMonth(reader.nextString());
} else if (name.equals("year")) {
answer.setYear(reader.nextString());
} else if (name.equals("question")) {
answer.setQuestion(reader.nextString());
} else if (name.equals("answer")) {
answer.setAnswer(reader.nextString());
} else if (name.equals("question_no")) {
answer.setQuestion_no(reader.nextString());
} else if (name.equals("marks")) {
answer.setMarks(reader.nextString());
} else {
reader.skipValue();
}
}
answer.save(db);
reader.endObject();
flag = true;
}
reader.endArray();
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
file.delete();
db.close();
}
return flag;
}
and then i am retrieving each fields departments,subjects,month and year,questions,answers,question_no, but while retrieving marks i am getting only unique entries that is 10 and 5....Ideally the size of one set is 18 so i m getting ArrayIndexoutOfBounds Exception.
//database calling part
marks = db.getMarksList(department, subject, month_year);
database method is,
public String[] getMarksList(String department, String subject,
String month_year) {
String month = month_year.split("-")[0];
String year = month_year.split("-")[1];
String whereClause = DEPARTMENT + " = '" + department + "'" + " AND "
+ SUBJECT + " = '" + subject + "' AND " + MONTH + " = '"
+ month + "' AND " + YEAR + " = '" + year + "'";
System.out.println("questions: " + whereClause);
Cursor cursor = db.query(true, "ANSWERS", new String[] { "MARKS" },
whereClause, null, null, null, "DEPARTMENT", null);
String list[] = new String[cursor.getCount()];
int i = 0;
if (cursor != null && cursor.getCount() > 0) {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
.moveToNext()) {
list[i] = new String(cursor.getString(0));
i++;
}
}
return list;
}
Can anyone help me to resolve this issue?? Why getting only unique value,I have checked my json result also each row contains marks.
i got the solution for this,
Changed database query and method as following,
public List<Answer> getMarksList(String department, String subject,
String month_year) {
List<Answer> list = new ArrayList<Answer>();
String month = month_year.split("-")[0];
String year = month_year.split("-")[1];
try {
String sql1 = "select all marks from " + TABLE_NAME
+ " where department = '" + department
+ "' AND subject = '" + subject + "' AND month = '" + month
+ "' AND year = '" + year + "';";
SQLiteDatabase db1 = this.getWritableDatabase();
Cursor cursor = db1.rawQuery(sql1, null);
if (cursor.moveToFirst()) {
do {
Answer a = new Answer();
a.setMarks(cursor.getString(0));
list.add(a);
} while (cursor.moveToNext());
}
} catch (Exception e) {
}
return list;
}
using "all" in query is retrieving all records.
I've got a long running task that I run onResume on my activity. The task involves querying a database then decrypting some data, then manually sorting it then updating the sort order in the database using a transaction.
This works fine when I run it from the Activities main UI thread, but when I execute the same task from within an AsyncTask I always get these errors:
I/SqliteDatabaseCpp(5166): sqlite returned: error code = 1, msg = no such table: Household, db=/mnt/sdcard/myDatabase.db
no such table: while compiling: no such table: Household: , while compiling: SELECT DISTINCT street FROM Household WHERE street IS NOT NULL AND LENGTH(LTRIM(RTRIM(street)))>0
I know that the database exists and that SQL statement is fine because it runs fine outside the AsyncTask. Is there something about access my database from within an AsyncTask that causes problems?
I'm getting errors on the "SELECT DISTINCT" raw query below.
private boolean update_street_sort_order() {
boolean returnValue = false;
DBUtilities objDbUtil = null;
Cursor cCases = null;
final String SORT_ATTRIBUTE = "street_sort_order";
final int STREET_INDEX = 0;
final int ENCRYPTED_STREET = 0;
final int DECRYPTED_STREET = 1;
try {
objDbUtil = DBUtilities.getInstance(this);
if (objDbUtil != null) { // Get list of cases
ArrayList<String[]> alStreet = new ArrayList<String[]>();
SQLiteDatabase sqlitedatabase = objDbUtil.getDatabase();
if (sqlitedatabase != null && sqlitedatabase.isOpen()) {
cCases = sqlitedatabase.rawQuery("SELECT DISTINCT street "
+ "FROM Household " + "WHERE street IS NOT NULL "
+ "AND LENGTH(LTRIM(RTRIM(street)))>0", null);
String _password = this.context.getPassword();
if (cCases != null && cCases.moveToFirst()) {
do { // Create list of en/decrypted streets
alStreet.add(new String[] {
cCases.getString(STREET_INDEX),
Crypto.decrypt(_password,
cCases.getString(STREET_INDEX)) });
} while (cCases.moveToNext());
}
if (cCases != null) {
cCases.close();
cCases = null;
}
int alStreet_length = alStreet.size();
if (alStreet_length > 0) {
Collections.sort(alStreet, new Comparator<String[]>() {
#Override
public int compare(String[] lhs, String[] rhs) {
return lhs[DECRYPTED_STREET]
.compareToIgnoreCase(rhs[DECRYPTED_STREET]);
}
}); // sort decrypted street using custom comparator
StringBuilder sql_transaction = new StringBuilder(
"BEGIN TRANSACTION;" + "UPDATE Household SET "
+ SORT_ATTRIBUTE + "=NULL;");
for (int i = 0; i < alStreet_length; i++) {
sql_transaction.append(String.format(
"UPDATE Household " + "SET "
+ SORT_ATTRIBUTE + "=%1$d "
+ "WHERE street=\"%2$s\";", i,
alStreet.get(i)[ENCRYPTED_STREET]));
}
sql_transaction.append("COMMIT;");
// execute transaction
sqlitedatabase.execSQL(sql_transaction.toString());
}
returnValue = true;
}
}
} catch (Exception e) {
Log.e(Utilities.getFullMethodName(e), e.getMessage());
} finally {
if (objDbUtil != null) { // release resources
objDbUtil.close();
objDbUtil = null;
}
}
return returnValue;
Hї!
I have wrote test for my application. I need add item to database throught UI interface (using robotium) and then I want to check if item exists in database using SQLiteDatabase.
Item is added succesfully (I see new record in database after test finished), but isExistsInDb in my test class returns false. I do not understand why. Could you please help me.
Thanks!
Activity class:
public abstract class EditActivity {
// Some code .....
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initButtonCancelOk();
}
protected void validateAndSave() {
try {
formValidator.validateAll();
if (formValidator.isFormValid()) {
DatabaseOpenHelper doh = new DatabaseOpenHelper(this);
Dao d = new Dao(doh);
d.add(fetchObjectFromUi());
finish(); // destroy this activity
} else {
ToastImage.makeImageText(context,
R.drawable.warning,
formValidator.getMessages(),
Toast.LENGTH_SHORT
).show();
}
} catch (Exception e) {
Toast.makeText(context, " Error during validate form ", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
private void initButtonCancelOk() {
btnOk = (Button) findViewById(R.id.btn_ok);
btnOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
validateAndSave();
}
});
}
}
Test class:
public class AddItemSmokeTest extends extends ActivityInstrumentationTestCase2<EditActivity> {
protected Activity activity;
protected Solo solo;
public AddItemSmokeTest() {
super("com.myapp", EditActivity.class);
Intent i = createIntent(2);
setActivityIntent(i);
activity = getActivity();
solo = new Solo(getInstrumentation(), activity);
solo.sleep(1000); // interval between tests
}
protected Intent createIntent(long transType) {
Intent i = new Intent();
i.putExtra(INTENT_VALUE_MODE_NAME, MODE_INSERT_TRANSACTION);
i.putExtra(INTENT_VALUE_TYPE_ID_NAME, transType);
return i;
}
#Override
protected void tearDown() throws Exception {
}
protected void setIncomExpenseData(AbsTransIncomeExpenseTestData testData) {
solo.pressSpinnerItem(CATEGORY_SPN_INDEX, testData.getCategorySpinnerPos());
solo.pressSpinnerItem(ACCOUNT_SPN_INDEX, testData.getAccountSpinnerPos());
solo.typeText((EditText) activity.findViewById(com.rirdev.moneycounter.R.id.et_sum), testData.getSum());
solo.typeText((EditText) activity.findViewById(com.rirdev.moneycounter.R.id.et_comment), testData.getComment());
}
#Smoke
public void testAddIncomeTransaction() throws Exception {
initForType(TransactionType.INCOME);
AbsTransIncomeExpenseTestData testData = new IncomeTestData();
setIncomExpenseData(testData);
solo.clickOnButton(OK);
//solo.getActivityMonitor();
assertTrue(
"Item" + testData.getComment() + " was not added ",
isExistsInDb(activity, Transactions.TABLE_NAME, Transactions.DESCRIPTION, testData.getComment())
);
}
protected static boolean isExistsInDb(Context context, String tableName, String commentFieldName, String comment) {
DatabaseOpenHelper doh = new DatabaseOpenHelper(context);
SQLiteDatabase db = doh.getDatabaseReadable();
Cursor cursor = null;
try {
String query = "SELECT COUNT(*) FROM " + tableName + " WHERE " + commentFieldName + " = \"" + comment + "\"";
cursor = db.rawQuery(query, null);
cursor.moveToFirst();
if (cursor.getInt(0) > 1) {
return true;
}
return false;
} finally {
if (cursor != null) {
cursor.close();
}
db.close();
doh.close();
}
}
}
Update:
If I run test the second time it is passed because in database exists item added by previous test.
I recommend to use use parametrized statement, your approach is danger and not much clear.
Also much better is use getCount() method.
String query = "SELECT COUNT(*) FROM " + tableName + " WHERE columnName = ?";
cursor = db.rawQuery(query, new Sring[] {comment});
int count = 0;
if (cursor.getCount() > 0) {
cursor.moveToFirst();
count = cursor.getInt(0);
}
if (count > 0) {
return true;
}
else {
return false;
}
in where clasue use 'string' instead of "string".....
"SELECT COUNT(*) FROM " + tableName + " WHERE " + commentFieldName + " = '" + comment + "'";