Skip to content Skip to sidebar Skip to footer

Datetime Does Not Show Up

I am trying to get timestamp to show- I have tried the onCreate query in different ways and also tried to to have addTime as a value in addPrime. Nothing seems to work. My intentio

Solution 1:

Ok, since you uploaded your project I think I got it working the way you want. It is working nonetheless.

There were several errors - mostly with logic. I tried to comment as much as I could so you can understand what/why I was doing everything.

One thing I did not comment was that the AndroidManifest needed permission:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


You can download the project here, or just look at the snippets:

MainActivity

I added a ListView so you can see all the primes. Also changed how/where we get the data from the DB, and how we save to DB.

publicclassMainActivityextendsActionBarActivity {

    privatestaticfinalStringTAG= MainActivity.class.getSimpleName();
    privateintmax=500;
    private TextView primeText;
    privateint previousPrimeNumber;
    private List<Prime> primes;
    private PrimeAdapter adapter;
    private MyDBHandler dbManager;

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        primeText = (TextView) findViewById(R.id.primeText);

        //get the object from previous session. Remember these are sorted by date
        dbManager = newMyDBHandler(this);
        primes = dbManager.getPrimeObjects();

        //get the first prime. (AKA the last one added)if (primes.size() != 0) {
            previousPrimeNumber = primes.get(0).get_primeno(); //get the first item
            primeText.setText(String.valueOf(previousPrimeNumber));
        } else {
            previousPrimeNumber = 2;
        }

        //create list view and adapter to display the dataListViewlistView= (ListView) findViewById(R.id.listView);
        adapter = newPrimeAdapter(this, primes);
        listView.setAdapter(adapter);

        findViewById(R.id.primeButton).setOnClickListener(newView.OnClickListener() {
            @OverridepublicvoidonClick(View v) {
                intprimeNumber= -1;
                //increment previousPrimeNumber by one so we wont keep using previousPrimeNumberfor (inti= previousPrimeNumber + 1; i <= max; i++) {
                    if (isPrimeNumber(i)) {
                        primeNumber = i;
                        primeText.setText(String.valueOf(i));
                        previousPrimeNumber = i + 1;
                        break;
                    }
                }

                if (primeNumber != -1) {
                    Primeprime=newPrime(primeNumber);
                    dbManager.addPrime(prime);
                    /* Yes, it saved to our database. But there is no reason for us to read from
                     * it too when we have the prime object right here. So just add it to the
                     * adapter and be done *///The adapter is looking at the list primes. So add it to the top and notify
                    primes.add(0, prime);
                    adapter.notifyDataSetChanged();
                } else {
                    Log.e(TAG, "Oops, there was an error. Invalid prime number");
                }
            }
        });
    }

    publicbooleanisPrimeNumber(int number) {
        for (inti=2; i <= number / 2; i++) {
            if (number % i == 0) {
                returnfalse;
            }
        }
        returntrue;
    }

    /**
     * If this is too confusing you can ignore it for now.
     * However, I recommend understanding the android UIs before diving in to database storage.
     * Take a look at this link:
     * http://www.vogella.com/tutorials/AndroidListView/article.html
     */privateclassPrimeAdapterextendsArrayAdapter<Prime> {

        publicPrimeAdapter(Context context, List<Prime> primes) {
            // I am just using androids views. (android.R.id...)super(context, android.R.layout.simple_list_item_2, primes);
        }

        @Overridepublic View getView(int position, View view, ViewGroup parent) {
            /* This method will automagically get called for every item in the list.
             * This is an ARRAY adapter. So it has a list of the data we passed in on
             * the constructor. So by calling "this" we are accessing it like it were a list
             * which it really is. */finalPrimeprime=this.getItem(position);

            if (view == null) {
                view = LayoutInflater.from(MainActivity.this)
                        .inflate(android.R.layout.simple_list_item_2, null);
            }

            /* if you look at simple_list_item_2, you will see two textViews. text1 and text2.
             * Normally you would create this view yourself, but like i said, that is not the
             * reason I am here */// Notice I am referencing android.R.id. and not R.id. That is cause I am lazy and// didn't create my own views.TextViewtv1= (TextView) view.findViewById(android.R.id.text1);
            TextViewtv2= (TextView) view.findViewById(android.R.id.text2);

            tv1.setText(String.valueOf(prime.get_primeno()));
            tv2.setText(prime.getDateTimeFormatted());

            //now return the view so the listView knows to show itreturn view;
        }

    }

