1

我坚持使用 Froyo 中的 call_log 功能。众所周知,Froyo 不仅会登录通话记录,还会记录每条传出和传入的 SMS 消息。您可以在选项中选择显示所有这些废话,或仅显示特定类型(拨出电话、拨入电话、已发送消息、已接收消息等),但由于这是单选按钮,您不能仅指定正在进行的和传入的呼叫。非常知名且令人讨厌的 Froyo 功能。

所以我开始写一些简单的工具来自己阅读通话记录。这是代码片段:

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=)

不要查找语法错误,它是故意创建的,目的是强制提供程序通过调用query(CallLog.Calls.CONTENT_URI, columns, "_ID=", null, null )). 这(_ID=)是查询中提供的内容,其余部分(logtype=100 OR logtype=500)显然是由呼叫日志提供程序本身添加的。

所以我有两个问题:

  1. 我在哪里可以在 Android 代码中找到提供者如何添加 logtype 过滤器?我正在查看CallLog.javaCallLogProvider.java并找不到它。
  2. 如何从 Froyo 的通话记录中读取所有记录?我无法绕过通话记录提供程序并为此使用我自己的 SQL 帮助程序,直到我不会 root 电话,这不是一个选项。还有其他方法吗?
4

1 回答 1

0

我不确定出了什么问题,但阅读通话记录以获取来电或去电非常简单。下面的示例对查询添加了限制,使其仅返回特定日期之后拨出的呼叫的数据。该where字符串使用问号来指示wargs应将数组中的值替换到何处以形成 sql 查询。

关于额外 WHERE 子句出现的位置。几乎可以肯定在 calllog 提供程序实现中。提供程序通常有一个 switch 语句,它使用您用来打开提供程序的 uri,然后根据 uri 添加限制。呼叫日志似乎在包/提供者/联系人提供者中。

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;
}
于 2011-11-26T15:21:24.080 回答