1. 注册ContentObserver时Sms.Inbox.CONTENT_URI应改成Sms.CONTENT_URI.

getContentResolver().registerContentObserver(Sms.Inbox.CONTENT_URI,
        true, mInboxObserver);

此时Uri是Sms.Inbox.CONTENT_URI,它并没有表示一张表。我将它理解为Sms.CONTENT_URI的一个视图。

getContentResolver().registerContentObserver(Sms.CONTENT_URI,
        true, mInboxObserver);

2. 在使用getContentResolver().update()方法时必须设置selection参数。

如果selection为null,表示Uri表示的所有数据都在update的范围之中。

如果Uri表示某一张表,比如Sms.CONTENT_URI表示Sms表,如果没有设定selection,那么将修改Sms表中所有数据,造成低级但严重错误。

private ContentObserver mInboxObserver = new ContentObserver(null) {
    public void onChange(boolean selfChange) {
        Cursor cursor = getContentResolver().query(Sms.Inbox.CONTENT_URI,
                new String[]{Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.BODY, Sms.DATE, Sms.READ},
                "type = " + Sms.MESSAGE_TYPE_INBOX + " and read = 0 and thread_id = " + getOrCreateThreadId(),
                null, null);
        TxrjMessage msg = null;
        if(cursor != null) {
            if(cursor.moveToFirst()) {
                msg = new TxrjMessage();
                msg.setMessageId(cursor.getInt(cursor.getColumnIndex(Sms._ID)));
                msg.setThreadId(cursor.getInt(cursor.getColumnIndex(Sms.THREAD_ID)));
                msg.setType(cursor.getInt(cursor.getColumnIndex(Sms.TYPE)));
                msg.setBody(cursor.getString(cursor.getColumnIndex(Sms.BODY)));
                msg.setTime(cursor.getLong(cursor.getColumnIndex(Sms.DATE)));
                mMessages.add(msg);
                mHandler.sendMessage(mHandler.obtainMessage()); // 在优化过程中会改掉。
            }
            cursor.close();
        }
        if(msg != null) {
            ContentValues values = new ContentValues();
            values.put(Sms._ID, msg.getMessageId()); // Bug语句。
            values.put(Sms.READ, 1);
            getContentResolver().update(Sms.Inbox.CONTENT_URI, values, null, null); // selection为null是个bug。
        }
    }
};

3. 在onChange()方法中使用Handler,使程序在主线程中更新UI,

onChange()方法是否在主线程中执行,有待确定。

private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        mListAdapter.notifyDataSetChanged();
        mListView.setSelection(mListView.getBottom());
    }
};

4. 在会话列表界面中,点击某个会话打开信息列表界面之前将此会话中的未读信息改为已读。

在ConversationListActivity中点击某个item时首先执行

if(thread.getUnReadCount()>0) {
    ContentValues values = new ContentValues();
    values.put(Sms.READ, 1);
    getContentResolver().update(Sms.Inbox.CONTENT_URI, values,
            "read=0 and thread_id=" + thread.getThreadId(), null);
}

5. 将收到的未读信息在ListView中显示出来,并且修改它的read字段。

在执行getContentResolver.update()之前关闭cursor,否则:

当update()方法执行之后修改了数据,然后再从之前query返回的cursor中获得数据将出现不同步结果。

private ContentObserver mInboxObserver = new ContentObserver(null) {
    public void onChange(boolean selfChange) {
        Log.i("txrjsms", "receive a message.");           
        Cursor cursor = getContentResolver().query(Sms.CONTENT_URI,
                new String[]{Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.BODY, Sms.DATE, Sms.READ},
                "type = " + Sms.MESSAGE_TYPE_INBOX + " and read = 0 and thread_id = " + mThreadId,
                null, null);
        TxrjMessage msg = null;
        if(cursor != null) {
            if (cursor.moveToFirst()) {
                msg = new TxrjMessage();
                msg.setMessageId(cursor.getInt(cursor.getColumnIndex(Sms._ID)));
                msg.setThreadId(cursor.getInt(cursor.getColumnIndex(Sms.THREAD_ID)));
                msg.setType(cursor.getInt(cursor.getColumnIndex(Sms.TYPE)));
                msg.setBody(cursor.getString(cursor.getColumnIndex(Sms.BODY)));
                msg.setTime(cursor.getLong(cursor.getColumnIndex(Sms.DATE)));
                cursor.close();
                ContentValues values = new ContentValues();
                values.put(Sms.READ, 1);
                getContentResolver().update(Sms.CONTENT_URI, values, "_id=" + msg.getMessageId(), null);
                mMessages.add(msg);
                mHandler.sendMessage(mHandler.obtainMessage());
            }
        }
    }
};

6. 在uri中指定了具体哪条数据,因此可以将selection置为空。

private void updateMsgType(Uri uri, int type) {
    ContentValues values = new ContentValues();
    values.put(Sms.TYPE, type);
    getContentResolver().update(uri, values, null, null);
}

