Datetime does not show up

旧巷老猫 提交于 2020-01-11 14:06:12

问题


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 intention is for the app to show previous primes and the time that they were found. The intention for the app is for the user to be able to close/kill the app and resume counting from last found prime number when restarting the app, if you have any hints how also this would be possible I would be grateful.

This is the PrimeDBManager class

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 class

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

And lastly the MainActivity class

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

回答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.

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

}



回答2:


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



来源:https://stackoverflow.com/questions/29498565/datetime-does-not-show-up

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!