关于监听联系人变化的问题与解决方法探讨

关于监听联系人变化的问题与解决方法探讨

需要注意的问题:文中的ContentObserve的使用是一个非常好的主意;不过在两个数据库的监听和Handler消息发送上容易出问题。

建议改为对联系人data表的监听:

部分主要代码如下:

1.

//注册监听联系人数据库
Uri uri=Uri.parse("content://com.android.contacts/data");
getContentResolver().registerContentObserver(uri, true, mContactObserver);

2.

 /**
     * 系统联系人数据库监控器
     */
    public ContentObserver mContactObserver=new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            //当系统联系人数据库发生更改时触发此操作
            LogUtil.d(TAG, "SYS CONTACT CHANGE");

//            //去掉多余的或者重复的同步
//            mHandler.removeMessages(CONTACT_CHANGE);

            //延时ELAPSE_TIME(10秒)发送同步信号CONTACT_CHANGE
            mHandler.sendEmptyMessageDelayed(CONTACT_CHANGE, ELAPSE_TIME);
        }
    };


原文转自:

http://www.eoeandroid.com/forum.php?mod=viewthread&tid=234378



由于最近做的项目Any.ONE中需要缓冲联系人数据库,遇到很狗血的是,Android只能监听整个数据库的改变,更狗血的是,当你监听联系人数据库时,通话记录改变,也就是打一下电话什么的,也会触发前面的监听器!具体原因,查看了一下资料,主要是联系人数据库中有“联系次数"、”最后通话时间“等字段,所以每次打电话都会更新联系人数据库。

始终查不到比较完美的解决方法,这里展示出我的比较折中的解决办法,主要思路是同时监听联系人数据库和通话记录数据库,如果两个监听器都触发了,则认为这仅仅是打了一次电话,如果只有联系人数据库的监听器被触发了,则认为是真正的联系人被更改了,从而做出相应的处理。当然,这是一种折中的处理,会有一些“意外”,不过一般都不会出现而且可被接受。

如果哪位大神对“监听联系人变化”这个问题有比较好的方法,希望提供出来研讨一下,谢谢~

下面是解决代码片段,带详细注释,是一个Service来的,稍作修改即可直接使用:

[mw_shl_code=java,true]package tk.linshuaibin.any.one;

import android.app.Service;
import android.content.Intent;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.util.Log;

public class ContacterSyncService extends Service {

        private final static String TAG = "Any.ONE.ContacterSyncService";
        
        //延时处理同步联系人,若在延时期间,通话记录数据库未改变,即判断为联系人被改变了
        private final static int ELAPSE_TIME = 10000;
        
        
        private Handler mHandler = null;

        public ContentObserver mObserver = new ContentObserver(new Handler()) {

                @Override
                public void onChange(boolean selfChange) {
                        // 当系统联系人数据库发生更改时触发此操作

                        Log.i(TAG, "Catact");
                        
                        //去掉多余的或者重复的同步
                        mHandler.removeMessages(0);

                        //延时ELAPSE_TIME(10秒)发送同步信号“0”
                        mHandler.sendEmptyMessageDelayed(0, ELAPSE_TIME);
                }

        };

        // 当通话记录数据库发生更改时触发此操作
        private ContentObserver mCallLogObserver = new ContentObserver(new Handler()) {
                @Override
                public void onChange(boolean selfChange) {
                        // 当通话记录数据库发生更改时触发此操作
                        Log.i(TAG, "CallLog");
                        //如果延时期间发现通话记录数据库也改变了,即判断为联系人未被改变,取消前面的同步
                        mHandler.removeMessages(0);
                }

        };
        
        

        //在此处处理联系人被修改后应该执行的操作
        public void updataContact() {
                //DO SOMETHING HERE...
        }

        @Override
        public IBinder onBind(Intent arg0) {
                return null;
        }

        @Override
        public void onCreate() {
                super.onCreate();
                Log.i(TAG, "OnCreate");
                //注册监听通话记录数据库
                getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, mCallLogObserver);
                //注册监听联系人数据库
                getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, mObserver);
               
                //为了避免同步联系人时阻塞主线程,此处获取一个子线程的handler
                new Thread(new Runnable() {
                        public void run() {
                                Looper.prepare();
                                mHandler = new Handler() {
                                        @Override
                                        public void handleMessage(Message msg) {
                                                switch (msg.what) {
                                                case 0:
                                                        updataContact();
                                                        break;

                                                default:
                                                        break;
                                                }
                                        }
                                };
                                Looper.loop();
                        }
                }).start();
        }

        @Override
        public void onStart(Intent intent, int startId) {
                super.onStart(intent, startId);

        }

        @Override
        public void onDestroy() {
                super.onDestroy();
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
                return flags;
        }

}
[/mw_shl_code]


评分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值