In my Android app, I'm trying to retrieve a string from my database based on the date. But I don't want the year in the date (that way I only have to have 365 rows). The only way I've gotten it to work is in my DB, have the date in the Date column be in the format yyyyMMdd. If I change all the dates in the Date column to be in the format MMdd, the double digit months (like Oct, Nov, Dec) work, but the single digit months like Jan. or Sept. (01, 09) crash the app with the error CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0. I've tried the formats MM-dd, yyyy-MM-dd, in the DB and they crash the app with the error listed above. Is it not possible to have the date formatted with just MMdd in a Sqlite database? Any ideas?
MainActivity:
DBT = new SimpleDateFormat("MMdd", Locale.US);
tMMddStr = DBT.format(new Date(System.currentTimeMillis()));
private void getTH() {
dba.open();
tArray = dba.getTHA(tMMddStr);
dba.close();
optionB_TV.setText(todayArray[2]);
hideDayAtv.setText(todayArray[1]);
hideYearAtv.setText(todayArray[0]);
}
DBAdapter:
public String[] getTHA(String tMMddStr) {
String[] columns = new String[] { KEY_Y, KEY_MD, KEY_HA };
Cursor cursor = db.query(DB_TABLE, columns, KEY_DATE + "=" + tMMddStr,
null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
String hapT[] = new String[3];
hapT[0] = cursor.getString(0);
hapT[1] = cursor.getString(1);
hapT[2] = cursor.getString(2);
cursor.close();
this.db.close();
return hapT;
}
return null;
}
CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
This error means that you are trying to read an empty Cursor, simply check if the Cursor has any data before trying to read it:
if (cursor != null && cursor.moveToFirst()) {
As far as the single digit month problem, this could be related to the KEY_DATE column's data type. If KEY_DATE is any type of number, it will strip out the first 0. Try doing the same to tMMddStr.
(If this didn't help, post your tables CREATE statement and a few examples of how you are putting data into the database and pulling it out.)
Related
Am new for android development here is my doubt i have saved the datetime field as text in sqlite how to get the maximum datetime among these records how can i achieve this i came to know that it can be achieved through Max() query i tried but am not getting the result here let me post what i have tried so far:
Here is the Sqlite Query:
public String DateTime(){
String str="";
Cursor cursor = db.query(CustomerModel.CustomerTable , new String [] {"MAX(" + CustomerModel.Customer_LastMofiedFlag +")"}, null, null, null, null, null);
if(cursor.moveToFirst()) { // to move the cursor to first record
int index = cursor.getColumnIndex(CustomerModel.Customer_LastMofiedFlag);
str = cursor.getString(index);
} mcontext.getContentResolver().notifyChange(DB_Timetracker, null);
return str;
}
Is it possible to get the maximum datetime in text format am saving the datetime format in yyyy-MM-dd HH:mm:ss how can i achieve this!!
Maybe you can try to save it in long format?
I have dates stored in a SQLite table in int format (i.e. milliseconds - derived from System.currentTimeMillis()). I now want to query all rows from the table where the date is equal to today's date, but the query below always returns zero, even though file_uploaded_date in the upload_history table is set to today's date in at least 20 rows.
Can anyone tell me what's wrong with my query?
String today = new SimpleDateFormat("d-MMMM-yyyy").format(new Date());
String sql = "SELECT COUNT(*) as uploaded_today from upload_history "
+ "WHERE strftime('%-d-%b-%Y',file_uploaded_date) = strftime('%-d-%b-%Y','" + today + "')";
Cursor cursor = db.rawQuery(sql, null);
if(cursor != null && cursor.moveToFirst()){
int uploadedToday = cursor.getInt(cursor.getColumnIndex("uploaded_today"));
}
I'd say you have your format-strings incorrect.
I don't see a %b argument in the documentation. For month, you would want to use %m. Also %-d doesn't seem right. Use the following format string instead: %Y%m%d.
Further, you are then passing a poorly-formatted string into the query, rather than the int, and relying an sqlite to correct that. Instead, compare to a SimpleDateFormat( "yyyyMMdd" ) without further conversion.
Your code would then look like this:
String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
String sql = "SELECT COUNT(*) from upload_history "
+ "WHERE strftime('%Y%m%d',file_uploaded_date) = '" + today + "')";
Cursor cursor = db.rawQuery(sql, null);
if(cursor != null && cursor.moveToFirst()){
int uploadedToday = cursor.getInt(0);
}
(Note that if you return only one column, you don't have to name it, and can just access the first column for the result.)
Further, please be aware that this query will cause a table-scan every time it's executed, as sqlite needs to convert all the epochs to strings. You'd be better off adding a date column to the table, and update it once:
UPDATE upload_history
SET just_the_date = strftime('%Y%m%d',file_uploaded_date)
This will then allow you to do much quicker searches, and even search by year or month, using the LIKE operator. If your table is very large, you might want to put an index on that column as well.
You can add date in db as a string in date format like yyyy-mm-dd hh-mm-ss and compare the same while retrieving it from database using sql query.
I am accessing Android MMS database to get the date of MMS message:
Uri mmsUri = Uri.parse("content://mms/");
ContentResolver contentResolver = getContentResolver();
String[] projection = {"_id", "date"};
Cursor cursor = contentResolver.query(mmsUri, projection, null, null, null);
long dateVal = cursor.getLong(cursor.getColumnIndex("date"));
//This date is always 1970
Date mmsDate = new Date(dateVal);
But the date I get is always 1970. Then, I found an answer for this. I need to set the projection to null (to return all columns) and then use the following code to get date value:
//A mystery column of index 2
long timestamp = cursor.getLong(2) * 1000;
//It works !
Date mmsDate = new Date(timestamp);
Everything until here is fine. But, now instead of geting all rows from MMS database, I need to select those rows which were sent after a certain date, which means I need to use selection & selection argument. Something like:
String selection = NAME_OF_MYSTERY_COLUMN_IDX_2 > minDate
Cursor cursor = contentResolver.query(mmsUri, projection, selection, null, null);
But I have no idea what is the name of the column with index 2, how could I achieve what I need ? Is there a workaround?
Your first code block is correct, except for the Date instantiation. That constructor expects the time in milliseconds, but the MMS table keeps dates in seconds. To correct this, simply multiply the value returned from the query by 1000.
Date mmsDate = new Date(dateVal * 1000);
For future reference, the Cursor#getColumnName() method will give you the String name for a given column index.
You can try this.
String selection = "date_sent" > minDate
https://developer.android.com/reference/android/provider/Telephony.BaseMmsColumns.html#DATE_SENT
I would like to check with you ,
I would like to do a summary for my application.
Such that it will give me an average for my price based on month.
This mean that I've a set of records, which I've already filter by month.
If month = Jan, I would like to get all the Jan data and divide by the number of days in the month.
Right now,
I'm only able to take out the months.
I would like to check,
If I would want to do " would like to get all the Jan data and divide by the number of days in the month. ", how can I do it?
Can anyone suggest to me?
Im new to android, and trying to learn things.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.summary);
monthDate = (EditText)findViewById(R.id.month);
avgPrice = (TextView)findViewById(R.id.showavfPriceTV);
exFuel = (TextView)findViewById(R.id.showexFuelTV);
avgFC = (TextView)findViewById(R.id.showavgFCTV);
doneButton = (Button)findViewById(R.id.doneBTN);
exitButton = (Button)findViewById(R.id.exitBTN);
// First we need to make contact with the database we have created using
// the DbHelper class
AndroidOpenDbHelper openHelperClass = new AndroidOpenDbHelper(this);
// Then we need to get a readable database
SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase();
// We need a a guy to read the database query. Cursor interface will do
// it for us
// (String table, String[] columns, String selection, String[]
// selectionArgs, String groupBy, String having, String orderBy)
Cursor cursor = sqliteDatabase.query(
AndroidOpenDbHelper.TABLE_NAME_LOG, null, null, null, null,
null, null);
// Above given query, read all the columns and fields of the table
startManagingCursor(cursor);
// Cursor object read all the fields. So we make sure to check it will
// not miss any by looping through a while loop
while (cursor.moveToNext()) {
// In one loop, cursor read one undergraduate all details
// Assume, we also need to see all the details of each and every
// undergraduate
// What we have to do is in each loop, read all the values, pass
// them to the POJO class
// and create a ArrayList of undergraduates
String id = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_ROWID));
final String date = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_DATE));
String price = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_PRICE));
String pump = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_FUEL));
String cost = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_COST));
String odm = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_ODM));
String preodm = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_PREODM));
String fcon = cursor.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.KEY_CON));
// If you don't close the database, you will get an error
sqliteDatabase.close();
Log.i("FuelLog", "dataBundle " + date);
monthDate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// showDialog(DATE_DIALOG_ID);
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
}
});
doneButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (monthDate.getText().toString().equals(date.subSequence(3,9).toString()))
{
Log.d("MONTHDATE","date : "+ monthDate.getText().toString());
Log.d("BBUNDLEDATE","date : "+ (date.subSequence(3,9).toString()));
Intent intent=new Intent(getApplicationContext(),homeActivity.class);
startActivity(intent);
}
else
{
Intent intent=new Intent(getApplicationContext(),about.class);
startActivity(intent);
Log.d("ELSEMONTHDATE","date : "+ monthDate.getText().toString());
Log.d("ELSEBUNDLEDATE","date : "+ (date.subSequence(3,9).toString()));
}
}
});
}
}
Supposing you have the SUM of your monthly data for a single month,
Cursor cur = myDB.rawQuery
("SELECT SUM(Price) FROM Prices WHERE Month = 1", null);
if(cur.moveToFirst())
{
return cur.getInt(0);
}
Even better, you can have a single query to get the months and the summed prices per each month of the given year:
String sql = "SELECT Month, SUM(Price) FROM Prices WHERE Year = ? GROUP BY Month ORDER BY Month";
Divide your single monthly datum by:
Calendar cal = new GregorianCalendar(2014, Calendar.JANUARY, 1); // Specify an year and a month basing on your datum
int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
Just keep in mind this: (fromm the SQLite reference site)
sum(X) and
total(X)
The sum() and total() aggregate functions return sum of all non-NULL values in the group. If there are no non-NULL input rows then sum() returns NULL but total() returns 0.0. NULL is not normally a helpful result for the sum of no rows but the SQL standard requires it and most other SQL database engines implement sum() that way so SQLite does it in the same way in order to be compatible. The non-standard total() function is provided as a convenient way to work around this design problem in the SQL language.
The result of total() is always a floating point value. The result of sum() is an integer value if all non-NULL inputs are integers. If any input to sum() is neither an integer or a NULL then sum() returns a floating point value which might be an approximation to the true sum.
Sum() will throw an "integer overflow" exception if all inputs are integers or NULL and an integer overflow occurs at any point during the computation. Total() never throws an integer overflow.
ALSO NOTE
It's always a good idea to put dummy values (0.0) for months where no price is specified
Hy Guys, I am Beginner Android Developer. I need your help. i want to insert data into 2 tables of sqlite tblorder, and orderdtl. on orderdtl i have to insert data from multiple item from listview. i try to toast all variable that i want to inserted. their all appears. but when i try to save it. i get those error.
this is my DBDataSource.java
public order createorder(String orderid, String notes, long outletid) {
ContentValues values = new ContentValues();
values.put(DBHelper.ORDER_ID, orderid); // inserting a string
values.put(DBHelper.NOTES, notes); // inserting an int
values.put(DBHelper.OUTLET_ID, outletid); // inserting an int
long insertId = database.insert(DBHelper.TABLE_ORDER, null,
values);
Cursor cursor = database.query(DBHelper.TABLE_ORDER,
allorder, DBHelper.ORDER_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
order neworder = cursorToorder(cursor);
cursor.close();
return neworder;}
private order cursorToorder(Cursor cursor) {
order order = new order();
order.setorderid(cursor.getString(cursor.getColumnIndex(DBHelper.ORDER_ID)));
order.setorderdate(cursor.getString(cursor.getColumnIndex(DBHelper.ORDER_DATE)));
order.setnotes(cursor.getString(cursor.getColumnIndex(DBHelper.NOTES)));
order.setoutletid(cursor.getLong(cursor.getColumnIndex(DBHelper.OUTLET_ID)));
return order;
}
The error refer to this code
Cursor cursor = database.query(DBHelper.TABLE_ORDER,
allorder, DBHelper.ORDER_ID + " = " + insertId, null,
null, null, null);
And this code
order.setorderid(cursor.getString(cursor.getColumnIndex(DBHelper.ORDER_ID)));
orderid is string, i try to get from yyyyMMddHHmmss.this is the code:
private String orderid(){
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyyMMddHHmmss", Locale.getDefault());
Date date = new Date();
return dateFormat.format(date);
}
I would be very grateful for any help that you give.Thank You.
The query didn't match any rows. Check the result of moveToFirst() to see whether the operation succeeded and only then access cursor data.
Example:
order neworder = null;
if (cursor.moveToFirst()) {
order neworder = cursorToorder(cursor);
}
cursor.close();
return neworder;
The insertId you get from insert() is the sqlite row id for the row. It's likely not the same as ORDER_ID. To make a column an alias for rowid, declare it as INTEGER PRIMARY KEY.
The error I see in logcat is not about _Player_8, but about the unknown column "KEY_Team_Name"
The problem is in your activity, the line prior to the last one:
String EntryA =String.valueOf( db.getentry("Ravirrrr", "KEY_Team_Name"));
It should be:
String EntryA =String.valueOf( db.getentry("Ravirrrr", DatabaseHandler.KEY_Team_Name));
And the DatabaseHandler should have all column names public, as the getentry method requires a column name.
Edit: adding an answer to the question in the comments below.
After calling db.query, you should check if you got something by calling Cursor.isAfterLast(). If true, the select returned an empty result set.
In your example, you WILL get an empty result set as the code creates an entry with "Ravi" as the team name, then asks for a team named "Ravirrrr".