I am working on a Adaptive To-Do application, In this user will have a button to reschedule the pending tasks(Tasks with past date), when the user clicks reschedule, it'll change the pending tasks date to current free date(Dates which are not assigned to any task. What i cant understand is how to retrieve date from database and compare it with the available dates.But formater shows error, and if comparision also.
public void UpdateData() {
Calendar cal = Calendar.getInstance();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cursor = db.query(TaskContract.TaskEntry.TABLE_NAME,
new String[]{TaskContract.TaskEntry._ID,
TaskContract.TaskEntry.COLUMN_DATE,
},
null, null, null, null, null);
//Calendar reminderCalendar = Calendar.getInstance();
//reminderCalendar.set(year, month, day);
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String str1 = TaskContract.TaskEntry.COLUMN_DATE;
Date date1 = formatter.parse(str1);//Show Error UnHandled Exception java.text.parse exception.
if (date1.before(cal))// Shows error and says to flip to (cal.before(date1)) {
ContentValues cv = new ContentValues();
final Calendar c = Calendar.getInstance();
int yy = c.get(Calendar.YEAR);
int mm = c.get(Calendar.MONTH);
int dd = c.get(Calendar.DAY_OF_MONTH);
}
}
String str1 = TaskContract.TaskEntry.COLUMN_DATE;
Assuming your column is called MYDATE, your code is saying that str1 = "MYDATE";
Can you tell me what date MYDATE is? Nor can the formatter, hence the exception.
I believe what you want is:-
String str1 = "";
if (cursor.moveTofirst) {
str1 = cursor.getString(cursor.getColumnIndex(TaskContract.TaskEntry.COLUMN_DATE));
} else {
// handle no data being extracted for some reason
}
cursor.close(); // assuming you've done with the Cursor
Date date1 = formatter.parse(str1);
..........
To further explain when you say :-
`Cursor cursor = db.query(......`
You are saying get me a cursor from the table(1st parameter), with the columns (2nd parameter, null for all columns), 3rd parameter where clause and so on.
If it works you will get a Cursor named cursor which contain your data as a number of rows of columns (like a spreadhsheet).
To get to the data you need to do the equivalent of get the data from cell A1 (A being the first column of the first row).
However you move to a Row and then get the nth column using one the get???? methods. Above move's to the first row (we'd only expect the 1 row by the looks of your code (more later)).
At a row you can get data from columns by using the index/offset to that column. The first column being 0, the next 1 etc.
However, having to work this out and perhaps change it if you change the query can introduce difficulties, so it's probably much easier to find the index/offest by using the column name. Hence, getColumnIndex(column_name_as_a_string)
Back to moving, to explain why the moveToFirst is in an if.
A cursor can contain 0 or more rows, a cursor, if the query works will not be null, rather an empty cursor is returned (this is a relatively frequent occurrence, and also sometimes a very useful situation).
So rather than issuing an exception because a Cursor can't move to a position, it returns false (true if it can and does move).
So if(cursor.moveToFirst) {....} is saying only do if there is data in the cursor.
There are other move methods, moveToLast(), moveToNext(), moveToPrevious() and moveToPosition(int).
Perhaps the most common is moveToNext e.g.
while(cursor.moveToNext()) {
// use the respective column data here
}
traversing all rows of the cursor
Related
hello guys for the last three days I have been working on a simple query , but it is just not working , I'm trying to prevent register departure without having registered arrival , here is the code in my DB helper,not sure what is wrong with that query!!
public Boolean HasShowedUpToday(int check_id)
{
Boolean attend;
SQLiteDatabase db=this.getWritableDatabase();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault());
time=Calendar.getInstance().getTime();
String dateoftoday= dateFormat.format(time);
Cursor c = db.rawQuery("SELECT * FROM attendance where user_id = '"+check_id+"' and arrival_time ='"+dateoftoday+"' and departure_time ='';", null);
if (c.moveToFirst())
{
attend=true;
}
else
{
attend=false;
}
return attend;
}
First of all do not construct queries like that. This is very wrong habit which will made you in future to write code which is vulnerable to SQL injections.
Use rawQuery (String sql, String[] selectionArgs).
So it should look like this:
Cursor c = db.rawQuery("SELECT * FROM attendance where user_id = ? and arrival_time = ? and departure_time IS NULL",
new String[] { check_id, dateoftoday} );
Also take a look on this SO answer. And this answer looks even better - store dates as number of milliseconds since EPOCH time.
I get a date from the server in "MM/dd/yyy" form, then I convert it into milliseconds using the following function:
public static long getSimpleDateToMillis(String simpleDate) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
Date date = formatter.parse(simpleDate);
return date.getTime();
}
Then afterwards I save the result into the database as int.
Right now I'm stucked in what seems like a dead-end for me. I can't find a way through searching and from my stock knowledge on how I would be able to filter my cursorloader by project_date column which is saved as integer in the database.
In what way would I be able to query such that it would:
Select all row from projects table where the project_date is today and backwards (yesterday and so on).
I tried this one but seems to be really not the answer.
String [] projection = new String []{};
String selection = "datetime("+ ProjectsEntry.COLUMN_PROJECT_DATE + "/1000, 'unixepoch') =? ";
String [] selectionArgs = new String[]{" date('now')"};
return new CursorLoader(this,
JobsContract.JobsEntry.CONTENT_URI,
projection,
selection,
selectionArgs,
null);
I haven't found any other reference that would point me, so I'm hoping someone might also have encountered this perhaps.
This is how I do something quite similar, but using full timesteamp i.e. long rather than int.
First I have this method to get the TimeStamp, to get today's date/time as of midnight (bar 1 millisecond):-
/**
*
* #return 1 millsecond before midnight today
*/
private long getDateTimeOfAllofToday() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH,1); // tomorrow
cal.set(Calendar.MILLISECOND,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.HOUR_OF_DAY,0);
cal.add(Calendar.MILLISECOND,-1);
return cal.getTimeInMillis();
}
Then I create the respective where clause e.g. :-
filter = DBRulesTableConstants.RULES_ACTON_COL +
" <= " +
Long.toString(getDateTimeOfAllofToday());
This is used via a rawQuery so not exactly what you want but easy enough to to change " <= " to " <=?" and then use
String [] selectionArgs = new String[]{Long.toString(getDateTimeOfAllofToday())}; or a modified version to get integer.
I am new to android. I am getting a problem while restoring the call log, which I stored in a database.
I am storing the call log with the following code:
Cursor managedCursor = cr.query(CallLog.Calls.CONTENT_URI, null,
CallLog.Calls.NUMBER + "=?",
new String[] {(ActiveUserContacts.get(i).getnumber()) },
null);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
int name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME);
int NEW = managedCursor.getColumnIndex(CallLog.Calls.NEW);
while (managedCursor.moveToNext()) {
CallLogsModel Log = new CallLogsModel(Integer.toString(i),
managedCursor.getString(type),
managedCursor.getString(date),
managedCursor.getString(duration),
managedCursor.getString(number),
managedCursor.getString(name),
managedCursor.getString(NEW));
StoreData.addCallLog(UserNAME, Log);
}
managedCursor.close();
And I restore it with the code:
ContentValues values = new ContentValues();
values.put(CallLog.Calls.TYPE, PrevContents.get(i).getType());
values.put(CallLog.Calls.DATE, PrevContents.get(i).getDate());
values.put(CallLog.Calls.DURATION, PrevContents.get(i).getDuration());
values.put(CallLog.Calls.NUMBER, PrevContents.get(i).getNumber());
values.put(CallLog.Calls.CACHED_NAME, PrevContents.get(i).getName());
values.put(CallLog.Calls.NEW, PrevContents.get(i).getNew());
getActivity().getContentResolver().insert(CallLog.Calls.CONTENT_URI, values);
However, everything but the time of call got restored. Did I make a mistake?
Your PrevContents.get(i).getDate() may not be the right type or in the right format for the call log. Some of the examples I see of records inserted into the call log (e.g., android adding number to Call logs) use System.currentTimeMillis() as the date, which is actually of type long. You probably want to use managedCursor.getLong(date) in the code you use to retrieve the date, and store it as a long.
Another note: it looks as if you're getting 1 record when you query the call log, put that in your cursor, save that 1 record, then do the same thing for the next record, and get all the records by looping through all of the call log records manually (I assume that's what that index 'i' is for). You don't need to do that--the query can get all records for you, then you can use managedCursor.moveToNext() to do the looping. Take a look at http://android2011dev.blogspot.com/2011/08/get-android-phone-call-historylog.html for an example of how to do this. When you do the restoration you may need a loop (though there may be an easier way to do that, too).
I have a "small" problem. I have a SQLiteDatabase ("PLB") with a table called "Flights". In this table i have a column called "Total_Flight_Time"type TIME which memorize time in HH:MM format. I wanna make a SUM of the hours and minutes. Something like 01:20 + 01:50 = 03:10 (HH:MM) but i don't know how to do it.
I found a code here, on stackoverflow:
Function from DBAdapter:
public Cursor getTotalTime() throws SQLException {
return db.rawQuery("SELECT sum(strftime('H%:%M', Total_Flight_Time) - strftime('H%:%M', '00:00')), 'unixepoch' FROM Flights",null);
}
Function call in main activity (it should show the SUM result in a Text View):
DBHelper.open();
TextView txt = (TextView)findViewById(R.id.textView22);
String total = DBHelper.getTotalTime().toString();
txt.setText(total);
But on the Screen it shows: android.database.sqlite.SQLiteCursor#41aa42b8
How do i have to do the function and the function call to fix the problem, i wan it to show HH:MM? :)
SOLVED!
SOLUTION:
DBAdapter function:
public Cursor getTotalTime() throws SQLException {
return db.rawQuery("SELECT time(sum(strftime('%s', Total_Flight_Time) - strftime('%s','00:00:00')),'unixepoch') FROM Flights",null);
}
Function Call in Main Activity:
TextView txt = (TextView)findViewById(R.id.textView22);
Cursor c = DBHelper.getTotalTime();
c.moveToFirst();
String[] names = c.getColumnNames(); // inspect this as it should have a length of 1
String total = c.getString(c.getColumnIndex(names[0]));
txt.setText(total);
This is the source of your problems:
In this table i have a column called "Total_Flight_Time" type TIME which memorize time in HH:MM format.
You're misusing TIME data type because your Total_Flight_Time is actually storing a duration, not a point in time. Change the type for Total_Flight_Time to integer, representing the number of seconds or the number of minutes in the duration. Then summing up your durations become a trivial matter of integer sums. A little arithmetic will allow you to transform number of seconds/minute to days, hours, minutes, and seconds.
db.rawQuery(...) returns type Cursor so you are calling cursor.toString() which results in what you see. You need to use a function of the Cursor class to extract the results of your query and then display the results. eg:
you may have to move the cursor to the first row in which case it will look like this:
Cursor c = DBHelper.getTotalTime();
c.moveToFirst();
String total = c.getString(0);
if you dont know the column index (and its not 0) try:
Cursor c = DBHelper.getTotalTime();
c.moveToFirst();
String[] names = c.getColumnNames() // inspect this as it should have a length of 1
String total = c.getString(c.getColumnIndex(names[0]));
If names.length != 1 let me know the results.
I think this (or some variation of this) should help. See the documentaion of the Cursor class for more details: http://developer.android.com/reference/android/database/Cursor.html
comment response:
c.moveToFirst();
while (c.isAfterLast() == false) {
Log.w("query Test", "result: " + cur.getString(0);
c.moveToNext();
}
SimpleDateFormat formatter = new SimpleDateFormat("HH:MM");
Date curDate = formatter.parse(DBHelper.getTotalTime().toString());
long curMillis = curDate.getTime();
Then, you can add this to some other date (again converting that to long) and display the sum in the date format.
I get data from my DB using
cursor = db.query("WebLeadMaster", select, "condition1="+conditionVal1+
" and condition2="+ConditionVal2,null, null, null, "RegistrationTime DESC");
I am getting the data in my cursor alright. To display the data, i use the following code:
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.resultleadlookup, cursor, columns, to);
mAdapter.notifyDataSetChanged();
lstResult.setAdapter(mAdapter);
So, I cannot modify the contents of the cursor. The sort query has condition "RegistrationTime" which is a String data type. As you can see in the image below, it is not in a proper sorted format. (not according to date-time).
What changes should i make in my code so that it would sort properly according to date-time?
If i alter my DB query, to look like
cursor = db.query("WebLeadMaster", select, "condition1="+conditionVal1+
" and condition2="+ConditionVal2,null, null, null, null);
it gives an ascending order. All i want it the descending order.
The easiest suggestion would be to save the date in a different format (but still saved as string) into the database. If you would save the data into SQLite’s default date format (YYYY-MM-DD HH:NN:SS), you can easily sort the dates.
To display the date in your format, you would only just need to reformat the date into the correct format.
Well, i changed my table structure. I added another field "_id" to it. Set the property as AUTO INCREMENT to it, and sorted the list with respect to _id field.
If you r using ORM you can sort the data by timestamp.
ORM makes data insertion and data retrieval easier from database.
You have to include jar files to your project to use ORM...
since SQLite has no datetime type, store date type as LONG/INT/NUMERIC in SQLite (EPOCH time) it will be easier to sort
then add ViewBinder to Adapter
/*field in activity/fragment*/
final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //or other format that you wana to show in ListView
...
mAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor,
int columnIndex) {
final int id = view.getId();
switch (id) {
case R.id.id_of_textview_with_date_data:
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(cursor.getLong(columnIndex));
((TextView) view).setText(sdf.format(cal.getTime()));
return true;
}
return false;
}
});
... or as dennisg pointed store it as STRING/VARCHAR edit: in "yyyy-MM-dd HH:mm:ss" format