MyDBHandler:

Changed the queries and added two methods that will convert Prime to a ContentValues object and from Cursor to a prime.

publicclassMyDBHandlerextendsSQLiteOpenHelper {
    privatestaticfinalintDATABASE_VERSION=1;
    privatestaticfinalStringDATABASE_NAME="prime.db";
    publicstaticfinalStringTABLE_PRIME="prime";
    publicstaticfinalStringCOLUMN_ID="_id";
    publicstaticfinalStringCOLUMN_PRIMENO="primeno";
    publicstaticfinalStringCOLUMN_DATETIME="datetime";

    publicMyDBHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @OverridepublicvoidonCreate(SQLiteDatabase db) {
        Stringquery="CREATE TABLE " + TABLE_PRIME + "(" +
                /* This must be in same order everywhere! */
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +    // ID will be index 0
                COLUMN_PRIMENO + " INTEGER, " +                         // Prime will be index 1
                COLUMN_DATETIME + " LONG);";                            // Date will be index 2
        db.execSQL(query);

        /* Something else to note: I changed the column types. You had text for these,
         * which is fine. But the object that you are storing in each of these is not
         * a string. So for consistency store the object as its original class type:
         * PrimeNo == integer
         * Datetime == long (milliseconds)
         * This also makes it so sorting is much easier */
    }

    @OverridepublicvoidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRIME);
        onCreate(db);
    }

    /**
     * You want to save the entire Prime object at once. Not bits and pieces.
     *
     * @param prime
     */publicvoidaddPrime(Prime prime) {
        ContentValuesvalues= writePrime(prime);
        SQLiteDatabasedb= getWritableDatabase();
        db.insert(TABLE_PRIME, null, values);
        /* DON'T FORGET TO CLOSE YOUR DATABASE! */
        db.close();
    }

    /**
     * Again, you want to receive the entire prime object at once. Not bits.
     *
     * @return List of previous prime objects
     */public List<Prime> getPrimeObjects() {
        final List<Prime> primes = newArrayList<Prime>();
        finalSQLiteDatabasedb= getWritableDatabase();
        /* Normally i would use this line of code:

        final Cursor c = db.rawQuery("SELECT * FROM " + TABLE_PRIME, null);

        but, you want to be sure you will get them order by DATE so you know
        the first prime in the list is the last added. so I switched the query to this:
         */finalCursorc= db.query(TABLE_PRIME,
                newString[]{COLUMN_ID, COLUMN_PRIMENO, COLUMN_DATETIME},
                null, null, null, null, //much null. So wow.
                COLUMN_DATETIME + " DESC"); //order in descending./* After queried the first item will be our starting point */

        c.moveToFirst();
        while (c.moveToNext()) {
            Primep= buildPrime(c);
            //check not nullif (p != null)
                primes.add(p); //add to list
        }

        /* DON'T FORGET TO CLOSE YOUR DATABASE AND CURSOR! */
        c.close();
        db.close();
        return primes;
    }

    /**
     * Convert the Cursor object back in to a prime number
     *
     * @param cursor Cursor
     * @return Prime
     */private Prime buildPrime(Cursor cursor) {
        finalPrimeprime=newPrime();
        prime.set_id(cursor.getInt(0));             // id index as stated above
        prime.set_primeno(cursor.getInt(1));        // prime index as stated above
        prime.setDateTime(cursor.getLong(2));        // date index as stated abovereturn prime;
    }

    /**
     * Convert the prime object in to ContentValues to write to DB
     *
     * @param prime prime
     * @return ContentValues
     */private ContentValues writePrime(Prime prime) {
        ContentValuesvalues=newContentValues();
        values.put(COLUMN_PRIMENO, prime.get_primeno());    //must insert first
        values.put(COLUMN_DATETIME, prime.getDateTime());    //must insert secondreturn values;
    }

}

