您的位置:首页 > 其它

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

2015-11-11 17:32 471 查看
关于监听联系人变化的问题与解决方法探讨
需要注意的问题:文中的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]

联系人,

打电话,
监听,
通讯录,
通话记录

评分

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: