public GenericRawResults<Object[]> getCountByStatus(Date date,int status){
Log.info("CallDayPlanningDao",date.toString());
GenericRawResults<Object[]> rawResults=null;
Dao callDayPlanningDao = getDao(CallDayPlanning.class);
QueryBuilder query = callDayPlanningDao.queryBuilder();
int year = date.getYear();
int month = date.getMonth();
Date date1 = new Date(year, month,1);
Date date2 = new Date(year, month+1,1);
Date startDate = new Date(date1.getTime()-5);
Date endDate = new Date(date2.getTime()-5);
try {
**query.where().between("calldate", startDate, endDate);**//This line is not working
if(status==Constant.cnStatus){
query.where().in("callstatus", status,Constant.ccStatus);
}else{
query.where().eq("callstatus", status);
}
query.groupBy("calldate");
query.selectRaw("calldate,count(*)");
rawResults = callDayPlanningDao.queryRaw(query.prepareStatementString(), new DataType[] {
DataType.DATE_STRING, DataType.INTEGER });
// page through the results
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return rawResults;
}
Well, I want to get the count of the object, but the condition of date is invalid, I get all the data from my database.Somebody could help me?Thanks.
I am new to ORMLite and faced the same problem when accessed SQLite database.
It took me a whole day today to figure it out, here is the summary:
I found format "yyyy-M-d H:m:s" works fine in ORMLite for dealing with SQLite DateTime data type, not ORMLite's default format "yyyy-MM-dd HH:mm:ss.SSSSS".
For ORMLite to translate between "Java Date" and "SQLite DateTime", a persister class will be needed.
Here shows the code of the persister class I use, which override the public functions of DateStringType and use "dateFormatConfig" instead of defaultDateFormatConfig" :
`
public class DateStringSQLiteType extends DateStringType {
protected static final DateStringFormatConfig dateFormatConfig = new DateStringFormatConfig(
"yyyy-M-d H:m:s");
private static final DateStringSQLiteType singleTon = new DateStringSQLiteType();
public static DateStringSQLiteType getSingleton() {
return singleTon;
}
private DateStringSQLiteType() {
super(SqlType.STRING, new Class<?>[0]);
}
/**
* Convert a default string object and return the appropriate argument to a
* SQL insert or update statement.
*/
#Override
public Object parseDefaultString(FieldType fieldType, String defaultStr)
throws SQLException {
DateStringFormatConfig formatConfig = convertDateStringConfig(
fieldType, dateFormatConfig);
try {
// we parse to make sure it works and then format it again
return normalizeDateString(formatConfig, defaultStr);
} catch (ParseException e) {
throw SqlExceptionUtil.create("Problems with field " + fieldType
+ " parsing default date-string '" + defaultStr
+ "' using '" + formatConfig + "'", e);
}
}
/**
* Return the SQL argument object extracted from the results associated with
* column in position columnPos. For example, if the type is a date-long
* then this will return a long value or null.
*
* #throws SQLException
* If there is a problem accessing the results data.
* #param fieldType
* Associated FieldType which may be null.
*/
#Override
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results,
int columnPos) throws SQLException {
return results.getString(columnPos);
}
/**
* Return the object converted from the SQL arg to java. This takes the
* database representation and converts it into a Java object. For example,
* if the type is a date-long then this will take a long which is stored in
* the database and return a Date.
*
* #param fieldType
* Associated FieldType which may be null.
* #param sqlArg
* SQL argument converted with
* {#link #resultToSqlArg(FieldType, DatabaseResults, int)} which
* will not be null.
*/
#Override
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos)
throws SQLException {
String value = (String) sqlArg;
DateStringFormatConfig formatConfig = convertDateStringConfig(
fieldType, dateFormatConfig);
try {
return parseDateString(formatConfig, value);
} catch (ParseException e) {
throw SqlExceptionUtil.create("Problems with column " + columnPos
+ " parsing date-string '" + value + "' using '"
+ formatConfig + "'", e);
}
}
/**
* Convert a Java object and return the appropriate argument to a SQL insert
* or update statement.
*/
#Override
public Object javaToSqlArg(FieldType fieldType, Object obj) {
DateFormat dateFormat = convertDateStringConfig(fieldType,
dateFormatConfig).getDateFormat();
return dateFormat.format((Date) obj);
}
/**
* #throws SQLException
* If there are problems creating the config object. Needed for
* subclasses.
*/
#Override
public Object makeConfigObject(FieldType fieldType) {
String format = fieldType.getFormat();
if (format == null) {
return dateFormatConfig;
} else {
return new DateStringFormatConfig(format);
}
}
}
`
Define you data class with notation:
#DatabaseField(..., persisterClass = DateStringSQLiteType.class)
private Date date;
It worked fine for me, can do "Between" query like:
list = foo.getDao().queryBuilder().where().between(HistoryStandardView.DATE_FIELD_NAME, new Date(98,1,1), new Date(115,1,1)).query();
ORMLite's logger shows the resulting statement:
[DEBUG] StatementExecutor query of 'SELECT * FROM `HistoryStandardView` WHERE `date` BETWEEN '1998-2-1 0:0:0' AND '2015-2-1 0:0:0' ' returned 2 results
Correct me if am wrong is your calldate column's type is DataType.DATE_STRING ? If that's the case it means that the persisted data type is VARCHAR so when you execute your query your doing a String comparison and not a Date comparison. So to solve your problem you can either :
Change your calldate column's type to DataType.DATE which is represented as a TIMESTAMP.
Change your calldate column's type to DataType.DATE_LONG.
Find a way to do a String comparison that matches what your need (for instance calling the sql date(calldate) fonction if your calldate values matches a Time Strings format see http://www.sqlite.org/lang_datefunc.html).
Here is what i did, it's not pretty but works like wanted to:
QueryBuilder<OffreEntity, Integer> qb = this.daoOffre.queryBuilder();
//Need to format the date i want to compare so it can actually be compare with what i have on db
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyMMdd");
String correctFormat = dateFormatter.format(dateLimite);
//In db the date is represented as a VARCHAR with format dd/MM/yy so i need to reformat so it matches yyMMdd
String rawQuery = String.format("substr(%1$s,7)||substr(%1$s,4,2)||substr(%1$s,1,2) > '%2$s'", OffreEntity.COLUMN_NAME_DATE, correctFormat);
qb.where().raw(rawQuery);
offresDept = qb.query();
Hope it helps!
Ps: Thanks to Jack Douglas for the date format query
Related
I store my dates in my database as strings. This worked fine when using MySQL, however using room in android I cannot search by date to and date from in my queries correctly as room doesn't recognise the string dates. I'm wondering is it possible to use the type converter to simply convert the string into the long. Rather than having to redo my whole database to store Date instead of string then convert from Date to long.
Any assistance with this would be greatly appreciated.
/**
* Method used to gain the current date.
*
* #return
*/
private Date currentDate() {
calendar.add(Calendar.DATE, 0);
return calendar.getTime();
}
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
String dateTimeOfWorkout = dateFormat.format(currentDate());
I got this:
#TypeConverter
public static Date fromTimestamp(String value) {
if (value != null) {
try {
return df.parse(value);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
} else {
return null;
}
QUERY
// Get Monthly Logs
#Query("SELECT checkInTable.checkInId, checkInTable.moodBeforeId, " +
"checkInTable.checkInEntry, checkInTable.checkInEntry2, " +
"checkInTable.userId, moodBeforeTable.workoutDate,
moodBeforeTable.moodBefore, " +
"moodBeforeTable.moodBeforePK " +
"FROM checkInTable " +
"JOIN moodBeforeTable " +
"ON checkInTable.moodBeforePK = moodBeforeTable.moodBeforePK " +
"WHERE moodBeforetable.workoutDate >= datetime('now', '-1 month') " +
"ORDER BY moodBeforeTable.workoutDate DESC")
LiveData<List<CheckInLogsPojo>> getCheckInLogsMonthly();
MODEL
#NonNull
#ColumnInfo(name = "workoutDate")
#TypeConverters({TimeTypeConverter.class})
private String workoutDate;
UPDATE: With the above typer converter and query it is still not sorting results for a 1 month period. Its just showing everything.
Without redo the whole database. It can be done using Database migration.
Using type convertor date can be stored in database.
Add a class for converting date to long
public class DateConverter {
#TypeConverter
public static Date toDate(Long timestamp){
return timestamp == null ? null : new Date(timestamp);
}
#TypeConverter
public static Long toTimestamp(Date date){
return date == null ? null : date.getTime();
}
}
Now we tell to the Room to use the DateConvertor we added using TypeConverts anotation
#Database(entities = {MyEntity.class},version = 1,exportSchema = false)
#TypeConverters(DateConverter.class)
public abstract class MyDatabase extends RoomDatabase {
//room database
}
Now we can use Date as a data type in entity class
I'd like to parse the json data coming from this api (taken from their example page):
https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=MSFT&outputsize=full&apikey=demo
I did build a parse method which takes ages (several seconds on my Galaxy A5) to parse the data (i know it is a lot of data to parse):
This is what i did:
private static List<PriceInfo> parsePriceDaily(JSONObject response, boolean onlyCurrentPrice) throws JSONException {
long millis = System.currentTimeMillis();
/* Check if this message is an Error Message = No data for symbol available.
* If not fetch data
* example structure
* https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=MSFT&outputsize=full&apikey=demo
*/
/* Get the First Object - Either Meta Data or Error Message */
Iterator<String> it = response.keys();
String key = it.next();
/* Is Error? */
if (key.contains("Error Message")) {
throw new JSONException(response.getString(key));
}
/* Valid Object - process metadata */
String timeZone = response.getJSONObject(key).getString("5. Time Zone");
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
format.setTimeZone(TimeZone.getTimeZone(timeZone));
/* Process datasets */
List<PriceInfo> result = new ArrayList<>();
key = it.next();
JSONObject datasets = response.getJSONObject(key); /* Time Series (Daily) */
JSONObject dataset;
String dateString;
for (it = datasets.keys(); it.hasNext(); ) {
dateString = it.next(); /* dataset */
dataset = datasets.getJSONObject(dateString);
Date date = new Date(0); /* standard value */
try {
date = format.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
result.add(
new PriceInfo(
date,
dataset.getString("1. open"),
dataset.getString("2. high"),
dataset.getString("3. low"),
dataset.getString("4. close"),
dataset.getString("5. adjusted close"),
dataset.getString("6. volume"),
dataset.getString("7. dividend amount"),
dataset.getString("8. split coefficient")
)
);
if (onlyCurrentPrice) {
break;
}
}
Log.d(TAG, "Passed time: " + (System.currentTimeMillis() - millis));
return result;
}
What are the best improvements? Switching to another JSON library?
Use Gson for parsing and JsonSchemaToPojo for creating POJO classes .
Did you try gson library from Google?
How can I encrypt my data?
As far as the solutions I study there are two ways:
Encrypt data using an algorithm provided by android. I use "Cipher" is provided by android to encrypt my data. But I'm having problems retrieving data with large number of records, making the app's performance significantly reduced.
I coded the whole database and then every session I decoded and saved in the cache but no algorithm was found to solve this.
I use the following for encrypting/decrypting at a column level, i.e. it is only applied to the sensitive data.
class EncryptDecrypt {
private Cipher cipher;
private static SecretKeySpec secretKeySpec;
private static IvParameterSpec ivParameterSpec;
private boolean do_encrypt = true;
/**
* Construct EncryptDecrypt instance that checks the current logged-in
* user status; basically if the user is the special NOUSER, where
* the user does not use a password, then encryption decryption is
* skipped, the alternative constructor does not undergo this check and
* thus will always encrypt (see alternative)
* #param context The context, required for database usage (user)
* #param skey The secret key to be used to encrypt/decrypt
* #param userid The userid (so that the salt can be obtained)
*/
EncryptDecrypt(Context context, String skey, long userid) {
DBUsersMethods users = new DBUsersMethods(context);
if (MainActivity.mLoginMode == LoginActivity.LOGINMODE_NONE) {
do_encrypt = false;
return;
}
String saltasString = users.getUserSalt(userid);
String paddedskey = (skey + saltasString).substring(0,16);
secretKeySpec = new SecretKeySpec(paddedskey.getBytes(),"AES/CBC/PKCS5Padding");
ivParameterSpec = new IvParameterSpec((saltasString.substring(0,16)).getBytes());
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (Exception e){
}
}
/**
* Construct EncryptDecrypt instance that does not check user login-in
* mode, thus the assumption is that this user is NOT the special user
* NOUSER that doesn't require a password to login; this constructor
* is designed to ONLY be used when a user has been added by NOUSER,
* and to then encrypt the data using the enccryptForced method solely
* to encrypt any existing card data for the new user that has a password.
*
* #param context The context, required for database usage (user)
* #param skey The secret key to be used to encrypt/decrypt
* #param userid The userid (so that the salt can be obtained)
* #Param mode Not used other than to distinguish constructor
*/
EncryptDecrypt(Context context, String skey, long userid, boolean mode) {
DBUsersMethods users = new DBUsersMethods(context);
String saltasString = users.getUserSalt(userid);
String paddedskey = (skey + saltasString).substring(0,16);
secretKeySpec = new SecretKeySpec(paddedskey.getBytes(),"AES/CBC/PKCS5Padding");
ivParameterSpec = new IvParameterSpec((saltasString.substring(0,16)).getBytes());
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (Exception e){
//e.printStackTrace();
}
}
/**
* Normal encryption routine that will not encrypt data if the user is
* the special case NOUSER (i.e LOGIN mode is NOUSER), otherwise data
* is encrypted.
*
* #Param toEncrypt The string to be encrypted
* #return The encryted (or not if NOUSER) data as a string
*/
String encrypt(String toEncrypt) {
if (!do_encrypt) {
return toEncrypt;
}
byte[] encrypted;
try {
cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,ivParameterSpec);
encrypted = cipher.doFinal(toEncrypt.getBytes());
} catch (Exception e) {
//e.printStackTrace();
return null;
}
return Base64.encodeToString(encrypted,Base64.DEFAULT);
}
/**
* Encryption, irrespective of the USER type, noting that this should
* only be used in conjunction with an EncryptDecrypt instance created
* using the 2nd/extended constructor
*
* #param toEncrypt The string to be encrypted
* #return The encrypted data as a string
*/
String encryptForced(String toEncrypt) {
byte[] encrypted;
try {
cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,ivParameterSpec);
encrypted = cipher.doFinal(toEncrypt.getBytes());
} catch (Exception e) {
//e.printStackTrace();
return null;
}
return Base64.encodeToString(encrypted,Base64.DEFAULT);
}
/**
* Decrypt an encrypted string
* #param toDecrypt The encrypted string to be decrypted
* #return The decrypted string
*/
String decrypt(String toDecrypt) {
if (!do_encrypt) {
return toDecrypt;
}
byte[] decrypted;
try {
cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,ivParameterSpec);
decrypted = cipher.doFinal(Base64.decode(toDecrypt,Base64.DEFAULT));
} catch (Exception e) {
//e.printStackTrace();
return null;
}
return new String(decrypted);
}
}
Example usage (encryption) :-
........
db.beginTransaction();
........
newed = new EncryptDecrypt(mContext,newPassword,newUserId,true);
// Process the MatrixCursor created above
while (mxc.moveToNext()) {
// Generate the whereclause to determine which row is to be updated
whereclause = DBCardsTableConstants.CARDID.getDBColumnName() + "=?";
// Set the value to replace the ? plcaeholder with the current CARDID
whereargs = new String[]{
Long.toString(
mxc.getLong(
mxc.getColumnIndex(
DBCardsTableConstants.CARDID.getDBColumnName()
)
)
)
};
String mxc_nameoncard = mxc.getString(mxc.getColumnIndex(DBCardsTableConstants.CARDNAMEONCARD.getDBColumnName()));
String mxc_number = mxc.getString(mxc.getColumnIndex(DBCardsTableConstants.CARDNUMBER.getDBColumnName()));
String mxc_cvv = mxc.getString(mxc.getColumnIndex(DBCardsTableConstants.CARDCVVCODE.getDBColumnName()));
String mxc_pin = mxc.getString(mxc.getColumnIndex(DBCardsTableConstants.CARDPIN.getDBColumnName()));
String mxc_exp = mxc.getString(mxc.getColumnIndex(DBCardsTableConstants.CARDEXPIRYDATE.getDBColumnName()));
String enc_nameoncard = newed.encryptForced(mxc_nameoncard);
String enc_number = newed.encryptForced(mxc_number);
String enc_cvv = newed.encryptForced(mxc_cvv);
String enc_pin = newed.encryptForced(mxc_pin);
String enc_exp = newed.encryptForced(mxc_exp);
// Prepare the data to be updated.
ContentValues cv = new ContentValues();
cv.put(DBCardsTableConstants.CARDOWNER.getDBColumnName(),
newUserId
);
cv.put(DBCardsTableConstants.CARDNAMEONCARD.getDBColumnName(),enc_nameoncard);
cv.put(DBCardsTableConstants.CARDNUMBER.getDBColumnName(),enc_number);
cv.put(DBCardsTableConstants.CARDCVVCODE.getDBColumnName(),enc_cvv);
cv.put(DBCardsTableConstants.CARDPIN.getDBColumnName(),enc_pin);
cv.put(DBCardsTableConstants.CARDEXPIRYDATE.getDBColumnName(),enc_exp);
// Perform the update
db.update(DBCardsTableConstants.CARDS.getDBTableName(),
cv,
whereclause,
whereargs
);
}
// Done with the MatrixCursor so close it
mxc.close();
// Done updating so apply all the changes
db.setTransactionSuccessful();
// Done with the transaction
db.endTransaction();
Example Usage (decryption)
Cursor getDecyrptedCard(long cardid) {
EncryptDecrypt ed = new EncryptDecrypt(mContext,
LoginActivity.getCurrentUserPassWord(),
MainActivity.mCurrentUserid);
MatrixCursor cnvcsr = new MatrixCursor(mCardsTableColumns,10);
String whereclause = DBCardsTableConstants.CARDID.getDBColumnName() +
"=? AND " +
DBCardsTableConstants.CARDOWNER.getDBColumnName() +
"=?";
String[] whereargs = {Long.toString(cardid), Long.toString(MainActivity.mCurrentUserid)};
Cursor basecsr = db.query(DBCardsTableConstants.CARDS.getDBTableName(),
null,
whereclause,
whereargs,
null,null,null,null);
// Check to see of card exists (always should)
if (!basecsr.moveToFirst()) {
cnvcsr.addRow(new Object[]{0L,0L,"NOTACARD","NOTACARD","","","","",""});
return cnvcsr;
}
// If Card is for NOUSER then no decryption requires so return
// base cursor after repositioning to before first.
if (MainActivity.getLoginMode() == LoginActivity.LOGINMODE_NONE) {
basecsr.moveToPosition(-1);
return basecsr;
}
// Get data to decrypt
String extracted_cardnameoncard = basecsr.getString(basecsr.getColumnIndex(
DBCardsTableConstants.CARDNAMEONCARD.getDBColumnName()
));
String extracted_cardnumber = basecsr.getString(basecsr.getColumnIndex(
DBCardsTableConstants.CARDNUMBER.getDBColumnName()
));
String extracted_cardcvv = basecsr.getString(basecsr.getColumnIndex(
DBCardsTableConstants.CARDCVVCODE.getDBColumnName()
));
String extracted_cardpin = basecsr.getString(basecsr.getColumnIndex(
DBCardsTableConstants.CARDPIN.getDBColumnName()
));
String extracted_cardexpiry = basecsr.getString(basecsr.getColumnIndex(
DBCardsTableConstants.CARDEXPIRYDATE.getDBColumnName()
));
// Decrypt data
String decrypted_nameoncard = ed.decrypt(extracted_cardnameoncard);
String decrypted_cardnumber = ed.decrypt(extracted_cardnumber);
String deccrypted_cardcvv = ed.decrypt(extracted_cardcvv);
String decrypted_expiry = ed.decrypt(extracted_cardexpiry);
String decrypted_cardpin = ed.decrypt(extracted_cardpin);
// Store decrypted data
cnvcsr.addRow(new Object[]{
basecsr.getLong(
basecsr.getColumnIndex(
DBCardsTableConstants.CARDID.getDBColumnName()
)),
basecsr.getLong(
basecsr.getColumnIndex(
DBCardsTableConstants.CARDTYPEREF.getDBColumnName()
)
),
basecsr.getLong(
basecsr.getColumnIndex(
DBCardsTableConstants.CARDOWNER.getDBColumnName()
)
),
basecsr.getString(
basecsr.getColumnIndex(
DBCardsTableConstants.CARDNAME.getDBColumnName()
)
),
decrypted_nameoncard,
decrypted_cardnumber,
deccrypted_cardcvv,
decrypted_cardpin,
decrypted_expiry,
basecsr.getString(
basecsr.getColumnIndex(
DBCardsTableConstants.CARDNOTES.getDBColumnName()
)
),
basecsr.getInt(
basecsr.getColumnIndex(
DBCardsTableConstants.CARDCOLOUR.getDBColumnName()
)
)
});
basecsr.close();
return cnvcsr;
}
Note! NOUSER is when a single user of the App decides to not use a password/login.
I have an android application that display data from my external Database so from several tables. Everything work fine while internet connection is available (all data come from URL link and they are been parsed with volley). But how can I save and load lastest data when internet is not available.
What is the best way to do that. Im new in android....
Please help.
Normally Volley and also HttpStack it uses allows you to seamlessly cache responses. This however depends on your responses and requests. Those cache strategies obeys http cache definition. If You want to have different behavior for Volley you can just override this part. basically when you create a request you can override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
and instead of
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
you do
long now = System.currentTimeMillis();
Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
entry.ttl = now + 30l * 24 * 60 * 60 * 1000; //kepps cache for 30 days
//entry.softTtl = now + 30l * 24 * 60 * 60 * 1000; //will not refresh for 30 days
return Response.success(parsed, entry);
Which basically will refresh the cache every time the server specifies so but will always return the cache for 30 days unless changes .
Note that here you may receive 2 callbacks in response or in one response and 1 error(in case of no network). the first one will be the cache.
UPDATE:
if you add (which is commented in the example above):
entry.softTtl = now + 30l * 24 * 60 * 60 * 1000; //will not refresh for 30 days
this will affect the refresh of the cache. in this case it wont event try to refresh the cache for 30 days. In that case you will return 1 response.
Note that I never would recommend solution like this because cache needs to be updated, especially if you want to fake cache on POST requests as in your case.
Receiving 2 callbacks is not really an issue as you can handle this seamlesly for the user and update UI when needed. also if you want to have more control you can know which one is from the cache and which one form the network by implementing your
ResponseDelivery
or extend
ExecutorDelivery
and then check for the param
mResponse.intermediate
and decide what to do then. ResponseDelivery is the one which calls the callbacks.
Update
similar question and examples here
if you have to store only small chunk of data then use SharedPreferences
If you have large data then use SQLite
Use below code to create and update SQLite DB
public class SqlMangaeMenu
{
SQLiteDatabase db1 = null;
private static String DBNAME = "YourLocal.db";
Context gcntxt;
public SqlMangaeMenu(Context cntxt)
{
// TODO Auto-generated constructor stub
gcntxt=cntxt;
db1 = cntxt.openOrCreateDatabase(DBNAME, Context.MODE_PRIVATE,null);
db1.execSQL("CREATE TABLE IF NOT EXISTS mytbl(appid varchar PRIMARY KEY,appname varchar,iconcode varchar,msgidentfier varchar,scode varchar,image blob,imagehdr blobhdr); ");
}//EOF Constructor
public void insertContent(String appid,String appname,String iconcode,String msgidentifier,String scode,Bitmap bmp,Bitmap bmphdr)
{
ContentValues contentValues = new ContentValues();
contentValues.put("appid", appid);
contentValues.put("appname", appname);
contentValues.put("iconcode", iconcode);
contentValues.put("msgidentfier", msgidentifier);
contentValues.put("scode", scode);
byte[] blob = null,blobhdr=null;
if(bmp!=null)
{
ByteArrayOutputStream outStr = new ByteArrayOutputStream();
bmp.compress(CompressFormat.PNG, 100, outStr);
blob = outStr.toByteArray();
}
contentValues.put("image", blob);
if(bmphdr!=null)
{
ByteArrayOutputStream outStr1 = new ByteArrayOutputStream();
bmphdr.compress(CompressFormat.PNG, 100, outStr1);
blobhdr = outStr1.toByteArray();
}
contentValues.put("imagehdr", blobhdr);
Log.d("db", "SQL Writing"+appid+appname+iconcode+msgidentifier+scode);
try {
// db1.insert("mytbl",null,contentValues);
db1.insertWithOnConflict("mytbl", null, contentValues,SQLiteDatabase.CONFLICT_IGNORE);
} catch (Exception e)
{
// TODO: handle exception
}
db1.close();
}//EOF insertContent
// Deleting single contact
public void Delete_appid(String id)
{
db1.delete("mytbl", "appid" + "=" + id, null);
db1.close();
}//EOF Delete_appid
public void readAppId()
{
MyApplication.dbappid=new ArrayList<String>();
String appid;
try
{
Cursor c = db1.rawQuery("SELECT * FROM mytbl", null);
//Cursor c = db1.rawQuery("SELECT MAX(ID) FROM mytbl", null);
if(c!= null)
{
if (c.moveToFirst())
{
do {
appid=c.getString(c.getColumnIndex("appid"));
MyApplication.dbappid.add(appid);
}while(c.moveToNext());
}
}
Log.d("db", "SQL Reading");
db1.close();
}
catch(Exception e)
{
System.out.println(e);
}
}//EOF readAppId
public void readDataandImage()
{
Bitmap image=null,imagehdr = null;
//Bitmap images
MyApplication.dbimg=new ArrayList<Bitmap>();
MyApplication.dbhdrimage=new ArrayList<Bitmap>();
//String
MyApplication.dbappname=new ArrayList<String>();
MyApplication.dbappid=new ArrayList<String>();
MyApplication.dbiconcode=new ArrayList<String>();
String appname,appid,iconcode;
try
{
Cursor c = db1.rawQuery("SELECT * FROM mytbl", null);
if(c!= null)
{
if (c.moveToFirst())
{
do {
image=null;imagehdr=null;
byte[] blob = c.getBlob(c.getColumnIndex("image"));
byte[] blobhdr = c.getBlob(c.getColumnIndex("imagehdr"));
appid=c.getString(c.getColumnIndex("appid"));
appname=c.getString(c.getColumnIndex("appname"));
iconcode=c.getString(c.getColumnIndex("iconcode"));
if(blob!=null)
{
image = BitmapFactory.decodeByteArray(blob, 0, blob.length);
}
if(blobhdr!=null)
{
imagehdr = BitmapFactory.decodeByteArray(blobhdr, 0, blobhdr.length);
}
//Images
MyApplication.dbimg.add(image);
MyApplication.dbappid.add(appid);
//String
MyApplication.dbappname.add(appname);
MyApplication.dbiconcode.add(iconcode);
MyApplication.dbhdrimage.add(imagehdr);
}while(c.moveToNext());
}
}
Log.d("db", "SQL Reading");
db1.close();
}
catch(Exception e)
{
System.out.println(e);
}
}//EOF readDataandImage
public int dbRowCount()
{
int rowcnt=0;
String countQuery = "SELECT * FROM mytbl";
//SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db1.rawQuery(countQuery, null);
rowcnt = cursor.getCount();
cursor.close();
db1.close();
Log.d("db", "Numrecs"+rowcnt);
return rowcnt;
}//EOFdbRowCount
}
where MyApplication is a static class to hold the read values.
I am trying to select the max date using the ORMLITE lib:
GenericRawResults<Object[]> result = null;
try {
String sql = "select MAX(t.last_updated_on_server_utc) from measurements t";
result = databaseManager.getMeasurementDao().queryRaw(
sql, new DataType[]{DataType.DATE_LONG}
);
List<Object[]> results = result.getResults();
if (results.size() == 0) {
return null;
} else {
Date d = (Date) results.get(0)[0];
// Date d = new Date((Long) results.get(0)[0]);
Log.d(TAG, "d=" + d);
}
} catch (SQLException e) {
}
The date returned is always 1970-01-01 (i.e the value of d in the debug output)...That field is declared as a java.util.Date. I also tried using DataType.LONG, and still the same. If I use a raw query to select one of the date columns it's fine, my problem is when I use MAX().