Prime:

I just changed the value types. Prime's purpose is to store a prime integer. So why not make that field a integer?

publicclassPrime {

    privatestatic final String format = "yyyy-MM-dd HH:mm:ss";
    privatestatic final SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH);

    privateint _id;
    privateint _primeno;
    privatelong dateTime = 0; //this is in milliseconds. Makes it easier to managepublicPrime() { }

    publicPrime(int primeNumber) {
        //create a new prime object with a prime already known. set the date while we are at itthis._primeno = primeNumber;
        this.dateTime = System.currentTimeMillis();
    }

    publicvoidset_id(int _id) {
        this._id = _id;
    }

    publicvoidset_primeno(int _primeno) {
        this._primeno = _primeno;
    }

    publicintget_id() {
        return _id;
    }

    publicintget_primeno() {
        return _primeno;
    }

    publiclonggetDateTime() {
        return dateTime;
    }

    public String getDateTimeFormatted() {
        if (dateTime == 0) {
            dateTime = System.currentTimeMillis();
        }
        Date date = new Date(dateTime);
        return formatter.format(date);
    }

    publicvoidsetDateTime(long dateTime) {
        this.dateTime = dateTime;
    }

}

Solution 2:

This seems to work.

In your values create db.xml

<?xml version="1.0" encoding="utf-8"?><resources><stringname="prime_table_name">prime</string><stringname="prime_table_column_id">_id</string><stringname="prime_table_column_prime_no">prime_no</string><stringname="prime_table_column_datetime">date_time</string><string-arrayname="prime_table_all_columns"><item>@string/prime_table_column_id</item><item>@string/prime_table_column_prime_no</item><item>@string/prime_table_column_datetime</item></string-array><stringname="createTableOfPrimes">CREATE TABLE prime ( _id INTEGER PRIMARY KEY AUTOINCREMENT, prime_no TEXT, date_time DATETIME DEFAULT CURRENT_TIMESTAMP );</string><stringname="dropTableOfPrimes">DROP TABLE IF EXISTS prime</string><stringname="insertIntoTableOfPrimes">INSERT INTO prime (prime_no, date_time) VALUES(?,?)</string></resources>

Prime class

package si.kseneman.utilities;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

publicclassPrime {

    privatestaticfinalStringformat="yyyy-MM-dd HH:mm:ss";
    privatestaticfinalSimpleDateFormatformatter=newSimpleDateFormat(format, Locale.ENGLISH);

    privateint id;
    private String primeNo;
    private Calendar dateTime;

    publicPrime(String primeNo) {
        this.id = -1;
        this.primeNo = primeNo;
        this.dateTime = Calendar.getInstance();
    }

    publicintgetId() {
        return id;
    }

    publicvoidsetId(int id) {
        this.id = id;
    }

    public String getPrimeNo() {
        return primeNo;
    }

    publicvoidsetPrimeNo(String primeNo) {
        this.primeNo = primeNo;
    }

    public String getDateTime() {
        return formatter.format(dateTime.getTime());
    }

    publicvoidsetDateTime(Calendar calendar) {
        this.dateTime = (Calendar) calendar.clone();
    }

    publicvoidsetDateTime(String dateTimeString) {
        try {
           dateTime.setTime(formatter.parse(dateTimeString));
        } catch (ParseException e) {
          dateTime.setTimeInMillis(0);
       }
    }

    publicvoidsetDateTimeToNow() {
        this.dateTime = Calendar.getInstance();
    }
}

Prie SQL Lite Helper

package si.kseneman.utilities;

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

import java.lang.ref.WeakReference;

import si.kseneman.mobile.R;