信息列表中的ContentObserver、CONTENT_URI等的更多相关文章

  1. freecms怎样在信息列表类标签中提取info.content

    原文地址:http://javaz.cn/site/javaz/site_study/info/2015/22026.html 项目地址:http://www.freeteam.cn/ 因为info. ...

  2. 如若已在管理后台更新域名配置,请刷新项目配置后重新编译项目,操作路径:“项目-域名信息” http://www.mysite.com 不在以下 request 合法域名列表中

    报错如图 报错文字如下: 如若已在管理后台更新域名配置,请刷新项目配置后重新编译项目,操作路径:“项目-域名信息” http://www.mysite.net 不在以下 request 合法域名列表中 ...

  3. 【Azure Developer】在Azure Resource Graph Explorer中查看当前订阅下的所有资源信息列表并导出(如VM的名称,IP地址内网/公网,OS,区域等)

    问题描述 通过Azure的Resource Graph Explorer(https://portal.azure.cn/#blade/HubsExtension/ArgQueryBlade),可以查 ...

  4. chmod a+w . 权限控制 su、sudo 修改文件所有者和文件所在组 添加用户到sudoer列表中 当前用户信息

    对当前目录对所有用户开放读写权限 chmod a+r . $ sudo chmod -R a+w /usr/lib/python2.7 所有用户添加文件的写权限 [linux]su.sudo.sudo ...

  5. vs2015 编译时错误列表中没有错误,dll却没有生成出来

    最近发现vs2015的一个问题, 编译时,错误列表中没有错误,dll却没有生成出来,vs重启也无效 解决: 多次排查发现如果一个类库设置的是framework 4.0版本,但引用了framework4 ...

  6. 微信小程序 不在以下合法域名列表中,请参考文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html

    微信小程序  不在以下合法域名列表中,请参考文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html 友情提示: 大家 ...

  7. 从下拉菜单拖拽一个元素 出来,插入到页面中的app 列表中

    1,实现功能:从下拉菜单拖拽一个元素 出来,插入到页面中的app 列表中 并实现app向后移动一个元素的位置: 2.实现思路: 01.遍历下拉菜单,添加拖拽方法,实现位置移动功能: 02.遍历app列 ...

  8. 在GridView列表中使用图片显示记录是否包含附件

    在我的前面很多文章中,都介绍过通用附件模块的管理,本篇随笔主要介绍在一些应用模块中的列表展示中,包含附件的记录,在GridView列表界面中使用图标来快速显示是否有附件的情况. 1.通用附件模块的应用 ...

  9. 在滚动列表中实现视频的播放(ListView & RecyclerView)

    英文原文:Implementing video playback in a scrolled list (ListView & RecyclerView) 本文将讲解如何在列表中实现视频播放. ...

随机推荐

  1. FreePascal - Typhon在Windows10 X64下的使用问题!

    Typhon是CodeTyphon中的开发FreePascal的IDE工具. 在Windows10 X64中安装完CodeTyphon后,我们会发现有两套Typhon,分别对应32位和64位,32位可 ...

  2. 关于LINQ和SQL操作数据库的性能测试(转)

    微软linq技术已经出现很久,很多公司已经开始商业使用,作为我们暂时没有用到的人来说,也应该适当的了解下相关知识,但是直到目前网络上对他的看法仍然是褒贬不一,当然任何事情都不可能完美的,下面就针对大多 ...

  3. tensoflow数据读取

    数据读取 TensorFlow程序读取数据一共有3种方法: 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码来供给数据. 从文件读取数据: 在TensorFl ...

  4. 【转】Linux基础与Linux下C语言编程基础

    原文:https://www.cnblogs.com/huyufeng/p/4841232.html ------------------------------------------------- ...

  5. 关于 stl的内存分配的深浅拷贝

    http://blog.csdn.net/u012501459/article/details/44132147

  6. 用 CSS 实现元素垂直居中,有哪些好的方案?

    1.不知道自己高度和父容器高度的情况下, 利用绝对定位只需要以下三行: parentElement{ position:relative; } childElement{ position: abso ...

  7. 【iOS地图开发】巧妙打造中英文全球地图

    地图开发的同学们经常遇到这样的问题,国内版地图开发,用高德或者百度就行了.但是,国外的地图怎么办?这里告诉大家,如果利用iOS地图,打造中英文的,国内国外都能用的,全球地图. 制作全英文地图的展示并不 ...

  8. iOS 获取APP相关信息 私有API

    /* Generated by RuntimeBrowser Image: /System/Library/Frameworks/MobileCoreServices.framework/Mobile ...

  9. ZH奶酪:PHP 执行时间Fatal error: Maximum execution time of...

    来源:http://stackoverflow.com/questions/5164930/fatal-error-maximum-execution-time-of-30-seconds-excee ...

  10. Centos7中firewalld防火锁墙的使用

    一.服务控制 启动: systemctl start firewalld 查看状态: systemctl status firewalld  停止: systemctl disable firewal ...