如何实现通话记录的 ContentObserver

2023-11-30

我想知道是否有办法知道呼叫的内容提供商是否已更改。我的意思是,如果我拨打电话或接听电话,它会返回一个“标志”,表明新日志已添加到通话记录中,或者 Android 存储有关通话信息的位置。

因为,当我拨打电话时,Android 会将号码、联系人姓名(如果存在)、通话时间、持续时间……全部存储在内容提供程序中。那么有没有一种方法可以捕获这个“标志”,表明呼叫的内容提供者更大,我的意思是,新的数据已插入到内容提供者CallLog.Calls上。

所以,对于这个问题,我还是有很多疑问。我不知道在哪里注册内容观察者。我的意图是,当 CallLog 内容提供程序发生变化时,将使用代码的 insert 方法。

我的意思是,除非新数据已添加到 CallLog 内容提供程序中,否则代码不会执行任何操作。如果某些数据已添加到 CallLog 内容提供程序中,则代码将查询新数据,然后插入。我想这样做,因为如果没有内容观察器,应用程序将在每次运行应用程序时已插入的数据库中插入数据,明白了吗?

这是我的代码。如果有人能告诉我该放在哪里registerContentObserver()以及其他所需的一切。

public class RatedCalls extends ListActivity {

    private SQLiteDatabase db;
    private CallDataHelper dh = null;
    StringBuilder sb = new StringBuilder();
    OpenHelper openHelper = new OpenHelper(RatedCalls.this);

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Cursor cursor = getContentResolver().query(
                android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
                android.provider.CallLog.Calls.DATE + " DESC ");

        dh = new CallDataHelper(this);
        db = openHelper.getWritableDatabase();

        startManagingCursor(cursor);
        int numberColumnId = cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
        int durationId = cursor.getColumnIndex(android.provider.CallLog.Calls.DURATION);
        int contactNameId = cursor.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
        int dateId = cursor.getColumnIndex(android.provider.CallLog.Calls.DATE);
        int numTypeId = cursor.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);

        Date dt = new Date();
        int hours = dt.getHours();
        int minutes = dt.getMinutes();
        int seconds = dt.getSeconds();
        String currTime = hours + ":" + minutes + ":" + seconds;

        ArrayList<String> callList = new ArrayList<String>();
        if (cursor.moveToFirst()) {
            do {
                String contactNumber = cursor.getString(numberColumnId);
                String contactName = cursor.getString(contactNameId);
                String duration = cursor.getString(durationId);
                String callDate = DateFormat.getDateInstance().format(dateId);
                String numType = cursor.getString(numTypeId);

                ContentValues values = new ContentValues();
                values.put("contact_id", 1);
                values.put("contact_name", contactName);
                values.put("number_type", numType);
                values.put("contact_number", contactNumber);
                values.put("duration", duration);
                values.put("date", callDate);
                values.put("current_time", currTime);
                values.put("cont", 1);

                this.db.insert(CallDataHelper.TABLE_NAME, null, values);

                Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG);
                callList.add("Contact Number: " + contactNumber
                        + "\nContact Name: " + contactName + "\nDuration: "
                        + duration + "\nDate: " + callDate);

            } while (cursor.moveToNext());
        }
        setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem, callList));

        ListView lv = getListView();
        lv.setTextFilterEnabled(true);
        lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

这就是答案。不要忘记使用此方法注册内容观察器:

registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer)

然后你就可以像这样创建它。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.getApplicationContext()
    .getContentResolver()
    .registerContentObserver(
            android.provider.CallLog.Calls.CONTENT_URI, true,
            new MyContentObserver(handler)); 
}

class MyContentObserver extends ContentObserver {
    public MyContentObserver(Handler h) {
        super(h);
    }

    @Override
    public boolean deliverSelfNotifications() {
        return true;
    }

