小编典典

日期时间不显示

java

我正在尝试显示时间戳记-
我尝试了onCreate不同的查询方式,并且还尝试将addTime用作值addPrime。似乎没有任何作用。我的目的是让该应用显示以前的素数和它们被发现的时间。该应用程序的初衷是让用户能够关闭/杀死该应用程序,并在重新启动该应用程序时从上次找到的素数恢复计数。如果您有任何暗示,我也将不胜感激。

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

}

头等舱

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

阅读 217

收藏
2020-11-30

共1个答案

小编典典

好的,既然您上传了项目,我 我已经按照您想要的方式进行了工作。尽管如此,它仍在工作。

有几个错误-主要是逻辑错误。我尽我所能地发表评论,以便您了解我为什么/什么都做。

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

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


您可以在此处下载该项目,也可以只看一下代码片段:

主要活动

我添加了一个,ListView以便您可以看到所有素数。还更改了我们从数据库获取数据的方式/位置以及保存到数据库的方式。

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:

更改了查询并添加了两种方法,它们将分别转换PrimeContentValues对象和Cursor质数。

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的目的是存储一个素数整数。那么,为什么不将该字段设为整数呢?

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

}
2020-11-30