2011-02-03 1 views
1

Я застрял с функциональностью call_log в Froyo. Как многие из вас знают, Froyo регистрирует в журнале вызовов не только звонки, но и каждое исходящее и входящее SMS-сообщение. Вы можете выбрать в вариантах для отображения всего этого дерьма или только определенные типы (исходящие вызовы, входящие вызовы, отправленные сообщения, принятые сообщения и т. Д.), Но поскольку это переключатель, вы не можете указывать, например, только текущие и входящие вызовы. Очень известна и анонсирована функциональность Froyo.Android Froyo: моя жизнь с call_log

Итак, я начал писать простой инструмент для чтения журнала вызовов. Вот фрагмент кода:

try { 
    mCur = getApplicationContext().getContentResolver() 
       .query(CallLog.Calls.CONTENT_URI, columns, null, null, null); 
    mCur.moveToFirst(); 
    io = mCur.getColumnIndex(CallLog.Calls._ID); 
    bo = mCur.getColumnIndex(CallLog.Calls.NUMBER); 
    no = mCur.getColumnIndex(CallLog.Calls.CACHED_NAME); 
    to = mCur.getColumnIndex(CallLog.Calls.TYPE); 

    while (mCur.isAfterLast() == false) { 
     i = mCur.getString(io); 
     b = mCur.getString(bo); 
     n = mCur.getString(no); 
     t = mCur.getString(to); 
     Log.i(TAG, "CallLog: ID="+i+" number="+b+" name="+n+" type="+t); 

     mCur.moveToNext(); 
    } 
} catch (Exception e) { 
    Log.e(TAG, "updateCallLog", e); 
} finally { 
    if (mCur != null) { 
     mCur.close(); 
     mCur = null; 
    } 
} 

Сюрприз, сюрприз, провайдер CALL_LOG пропускает смс записи из журнала вызовов. Поэтому с приведенным выше кодом я вижу только записи звонков (входящие или исходящие), все остальные записи пропускаются. Немного больше углубиться в это показало, что поставщик CallLog добавляет внутренне фильтрацию в базе данных журнала вызовов:

02-03 09:26:42.348 E/CLCService(28244): android.database.sqlite.SQLiteException: 
near ")": syntax error: , while compiling: 
SELECT _id, name, number, type FROM logs WHERE (logtype=100 OR logtype=500) AND (_ID=) 

Не ищите ошибки синтаксиса, он был создан с целью заставить поставщик сбросить запрос SQL с помощью вызова query(CallLog.Calls.CONTENT_URI, columns, "_ID=", null, null)). (_ID=) - это то, что предоставляется в запросе, остальная часть (logtype=100 OR logtype=500), по-видимому, добавлена ​​самим поставщиком журнала вызовов.

Поэтому у меня есть два вопроса:

  1. Где я могу найти в Android код, как провайдер добавляющий LOGTYPE фильтр? Я искал CallLog.java и CallLogProvider.java и не могу найти его.
  2. Как я могу прочитать все записи из журнала вызовов в Froyo? Я не могу обойти провайдера журналов вызовов и использовать мой собственный SQL-помощник для этого, пока я не буду корневать телефон, что не является вариантом. Есть ли другой способ сделать это?
+0

Ну, я загрузил исходники Android и искал «logtype». Еще ничего. Я нашел только этот метод:. ./QuickSearchBox/src/com/android/quicksearchbox/SuggestionData.java: public SuggestionData setSuggestionLogType (String logType) ', который, похоже, не используется вообще. Значит ли это, что моя проблема - это какой-то конкретный аддон для конкретного поставщика, которого нет в базовом коде Android? Я пользуюсь телефоном Samsung Galaxy S. –

ответ

0

Я не уверен, что что-то не так, но чтение журнала вызовов для получения только входящих или исходящих звонков достаточно просто. В приведенном ниже примере добавляются ограничения на запрос, чтобы он возвращал данные только для исходящих вызовов, сделанных после определенной даты. Строка where использует вопросительные знаки, чтобы указать, где значения из массива wargs должны быть заменены для формирования запроса sql.

О том, где возникает дополнительное предложение WHERE. Почти наверняка в реализации поставщика calllog. Поставщики обычно имеют оператор switch, который использует uri, который вы используете для открытия поставщика, а затем добавляет ограничения на основе uri. Кажется, что calllog находится в пакетах/провайдерах/ContactsProvider.

public static int getMinutesUsedSince(Context context, Date date) { 
    Uri uri = CallLog.Calls.CONTENT_URI; 
    String columns[] = new String[] { CallLog.Calls.DURATION }; 
    String where = CallLog.Calls.TYPE + "=? AND " + CallLog.Calls.DATE + ">?"; 
    String wargs[] = new String[] { 
      String.valueOf(CallLog.Calls.OUTGOING_TYPE), 
      String.valueOf(date.getTime()) 
    }; 
    String sortOrder = "date DESC"; 
    Cursor c = context.getContentResolver().query(uri, columns, where, wargs, sortOrder); 
    long sum = 0; 
    int durationIndex = c.getColumnIndex(CallLog.Calls.DURATION); 
    if (c.moveToFirst()) { 
     do { 
      /* for each individual call, round up to the nearest minute */ 
      long duration = c.getLong(durationIndex); 
      long minutes = (long)Math.ceil(duration/60.0); 
      sum += minutes; 
     } while (c.moveToNext()); 
    } 
    c.close(); 
    return (int)sum; 
}