    @Override
    public void onChange(boolean selfChange) {
        Log.d(LOG_TAG, "MyContentObserver.onChange("+selfChange+")");
        super.onChange(selfChange);

        // here you call the method to fill the list
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何实现通话记录的 ContentObserver 的相关文章

随机推荐

  • jQuery - 如何将字符串中的每个字符包装在跨度中

    如何将div的字符转换为span 例如 我想转换这个 div Hello World div 进入这个 div span H span span e span span l span span l span span o span span
  • 如何将简单类序列化/反序列化为 XML 并返回

    有时我想模拟类的存储数据 而不需要设置与数据库的往返 例如 假设我有以下课程 public class ShoppingCart public List
  • 工作自动构建增量 Visual Studio 插件

    我正在寻找一个working Visual Studio 2012插件会自动增加我的内部版本号 就像是http autobuildversion codeplex com 但这对我不起作用 如果重要的话 我正在使用 Visual Studi
  • 使用 gson 解析 JSON 数组

    我在解析从 javascript 获取的 JSON 时遇到问题 JSON的格式是这样的 positions x 50 y 50 x 82 y 50 x 114 y 50 x 146 y 50 positions x 210 y 50 x 2
  • WPF NotifyPropertyChangeds 是否编组到调度程序?

    如果我更新一个在绑定控件调度程序之外的线程上抛出 INotifyPropertyChanged 的 属性 更新会被强制编组到该调度程序吗 BackgrounWorker Run gt blah Blahness 2 notifies pro
  • 从对象数组构造 TypeScript 类型

    我有数据库表的以下架构列 用于西瓜数据库 const columns name created at type number isOptional true name created by type string name is corru
  • 在Java中通过URL调用PHP文件

    我正在尝试开发一个 Android 应用程序 它调用 php 文件来查询并从数据库中提取数据 该 URL 可以在我的手机上通过网络浏览器访问 但我似乎无法从下面的 java 代码中调用它 任何人都可以帮助我从我的 Java 代码调用我的 P
  • wpf 窗口的默认字体大小是如何确定的?

    据我了解 在 WPF 中 控件使用的字体大小由父控件确定 除非定义了覆盖 鉴于我没有在应用程序中的任何位置定义字体大小 我假设默认字体大小是为顶级窗口配置的 该值是否由应用程序运行所在的系统决定 如果是 则在哪里 或者它是由某些内置的 WP
  • jQuery 调整两侧大小

    我会尝试用文字说清楚 我想知道是否有一种方法可以使用 jquery ui resizing 来同时调整 4 个边上的对象的大小 以便使对象的中心保持在相同的位置 这是沙箱http jsfiddle net V79Ge 所以 它很像aspec
  • 将 char* 交给 std::string 进行管理(最终释放内存)

    我必须使用一个库函数 为生成的字符串分配一些内存并返回一个char 期望调用者最终释放内存free Example declaration of the library function char foo Example usage aut
  • 在 Java 中使用 LIMIT 命令和预处理语句时出现 MySQL 语法错误

    我正在用 Java 编写代码 我想每次运行此代码时都从 MySQL 表中获取下一行 我第二次运行此代码是这样的 String timh1 1 String timh2 2 PreparedStatement st null String s
  • 空手道:重复请求

    我想重复 6 次场景的 post 请求 Given url
  • 如何根据表中的多列获取唯一记录

    考虑下表 primaryKey id activity template creator created 1 1 3 5 x 2011 10 13 2 2 4 2 y 2011 10 15 3 2 4 7 z 2011 10 24 4 2
  • 使用 WMI 和 C# 检测机器是否在线或离线

    我使用vs2008 winxp 在局域网中使用Win2003服务器 我想要在winxp中安装一个应用程序来检测win2003机器是否在线或离线 以及启动时是否离线 我有这个参考资料 还有更多参考资料 代码示例和最佳实践吗 http dani
  • 将树序列化为 Json 对象

    我有以下课程 树节点 cs public class TreeNode IEnumerable
  • Task.WhenAny 用于无故障任务

    的描述Task WhenAny方法说 它将返回第一个完成的任务 即使它出错了 有没有办法改变这种行为 以便它返回第一个成功的任务 像这样的东西应该可以做到 可能需要一些调整 尚未测试 private static async Task
  • 如何将整数数组连接成逗号分隔的字符串

    其实我有两个问题 如何将整数数组连接成逗号分隔的字符串 1 2 3 gt 1 2 3 如何将整数数组转换为字符串数组 1 2 3 gt 1 2 3 arraylist New Object system collections arrayl
  • 如何使用自动布局设置 tableHeaderView (UITableView) 的高度?

    在过去的三四个小时里 我一直用这个把头撞在墙上 但我似乎无法弄清楚 我有一个 UIViewController 里面有一个全屏 UITableView 屏幕上还有其他一些东西 这就是为什么我不能使用 UITableViewControlle
  • SonarQube Java插件3.7分析错误

    我最近升级到 SonarQube 5 2 和 Java 插件 3 7 在分析我的项目期间遇到以下错误 我已经删除了类文件名 但它是一个非静态的私有内部类 该分析适用于 Java 插件版本 3 5 和 3 6 仅在 3 7 下失败 有人可以帮
  • 如何实现通话记录的 ContentObserver

    我想知道是否有办法知道呼叫的内容提供商是否已更改 我的意思是 如果我拨打电话或接听电话 它会返回一个 标志 表明新日志已添加到通话记录中 或者 Android 存储有关通话信息的位置 因为 当我拨打电话时 Android 会将号码 联系人姓