publicclassPrimeDBSQLLiteHelperextendsSQLiteOpenHelper {

    publicstaticfinalintDATABASE_VERSION=1;
    publicstaticfinalStringDATABASE_NAME="Prime.db";
    privatestaticfinalStringTAG= PrimeDBSQLLiteHelper.class.getSimpleName();
    private WeakReference<Context> mContext;

    publicPrimeDBSQLLiteHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        mContext = newWeakReference<Context>(context);

    }

    @OverridepublicvoidonCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(getString(R.string.createTableOfPrimes));
        Log.i(TAG, "DataBase created");
    }

    @OverridepublicvoidonUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        sqLiteDatabase.execSQL(getString(R.string.dropTableOfPrimes));
        this.onCreate(sqLiteDatabase);
    }

    private String getString(int resID) {
        return mContext.get() != null ? mContext.get().getString(resID) : null;
    }
}

Prime SingleTon database

package si.kseneman.utilities;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;
import android.os.Environment;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import si.kseneman.mobile.R;

publicclassPrimeDataSource {

    privatestaticfinalStringTAG= PrimeDataSource.class.getSimpleName();
    privatestaticbyte numberOfInstances;
    private SQLiteDatabase database;
    private PrimeDBSQLLiteHelper primeDBSQLLiteHelper;
    privatestatic PrimeDataSource instance;
    privatestaticfinalObjectLOCK=newObject();

    private Context context;


    protectedPrimeDataSource(Context context) {
        this.context = context.getApplicationContext();
    }

    publicstaticsynchronized PrimeDataSource getInstance(Context context) {
        if (instance == null) {
            instance = newPrimeDataSource(context);
        }
        numberOfInstances++;
        return instance;
    }

    publicstaticsynchronizedvoiddecrementNumberOfInstances() {

        if (--numberOfInstances <= 0) {
            instance.close();
        }
        numberOfInstances = numberOfInstances < 0 ? 0 : numberOfInstances; //Sanity?
    }

    publicstaticsynchronizedvoidforceClose() {
        numberOfInstances = 0;
        instance.close();
    }

    privatevoidclose() {
        if (isDatabaseOpenOpen()) {
            primeDBSQLLiteHelper.close();
        }
        primeDBSQLLiteHelper = null;
        instance = null;
        database = null;
    }

    publicsynchronizedvoidopen() {
        if (database == null || !database.isOpen()) {
            primeDBSQLLiteHelper = newPrimeDBSQLLiteHelper(context);
            database = primeDBSQLLiteHelper.getWritableDatabase();
        }
    }

    publicbooleanisDatabaseOpenOpen() {
        return database != null && database.isOpen();
    }


    publicsynchronizedvoiddeleteAllPrimesFromDb() {
        try {
            database.delete(getString(R.string.prime_table_name), null, null);
        } catch (Exception e) {
            // Was it really created?
            createTableOfPrimes();
        }
    }

    publicsynchronizedvoidcreateTableOfPrimes() {
        database.execSQL(getString(R.string.createTableOfPrimes));
    }

    publicsynchronizedvoiddropTableOfJobs() {
        database.execSQL(getString(R.string.dropTableOfPrimes));
    }

    publicsynchronizedvoiddropDataBase() {
        database.execSQL("DROP DATABASE IF EXISTS " + PrimeDBSQLLiteHelper.DATABASE_NAME);
    }

    public String getDatabasePath() {
        return (Environment.getDataDirectory() + File.separator + PrimeDBSQLLiteHelper.DATABASE_NAME);
    }

    publicsynchronizedvoidinsertListOfPrimes(List<Prime> data) {
        synchronized (LOCK) {
            database.beginTransaction();
            SQLiteStatementstmt= database.compileStatement(getString(R.string.insertIntoTableOfPrimes));
            for (Prime p : data) {
                stmt.bindString(1, p.getPrimeNo());
                stmt.bindString(2, p.getDateTime());

                stmt.executeInsert();
                stmt.clearBindings();
            }
            database.setTransactionSuccessful();
            database.endTransaction();
            Log.i(TAG, "Insertion success");
        }
    }

    private Prime cursorToPrime(Cursor cursor) {
        // ID = 0 ; primeNo = 1; dateTime = 2;Primep=newPrime(cursor.getString(1));
        p.setId(cursor.getInt(0));
        p.setDateTime(cursor.getString(2));
        return p;
    }

    public List<Prime> getListOfPrimes() {
        synchronized (LOCK) {
            List<Prime> listOfPrimes = newArrayList<Prime>();

            Cursorcursor= database.query(getString(R.string.prime_table_name), getStringArray(R.array.prime_table_all_columns), null, null, null, null, null);

            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                listOfPrimes.add(cursorToPrime(cursor));
                cursor.moveToNext();
            }

            return listOfPrimes;
        }
    }

    publicvoidinsertPrime(Prime prime) {
        synchronized (LOCK) {
            database.beginTransaction();
            SQLiteStatementstmt= database.compileStatement(getString(R.string.insertIntoTableOfPrimes));

            stmt.bindString(1, prime.getPrimeNo());
            stmt.bindString(2, prime.getDateTime());

            stmt.executeInsert();
            stmt.clearBindings();

            database.setTransactionSuccessful();
            database.endTransaction();
        }
    }

    privateintgetCountFromCursor(Cursor cursor) {
        intresult= cursor.moveToFirst() ? cursor.getCount() : 0;
        cursor.close();
        return result;
    }

    publicintgetPrimeCount() {
        synchronized (LOCK) {
            Cursorcursor= database.query(getString(R.string.prime_table_name), newString[]{getString(R.string.prime_table_column_id)}, null, null, null, null, null);
            return getCountFromCursor(cursor);
        }
    }


    private String getString(int resID) {
        return context.getString(resID);
    }

    private String[] getStringArray(int resID) {
        return context.getResources().getStringArray(resID);
    }

    private String[] getStringArrayFromResources(int... integers) {
        String[] result = newString[integers.length];
        for (inti=0; i < integers.length; ++i) {
            result[i] = getString(integers[i]);
        }
        return result;
    }


}

