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. 给Spring的placeholder设置默认值

    问题:使用Spring时,可以方便地通过placeholder的形式${key}将key对应的properities定义value,注入到Bean中.但是如果在properities文件中,没有对ke ...

  2. K3 LEDE固件更改FRP客户端版本

    1.下载文件 /usr/bin/wget --no-check-certificate https://github.com/fatedier/frp/releases/download/v0.23. ...

  3. 硬链接(hard link)和符号连接(symbolic link)

    inode ====== 在Linux系统中,内核为每一个新创建的文件分配一个inode,每个文件都有一个惟一的inode号,我们可以将inode简单理解成一个指针,它永远指向本文件的具体存储位置.文 ...

  4. iOS开发-自定义UIAlterView(iOS 7)

    App中不可能少了弹框,弹框是交互的必要形式,使用起来也非常简单,不过最近需要自定义一个弹框,虽然iOS本身的弹框已经能满足大部分的需求,但是不可避免还是需要做一些自定义的工作.iOS7之前是可以自定 ...

  5. 【R】函数-统计函数

  6. 解决excel日期变成数字的问题

    在Excel中如果单元格的公式是日期格式,那么引用后的数值是错误的[不是日期格式而被转换成数字类型了],这种情况显然不是我们想要的结果 解决办法: 在公式中强制转成文本类型即可(="Date ...

  7. [Angular] Communicate with Angular Elements using Inputs and Events

    In a real world scenario we obviously need to be able to communicate with an Angular Element embedde ...

  8. iOS debug release

    去掉日志 #ifndef __OPTIMIZE__ #define NSLog(...) NSLog(__VA_ARGS__) #else #define NSLog(...){} #endif 打开 ...

  9. ZH奶酪:PHP error_log()将错误信息写入日志文件

    error_log() 是发送错误信息到某个地方的一个函数,在程序编程中比较常见,尤其是在程序调试阶段. bool error_log ( string $message [, int $messag ...

  10. ZH奶酪:ionic+angularJS+cordova(FileTransfer)上传图片【移动端】

    [功能介绍] 在开发应用的时候,经常会遇到需要上传图片的功能,比如修改个人资料的头像.本文介绍的是基于ionic框架,在移动端上传图片的功能. [功能流程] (1)点击页面上的头像,弹出一个对话框,选 ...