简体   繁体   中英

Why can't I add these default values in my SQLite database in Android?

So I'm building an alarm application. I want to display a few default alarms when the application is first installed. For example, 3 alarms at 7am, 8am and 9am. Below is my code.

getAllAlarms() is called to retrieve the list of alarms to be displayed. On first load up, the database would be empty, so I want to insert some default values if that is the case. This can be seen in the else statement where I add the alarms and then do a recursive call on itself. My understand is that after adding the 3 alarms, I call getAllAlarms again, it should enter the if statement normally. This appears to be the case as can be seen in the debug System.out.println statements. The list of alarms is printed out as expected however, somewhere along the line it appears the method is called again which results in the list being made empty as can be seen in the last debug statements.

Can you see where problem is? I've done a file search in the project and I'm not calling the delete method anywhere nor am I calling getAllAlarms apart from inside the method itself and in the ListActivity . The problem must be localized in the getAllAlarms method I think but I can't find it. Is it the recursive call?

   // Getting All Alarms
public List<Alarm> getAllAlarms() {
    List<Alarm> alarmList = new ArrayList<Alarm>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_ALARMS;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Alarm alarm = new Alarm();
            alarm.setID(cursor.getInt(0));
            alarm.setHour(cursor.getInt(1));
            alarm.setMinutes(cursor.getInt(2));
            // Adding alarm to list
            alarmList.add(alarm);
            System.out.println("inside loop");
            System.out.println(alarmList);

        } while (cursor.moveToNext());
    }
    else
    {           
        System.out.println("Adding default values...");
        addAlarm(new Alarm(7,0));
        addAlarm(new Alarm(8,0));
        addAlarm(new Alarm(9,0));
        System.out.println("Finished adding default values...");
        getAllAlarms();
    }

    System.out.println("before");
    System.out.println(alarmList);
    System.out.println("after");
    // return alarm list
    return alarmList;
}

This is my add method:

void addAlarm(Alarm alarm) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_HOUR, alarm.getHour()); // Alarm Name
    values.put(KEY_MINUTES, alarm.getMinutes()); // Alarm Phone

    // Inserting Row
    db.insert(TABLE_ALARMS, null, values);
    db.close(); // Closing database connection
}

Debug output:

04-23 16:17:49.261: I/System.out(10938): Adding default values...
04-23 16:17:49.291: I/System.out(10938): Finished adding default values...
04-23 16:17:49.291: I/System.out(10938): inside loop
04-23 16:17:49.291: I/System.out(10938): [07:00]
04-23 16:17:49.296: I/System.out(10938): inside loop
04-23 16:17:49.296: I/System.out(10938): [07:00, 08:00]
04-23 16:17:49.296: I/System.out(10938): inside loop
04-23 16:17:49.296: I/System.out(10938): [07:00, 08:00, 09:00]
04-23 16:17:49.296: I/System.out(10938): before
04-23 16:17:49.296: I/System.out(10938): [07:00, 08:00, 09:00]
04-23 16:17:49.296: I/System.out(10938): after
04-23 16:17:49.296: I/System.out(10938): before
04-23 16:17:49.296: I/System.out(10938): []
04-23 16:17:49.296: I/System.out(10938): after

UPDATE::

I've tried this to no avail:

if (cursor.moveToFirst()) { do { Alarm alarm = new Alarm(); alarm.setID(cursor.getInt(0)); alarm.setHour(cursor.getInt(1)); alarm.setMinutes(cursor.getInt(2)); // Adding alarm to list alarmList.add(alarm); System.out.println("inside loop"); System.out.println(alarmList);

    } while (cursor.moveToNext());            
}
else
{           
    System.out.println("Adding default values...");
    addAlarm(new Alarm(7,0));
    addAlarm(new Alarm(8,0));
    addAlarm(new Alarm(9,0));
    System.out.println("Finished adding default values...");
}

if(alarmList.isEmpty() || alarmList == null)
{
    System.out.println("test"  + alarmList);
    getAllAlarms();
}

However, this works by itself if I remove the if statement to check for the empty list and then I add the check outside the Database and inside the ListActivity . This is not what I want though. I don't want to be handling default value insertion outside the Database class.

else {
System.out.println("Adding default values..."); addAlarm(new Alarm(7,0)); addAlarm(new Alarm(8,0)); addAlarm(new Alarm(9,0)); System.out.println("Finished adding default values..."); }

and inside ListActivity :

protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_list);

Database db = new Database(AlarmListActivity.this);
list = db.getAllAlarms();
if(list.isEmpty())
{
    list = db.getAllAlarms();
}
....
....

}

As @umesh suggested, use getReadableDatabase(), no need for db.close(), but most importantly wrap you writes in a transaction:

db.beginTransaction();
// insert
db.setTransactionSuccessful();
db.endTransaction();

Update: singleton(ish) pattern

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

public class DBOpenHelper extends SQLiteOpenHelper {

    private enum OpenHelperEnum {
        INSTANCE; // Singleton instance;

        // Instance of dbHelper for all DB access in threads
        private SQLiteOpenHelper dbHelper = null;
        private SQLiteDatabase database = null;

        public SQLiteDatabase getDB(final Context context) {
            if (dbHelper == null) {
                dbHelper = new DBOpenHelper(context);
            }
            if (database == null) {
                database = dbHelper.getReadableDatabase();
            }
            return database;
        }
    }

    public DBOpenHelper(final Context context) {
        super(context, "DBName", null, 1);
    }

    @Override
    public void onCreate(final SQLiteDatabase database) {
        // ...
    }

    @Override
    public void onUpgrade(final SQLiteDatabase database, final int oldVersion, final int newVersion) {
        // ...
    }

    @Override
    public void onDowngrade(final SQLiteDatabase database, final int oldVersion, final int newVersion) {
        // ...
    }

    public static SQLiteDatabase getDB(final Context context) {
        return DBOpenHelper.OpenHelperEnum.INSTANCE.getDB(context);
    }
}

To get the databse use:

final SQLiteDatabase db = DBOpenHelper.getDB(this);

in getAllAlarms method just change

getWritableDatabase

to

getReadableDatabase  

like below

String selectQuery = "SELECT  * FROM " + TABLE_ALARMS;

SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM