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. Sharepoint2013 列表的NewForm 页面添加一个 保存新建 按钮

    昨天一同事问我如何在sharepoint2013的NewForm.aspx页面上添加一个 save and new的button.实现save 和new的功能,save的功能和默认的save按钮效果一 ...

  2. 如何把本地代码提交到git(码云)、github代码管理项目上

    前提必须安装了git工具 以下命令操作都是通过git bash操作. 将本地代码提交到码云空项目操作: D:\>mkdir inek_winprop D:\>cd inek_winprop ...

  3. 前端框架 Vue 初探

    一.前言 前几日使用微信网页版时,好奇这个网页用了什么前端框架.用Chrome的开发人员模式一探到底,发现原来用了一个名叫 Angular 的框架.好吧,既然微信用了.那我也最好还是看看.等等,你这篇 ...

  4. php学习笔记之动态生成一组单选button

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 页面显示This is the initial start page for the WebDriver server.的解决办法

    今天在做项目的时候,遇到一个奇怪的问题,打开浏览器是正常的,但是页面不会跳转到需要的URL,而是提示一行白字,如图: 反复研究了脚本,没有问题啊,但是就是不跳转. 后来查了下,在某论坛上找到了答案: ...

  6. 具体解说Android的图片下载框架UniversialImageLoader之磁盘缓存(一)

    沉浸在Android的开发世界中有一些年头的猴子们,预计都可以深深的体会到Android中的图片下载.展示.缓存一直是心中抹不去的痛.鄙人亦是如此.Ok,闲话不说.为了督促自己的学习.以下就逐一的挖掘 ...

  7. Mybatis源码分析之Cache二级缓存原理 (五)

    一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...

  8. Core Java-多线程-线程的生命周期

    0. 在介绍线程前我们先看一下什么是进程? 进程是线程的母亲,如果在大学计算机课程里读过操作系统一定不会陌生. 所谓进程,它是计算机程序关于某数据集上的一次活动,是系统进行资源分配和调度的基本单位,是 ...

  9. 【linux】Ubuntu中shell脚本无法使用source的原因及解决方法

    问题现象: shell脚本中source aaa.sh时提示 source: not found 原因: ls -l `which sh` 提示/bin/sh -> dash 这说明是用dash ...

  10. 微信小程序 - 自适应swiper高度(非组件)

    微信小程序swiper默认高度375rpx,一旦超过这高度,就滑动不到内容了,我们利用css3可以很简单做到这件事情 原理: 利用css3 横轴滚动属性overflow:scroll,设置死swipe ...