如何对两个不同的游标列表进行排序?

How to sort a two different cursor list?

我想对来自两个游标的结果进行排序。让我们考虑两个不同的游标 CursorCursor1

Cursor 来自 CallLog.Call.CONTENT_URICursor1 来自 Telephony.Sms.CONTENT_URI

问题是两个游标组合列表正在以两种不同的方式排序。我想使用日期列对这个组合列表进行排序。抱歉我的英语不好。

这是我的 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;
    }

假设 date 列是一个整数(或可识别的 SQLite 日期时间字符串 SQL As Understood By SQLite - Date And Time Functions),然后根据可用信息,以下基础查询可能会执行以下操作您希望,单个结果集意味着您只有一个游标。

WITH combined AS (SELECT * FROM Calls UNION SELECT address, type, date, 0 FROM SMS)
SELECT * FROM combined ORDER BY date DESC;

这结合(使 UNION)两个 tables(使用 0 作为 SMS 的持续时间(联合要求两者具有相同的列数,因此添加 0)) 并根据日期列对组合列表进行排序。

例子

以下

  1. 删除 tables,如果它们存在重新运行能力。
  2. 创建 tables(基于可能存在的列(名称可能不同))
  3. 将一些数据加载到调用中 table。
  4. 将一些数据加载到 SMS 中 table(时间穿插在通话时间中)
  5. 从每个 table 中选择行(带有一个额外的派生列,以易于阅读的格式显示日期)
  6. 最终如上调用查询。

:-

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;

结果

1。调用 table + 易于阅读格式的日期时间

2。短信 table + 易读格式的日期时间

3。合并后的排序列表

  • 注意 SMS 行已突出显示(它们以 2 而不是 1 开头)
  • 还为演示添加了易于阅读的数据和时间。