日期时间不会显示

我试图让时间戳显示 – 我以不同的方式尝试了onCreate查询,并尝试将addTime作为addTime中的值。 似乎没什么用。 我的目的是让应用程序显示以前的素数和它们被发现的时间。 该应用程序的目的是让用户能够关闭/终止该应用程序,并在重新启动应用程序时从最后找到的素数重新开始计数,如果您有任何提示,这将如何可行,我将不胜感激。

这是PrimeDBManager类

 public class PrimeDBManager 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 PrimeDBManager(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, DATABASE_NAME, factory, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String query = "CREATE TABLE " + TABLE_PRIME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_PRIMENO + " TEXT " + COLUMN_DATETIME + " DATETIME DEFAULT CURRENT_TIMESTAMP " + ");"; db.execSQL(query); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRIME); onCreate(db); } //Add a new prime to the database public void addPrime(Prime prime){ ContentValues values = new ContentValues(); values.put(COLUMN_PRIMENO, prime.get_primeno()); SQLiteDatabase db = getWritableDatabase(); db.insert(TABLE_PRIME, null, values); } public void addTime(Prime prime) { ContentValues values = new ContentValues(); values.put(COLUMN_DATETIME, prime.get_datetime()); SQLiteDatabase db = getWritableDatabase(); db.insert(TABLE_PRIME, null, values); } public String databaseToString(){ String dbString = ""; SQLiteDatabase db = getWritableDatabase(); String query = "SELECT * FROM " + TABLE_PRIME + " WHERE 1"; Cursor c = db.rawQuery(query, null); c.moveToFirst(); while(!c.isAfterLast()) { if (c.getString(c.getColumnIndex("primeno"))!=null){ dbString += c.getString(c.getColumnIndex("primeno")); dbString += "\n"; } c.moveToNext(); } db.close(); return dbString; } } 

Prime课程

 public class Prime { private int _id; private String _primeno; private String _datetime; public Prime(){ } public Prime(String _primeno) { this._primeno = _primeno; } public void set_id(int _id) { this._id = _id; } public void set_primeno(String _primeno) { this._primeno = _primeno; } public int get_id() { return _id; } public String get_primeno() { return _primeno; } public void set_datetime(String _datetime) { this._datetime = _datetime; } public String get_datetime() { return _datetime; } } 

最后是MainActivity类

 public class MainActivity extends ActionBarActivity { Button primeButton; int max = 500; TextView primeText; int j = 2; TextView previousPrime; PrimeDBManager dbManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); primeButton = (Button) findViewById(R.id.primeButton); primeText = (TextView) findViewById(R.id.primeText); previousPrime = (TextView) findViewById(R.id.previousPrime); dbManager = new PrimeDBManager(this, null, null, 1); printDatabase(); primeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = j; i <= max; i++) { if (isPrimeNumber(i)) { primeText.setText(i+""); j = i+1; break; } } Prime prime = new Prime(primeText.getText().toString()); dbManager.addPrime(prime); dbManager.addTime(prime); printDatabase(); } }); } public void printDatabase () { String dbString = dbManager.databaseToString(); previousPrime.setText(dbString); } public boolean isPrimeNumber(int number) { for (int i = 2; i <= number / 2; i++) { if (number % i == 0) { return false; } } return true; } } 

好的,既然你上传了你的项目,我我的工作方式就是你想要的。 尽管如此,它还是有效的。

有几个错误 – 主要是逻辑。 我尽可能多地评论,以便你能理解为什么/为什么我在做所有事情。

我没有评论的一件事是AndroidManifest需要许可:


你可以在这里下载项目 ,或者只看一下片段:

主要活动

我添加了一个ListView这样你就可以看到所有素数。 还改变了我们从DB获取数据的方式/位置,以及我们如何保存到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 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 { public PrimeAdapter(Context context, List 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:

更改了查询并添加了两个方法,将Prime转换为ContentValues对象,从Cursor转换为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 getPrimeObjects() { final List primes = new ArrayList(); 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的目的是存储一个素数。 那么为什么不将该字段设为整数呢?

 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; } } 

这似乎有效。

在您的值中创建db.xml

   prime _id prime_no date_time  @string/prime_table_column_id @string/prime_table_column_prime_no @string/prime_table_column_datetime  CREATE TABLE prime ( _id INTEGER PRIMARY KEY AUTOINCREMENT, prime_no TEXT, date_time DATETIME DEFAULT CURRENT_TIMESTAMP ); DROP TABLE IF EXISTS prime INSERT INTO prime (prime_no, date_time) VALUES(?,?)  

Prime课程

 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助手

 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 mContext; public PrimeDBSQLLiteHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); mContext = new WeakReference(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数据库

  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 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 getListOfPrimes() { synchronized (LOCK) { List listOfPrimes = new ArrayList(); 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; } } 

在活动中

 private PrimeDataSource dataSource; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); dataSource = PrimeDataSource.getInstance(getApplicationContext()); dataSource.open(); List demoListOfPrimes = new ArrayList(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输出:

 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 

PS你可能需要卸载你的应用程序或放弃你的表格才能工作

这是一个简单项目的zip,显示listview活动中的数字: LINK