I want to sort the results coming from two cursors. Let's consider two different cursors to be Cursor
and Cursor1
.
Cursor
is from CallLog.Call.CONTENT_URI
and Cursor1
is from Telephony.Sms.CONTENT_URI
.
The problem is two cursors combined list is sorting two different ways. I want to sort this combined list using date columns. Sorry for my bad English.
Here is my LogManager.java
public List<CallLogModel> getLogs() {
List<CallLogModel> logObjectList;
logObjectList = new ArrayList<>();
Cursor cursor = this.context.getContentResolver().query(CallLog.Calls.CONTENT_URI,null, null, null, CallLog.Calls.DATE + " DESC ");
Cursor cursor1 = this.context.getContentResolver().query(Telephony.Sms.CONTENT_URI, null, null, null, Telephony.Sms.DATE + " DESC ");
// ------ Call Log ------
int number = Objects.requireNonNull(cursor).getColumnIndex("number");
int type = cursor.getColumnIndex("type");
int date = cursor.getColumnIndex("date");
int duration = cursor.getColumnIndex("duration");
// ------ Call Log end ------
// ------ SMS Log ------
int smsDate = Objects.requireNonNull(cursor1).getColumnIndexOrThrow(Telephony.Sms.DATE);
int smsNumber = cursor1.getColumnIndexOrThrow(Telephony.Sms.ADDRESS);
int smsType = cursor1.getColumnIndexOrThrow(Telephony.Sms.TYPE);
// ------ SMS Log end ------
while(cursor.moveToNext() && cursor1.moveToNext()) {
CallLogModel log = new CallLogModel(this.context);
// ------ Call Log ------
log.setNumber(cursor.getString(number));
log.setType(cursor.getInt(type));
log.setDuration(cursor.getInt(duration));
log.setDate(cursor.getLong(date));
// ------ Call Log end ------
// ------ SMS Log ------
log.setAddress(cursor1.getString(smsNumber));
log.setSmsDate(cursor1.getLong(smsDate));
log.setSmsType(cursor1.getInt(smsType));
logObjectList.add(log);.
// ------ SMS Log end ------
}
cursor.close();
cursor1.close();
return logObjectList;
}
Assuming that the date column is an integer (or a recognised SQLite datetime string SQL As Understood By SQLite - Date And Time Functions), then based upon the available information the following underlying query may do as you wish and the single result set means that you have a single cursor.
WITH combined AS (SELECT * FROM Calls UNION SELECT address, type, date, 0 FROM SMS)
SELECT * FROM combined ORDER BY date DESC;
This combines (makes a UNION) both tables (using 0 as the duration for SMS's (union requires both to have the same number of columns, hence the addition of 0)) and orders the combined list according to the date column.
The following
:-
DROP TABLE IF EXISTS Calls;
DROP TABLE IF EXISTS SMS;
/*
int number = Objects.requireNonNull(cursor).getColumnIndex("number");
int type = cursor.getColumnIndex("type");
int date = cursor.getColumnIndex("date");
int duration = cursor.getColumnIndex("duration");
*/
CREATE TABLE IF NOT EXISTS Calls (number INTEGER, type INTEGER, date INTEGER, duration INTEGER);
/*
int smsDate = Objects.requireNonNull(cursor1).getColumnIndexOrThrow(Telephony.Sms.DATE);
int smsNumber = cursor1.getColumnIndexOrThrow(Telephony.Sms.ADDRESS);
int smsType = cursor1.getColumnIndexOrThrow(Telephony.Sms.TYPE);
*/
CREATE TABLE IF NOT EXISTS SMS (address INTEGER, date INTEGER, type INTEGER);
INSERT INTO Calls VALUES
(1000000001,100,strftime('%s','now','+1 minutes'),30),
(1000000002,100,strftime('%s','now','+3 minutes'),30),
(1000000003,100,strftime('%s','now','+4 minutes'),30),
(1000000004,100,strftime('%s','now','+6 minutes'),30),
(1000000005,100,strftime('%s','now','-7 minutes'),30)
;
INSERT INTO SMS VALUES
(2000000011,strftime('%s','now','+2 minutes'),200) /* Should be between call 1 and call 2 */,
(2000000012,strftime('%s','now','-12 minutes'),200) /* Should be after call 1 (when sorted with DESC) */,
(2000000013,strftime('%s','now','+5 minutes'),200) /* between call 3 and 4 */,
(2000000014,strftime('%s','now','+6 minutes'),200) /* same as call4 ? may be before or after unless ORDER BY is more comprehensive */
;
SELECT *,datetime(date,'unixepoch') AS easytoreaddatetime FROM Calls;
SELECT *,datetime(date,'unixepoch') AS easytoreaddatetime FROM SMS;
/*<<<<<<<<<< THE QUERY >>>>>>>>>>*/
WITH combined AS (SELECT * FROM Calls UNION SELECT address, type, date, 0 FROM SMS)
SELECT *, datetime(date,'unixepoch') FROM combined ORDER BY date DESC;