In Activity

private PrimeDataSource dataSource;

    @Override
    protectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        dataSource = PrimeDataSource.getInstance(getApplicationContext());
        dataSource.open();

        List<Prime> demoListOfPrimes = new ArrayList<Prime>(5);

        demoListOfPrimes.add(new Prime("1"));
        demoListOfPrimes.add(new Prime("3"));
        demoListOfPrimes.add(new Prime("5"));
        demoListOfPrimes.add(new Prime("7"));
        demoListOfPrimes.add(new Prime("11"));

        dataSource.insertListOfPrimes(demoListOfPrimes);

        demoListOfPrimes = dataSource.getListOfPrimes();

        if(demoListOfPrimes.size() == 0){
            Log.i("", "Empty list");
        }

        for (Prime p : demoListOfPrimes) {
            Log.i("Prime: ", p.getPrimeNo() + " ; " + p.getDateTime());
        }

    }

    @Override
    protectedvoidonDestroy() {
        super.onDestroy();
        dataSource = null;
        PrimeDataSource.decrementNumberOfInstances();
    }

LogCat output:

04-0722:45:18.5901005-1005/si.kseneman.mobileI/PrimeDataSource﹕Insertionsuccess04-0722:45:18.5901005-1005/si.kseneman.mobileI/Prime:﹕1;2015-04-07 22:45:1804-0722:45:18.5901005-1005/si.kseneman.mobileI/Prime:﹕3;2015-04-07 22:45:1804-0722:45:18.5901005-1005/si.kseneman.mobileI/Prime:﹕5;2015-04-07 22:45:1804-0722:45:18.5901005-1005/si.kseneman.mobileI/Prime:﹕7;2015-04-07 22:45:1804-0722:45:18.5901005-1005/si.kseneman.mobileI/Prime:﹕11;2015-04-07 22:45:18

P.S. you may need to uninstall your app or drop your table for this to work

Here is a zip of a simple project that displays the numbers in a listview activity: LINK

Post a Comment for "Datetime Does Not Show Up"