Datetime does not show up

后端 未结 2 497
臣服心动
臣服心动 2021-01-26 02:04

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<

相关标签:
2条回答
  • 2021-01-26 02:31

    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.

    public class MainActivity extends ActionBarActivity {
    
        private static final String TAG = MainActivity.class.getSimpleName();
        private int max = 500;
        private TextView primeText;
        private int previousPrimeNumber;
        private List<Prime> primes;
        private PrimeAdapter adapter;
        private MyDBHandler dbManager;
    
        @Override
        protected void onCreate(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 = new MyDBHandler(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 data
            ListView listView = (ListView) findViewById(R.id.listView);
            adapter = new PrimeAdapter(this, primes);
            listView.setAdapter(adapter);
    
            findViewById(R.id.primeButton).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int primeNumber = -1;
                    //increment previousPrimeNumber by one so we wont keep using previousPrimeNumber
                    for (int i = previousPrimeNumber + 1; i <= max; i++) {
                        if (isPrimeNumber(i)) {
                            primeNumber = i;
                            primeText.setText(String.valueOf(i));
                            previousPrimeNumber = i + 1;
                            break;
                        }
                    }
    
                    if (primeNumber != -1) {
                        Prime prime = new Prime(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");
                    }
                }
            });
        }
    
        public boolean isPrimeNumber(int number) {
            for (int i = 2; i <= number / 2; i++) {
                if (number % i == 0) {
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 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
         */
        private class PrimeAdapter extends ArrayAdapter<Prime> {
    
            public PrimeAdapter(Context context, List<Prime> primes) {
                // I am just using androids views. (android.R.id...)
                super(context, android.R.layout.simple_list_item_2, primes);
            }
    
            @Override
            public 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. */
    
                final Prime prime = 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.
                TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
                TextView tv2 = (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 it
                return view;
            }
    
        }
    

    MyDBHandler:

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

    public class MyDBHandler extends SQLiteOpenHelper {
        private static final int DATABASE_VERSION = 1;
        private static final String DATABASE_NAME = "prime.db";
        public static final String TABLE_PRIME = "prime";
        public static final String COLUMN_ID = "_id";
        public static final String COLUMN_PRIMENO = "primeno";
        public static final String COLUMN_DATETIME = "datetime";
    
        public MyDBHandler(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            String query = "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 */
        }
    
        @Override
        public void onUpgrade(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
         */
        public void addPrime(Prime prime) {
            ContentValues values = writePrime(prime);
            SQLiteDatabase db = 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 = new ArrayList<Prime>();
            final SQLiteDatabase db = 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:
             */
    
            final Cursor c = db.query(TABLE_PRIME,
                    new String[]{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()) {
                Prime p = buildPrime(c);
                //check not null
                if (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) {
            final Prime prime = new Prime();
            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 above
            return prime;
        }
    
        /**
         * Convert the prime object in to ContentValues to write to DB
         *
         * @param prime prime
         * @return ContentValues
         */
        private ContentValues writePrime(Prime prime) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_PRIMENO, prime.get_primeno());    //must insert first
            values.put(COLUMN_DATETIME, prime.getDateTime());    //must insert second
            return 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?

    public class Prime {
    
        private static final String format = "yyyy-MM-dd HH:mm:ss";
        private static final SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH);
    
        private int _id;
        private int _primeno;
        private long dateTime = 0; //this is in milliseconds. Makes it easier to manage
    
        public Prime() { }
    
        public Prime(int primeNumber) {
            //create a new prime object with a prime already known. set the date while we are at it
            this._primeno = primeNumber;
            this.dateTime = System.currentTimeMillis();
        }
    
        public void set_id(int _id) {
            this._id = _id;
        }
    
        public void set_primeno(int _primeno) {
            this._primeno = _primeno;
        }
    
        public int get_id() {
            return _id;
        }
    
        public int get_primeno() {
            return _primeno;
        }
    
        public long getDateTime() {
            return dateTime;
        }
    
        public String getDateTimeFormatted() {
            if (dateTime == 0) {
                dateTime = System.currentTimeMillis();
            }
            Date date = new Date(dateTime);
            return formatter.format(date);
        }
    
        public void setDateTime(long dateTime) {
            this.dateTime = dateTime;
        }
    
    }
    
    0 讨论(0)
  • 2021-01-26 02:44

    This seems to work.

    In your values create db.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="prime_table_name">prime</string>
    
        <string name="prime_table_column_id">_id</string>
        <string name="prime_table_column_prime_no">prime_no</string>
        <string name="prime_table_column_datetime">date_time</string>
    
        <string-array name="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>
    
        <string name="createTableOfPrimes">CREATE TABLE prime ( _id INTEGER PRIMARY KEY AUTOINCREMENT, prime_no TEXT, date_time DATETIME DEFAULT CURRENT_TIMESTAMP );</string>
        <string name="dropTableOfPrimes">DROP TABLE IF EXISTS prime</string>
        <string name="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;
    
    public class Prime {
    
        private static final String format = "yyyy-MM-dd HH:mm:ss";
        private static final SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH);
    
        private int id;
        private String primeNo;
        private Calendar dateTime;
    
        public Prime(String primeNo) {
            this.id = -1;
            this.primeNo = primeNo;
            this.dateTime = Calendar.getInstance();
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getPrimeNo() {
            return primeNo;
        }
    
        public void setPrimeNo(String primeNo) {
            this.primeNo = primeNo;
        }
    
        public String getDateTime() {
            return formatter.format(dateTime.getTime());
        }
    
        public void setDateTime(Calendar calendar) {
            this.dateTime = (Calendar) calendar.clone();
        }
    
        public void setDateTime(String dateTimeString) {
            try {
               dateTime.setTime(formatter.parse(dateTimeString));
            } catch (ParseException e) {
              dateTime.setTimeInMillis(0);
           }
        }
    
        public void setDateTimeToNow() {
            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;
    
    public class PrimeDBSQLLiteHelper extends SQLiteOpenHelper {
    
        public static final int DATABASE_VERSION = 1;
        public static final String DATABASE_NAME = "Prime.db";
        private static final String TAG = PrimeDBSQLLiteHelper.class.getSimpleName();
        private WeakReference<Context> mContext;
    
        public PrimeDBSQLLiteHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            mContext = new WeakReference<Context>(context);
    
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            sqLiteDatabase.execSQL(getString(R.string.createTableOfPrimes));
            Log.i(TAG, "DataBase created");
        }
    
        @Override
        public void onUpgrade(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;
    
    public class PrimeDataSource {
    
        private static final String TAG = PrimeDataSource.class.getSimpleName();
        private static byte numberOfInstances;
        private SQLiteDatabase database;
        private PrimeDBSQLLiteHelper primeDBSQLLiteHelper;
        private static PrimeDataSource instance;
        private static final Object LOCK = new Object();
    
        private Context context;
    
    
        protected PrimeDataSource(Context context) {
            this.context = context.getApplicationContext();
        }
    
        public static synchronized PrimeDataSource getInstance(Context context) {
            if (instance == null) {
                instance = new PrimeDataSource(context);
            }
            numberOfInstances++;
            return instance;
        }
    
        public static synchronized void decrementNumberOfInstances() {
    
            if (--numberOfInstances <= 0) {
                instance.close();
            }
            numberOfInstances = numberOfInstances < 0 ? 0 : numberOfInstances; //Sanity?
        }
    
        public static synchronized void forceClose() {
            numberOfInstances = 0;
            instance.close();
        }
    
        private void close() {
            if (isDatabaseOpenOpen()) {
                primeDBSQLLiteHelper.close();
            }
            primeDBSQLLiteHelper = null;
            instance = null;
            database = null;
        }
    
        public synchronized void open() {
            if (database == null || !database.isOpen()) {
                primeDBSQLLiteHelper = new PrimeDBSQLLiteHelper(context);
                database = primeDBSQLLiteHelper.getWritableDatabase();
            }
        }
    
        public boolean isDatabaseOpenOpen() {
            return database != null && database.isOpen();
        }
    
    
        public synchronized void deleteAllPrimesFromDb() {
            try {
                database.delete(getString(R.string.prime_table_name), null, null);
            } catch (Exception e) {
                // Was it really created?
                createTableOfPrimes();
            }
        }
    
        public synchronized void createTableOfPrimes() {
            database.execSQL(getString(R.string.createTableOfPrimes));
        }
    
        public synchronized void dropTableOfJobs() {
            database.execSQL(getString(R.string.dropTableOfPrimes));
        }
    
        public synchronized void dropDataBase() {
            database.execSQL("DROP DATABASE IF EXISTS " + PrimeDBSQLLiteHelper.DATABASE_NAME);
        }
    
        public String getDatabasePath() {
            return (Environment.getDataDirectory() + File.separator + PrimeDBSQLLiteHelper.DATABASE_NAME);
        }
    
        public synchronized void insertListOfPrimes(List<Prime> data) {
            synchronized (LOCK) {
                database.beginTransaction();
                SQLiteStatement stmt = 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;
            Prime p = new Prime(cursor.getString(1));
            p.setId(cursor.getInt(0));
            p.setDateTime(cursor.getString(2));
            return p;
        }
    
        public List<Prime> getListOfPrimes() {
            synchronized (LOCK) {
                List<Prime> listOfPrimes = new ArrayList<Prime>();
    
                Cursor cursor = 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;
            }
        }
    
        public void insertPrime(Prime prime) {
            synchronized (LOCK) {
                database.beginTransaction();
                SQLiteStatement stmt = database.compileStatement(getString(R.string.insertIntoTableOfPrimes));
    
                stmt.bindString(1, prime.getPrimeNo());
                stmt.bindString(2, prime.getDateTime());
    
                stmt.executeInsert();
                stmt.clearBindings();
    
                database.setTransactionSuccessful();
                database.endTransaction();
            }
        }
    
        private int getCountFromCursor(Cursor cursor) {
            int result = cursor.moveToFirst() ? cursor.getCount() : 0;
            cursor.close();
            return result;
        }
    
        public int getPrimeCount() {
            synchronized (LOCK) {
                Cursor cursor = database.query(getString(R.string.prime_table_name), new String[]{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 = new String[integers.length];
            for (int i = 0; i < integers.length; ++i) {
                result[i] = getString(integers[i]);
            }
            return result;
        }
    
    
    }
    

    In Activity

    private PrimeDataSource dataSource;
    
        @Override
        protected void onCreate(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
        protected void onDestroy() {
            super.onDestroy();
            dataSource = null;
            PrimeDataSource.decrementNumberOfInstances();
        }
    

    LogCat output:

    04-07 22:45:18.590    1005-1005/si.kseneman.mobile I/PrimeDataSource﹕ Insertion success
    04-07 22:45:18.590    1005-1005/si.kseneman.mobile I/Prime:﹕ 1 ; 2015-04-07 22:45:18
    04-07 22:45:18.590    1005-1005/si.kseneman.mobile I/Prime:﹕ 3 ; 2015-04-07 22:45:18
    04-07 22:45:18.590    1005-1005/si.kseneman.mobile I/Prime:﹕ 5 ; 2015-04-07 22:45:18
    04-07 22:45:18.590    1005-1005/si.kseneman.mobile I/Prime:﹕ 7 ; 2015-04-07 22:45:18
    04-07 22:45:18.590    1005-1005/si.kseneman.mobile I/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

    0 讨论(0)
提交回复
热议问题