Как отсортировать два разных списка курсора? - PullRequest
2 голосов
/ 26 сентября 2019

Я хочу отсортировать результаты по двум курсорам.Давайте рассмотрим два разных курсора: Cursor и Cursor1.

Cursor от CallLog.Call.CONTENT_URI и Cursor1 от 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;
    }

1 Ответ

1 голос
/ 26 сентября 2019

Если предположить, что столбец date является целым числом (или распознанной строкой даты и времени SQLite SQL, понятный SQLite - функциями даты и времени ), то на основе доступной информации следующеебазовый запрос может делать, как вы хотите, и один результирующий набор означает, что у вас есть один курсор.

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

Это объединяет (составляет UNION ) обе таблицы (используя 0 в качестве продолжительности)для SMS (объединение требует, чтобы оба столбца имели одинаковое количество столбцов, следовательно, добавляется 0) ) и упорядочивает объединенный список в соответствии со столбцом даты.

Пример

Следующее

  1. Удаляет таблицы, если они существуют для возможности повторного запуска.
  2. Создает таблицы (на основе вероятных столбцов (имена могут быть разными))
  3. Загружает некоторые данные в таблицу Calls.
  4. загружает некоторые данные в таблицу SMS (со временем, перемежающимся с временем вызова)
  5. ВЫБИРАЕТ строки из каждой таблицы (с помощью exпроизводный столбец tra, который показывает дату в удобном для чтения формате)
  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;

Results

1.Таблица вызовов + дата / время в удобном для чтения формате

enter image description here

2.Таблица SMS + дата / время в удобном для чтения формате

enter image description here

3.Объединенный, отсортированный список

enter image description here

  • Примечание Строки SMS выделены (они начинаются с 2, а не с 1)
  • Для демонстрации добавлены легко читаемые данные и время.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...