sim卡联系人的增删改查主要是通过ContentProvider来进行操作的,在android中对sim卡联系人操作的provider是定义在IccProvider.java这个类中的,这个类位于android源码的位置frameworks/base/telephony/java/com/android/internal/telephony/IccProvider.java,里面有对sim操作的uri定义和增删改查方法的定义

具体对sim卡联系人的增删改查都是通过AIDLIIccPhoneBook调用完成对sim的具体操作,在这里推荐一个查看android源码在线观看的网址,有兴趣的可以自己去看看。

对sim操作的uri单卡手机和双卡手机是不同的,你也可以查看相应的源码查看具体uri的定义

一般单卡为:"content://icc/adn"双卡为"content://icc/adn/subid/0""content://icc/adn/subid/1"

1.查询sim卡里的联系人

public void queryAllContact() {Cursor cursor = getContentResolver().query(uri, null, null, null, null);Log.d(TAG, "cursor count=" + cursor.getCount());while (cursor.moveToNext()) {String[] columnNames = cursor.getColumnNames();for (int i = 0; i < columnNames.length; i++) {String name = cursor.getString(0);String number = cursor.getString(1);String emails = cursor.getString(2);String id = cursor.getString(3);simCardInfo cardInfo = new simCardInfo(id, name, emails, number);if (i == columnNames.length - 1) {Log.d(TAG, "simcardinfo=" + cardInfo.toString());}}}}

2.向sim卡里添加联系人

public void insertContact(String name, String phoneNumber) {ContentValues values = new ContentValues();values.put("tag", name);values.put("number", phoneNumber);Uri insertInfo = getContentResolver().insert(uri, values);Log.d(TAG, insertInfo.toString());}

3.更新sim卡里联系人

public void updateContact(String oldName, String oldPhone, String newName,String newPhone) {ContentValues values = new ContentValues();values.put("tag", oldName);values.put("number", oldPhone);values.put("newTag", newName);values.put("newNumber", newPhone);int update = getContentResolver().update(uri, values, null, null);Log.d(TAG, "update =" + update);}

4.删除sim里的联系人

public void deleteContact(String name, String phone) {// 这种方式删除数据时不行,查阅IccProvider源码发现,在provider中重写的delete方法并没有用到String[]// whereArgs这个参数// int delete = getContentResolver().delete(uri,// " tag = ? AND number = ? ",// new String[] { "jason", "1800121990" });String where = "tag='" + name + "'";where += " AND number='" + phone + "'";int delete = getContentResolver().delete(uri, where, null);Log.d(TAG, "delete =" + delete);}
在删除sim卡联系人时,开始利用下面的语句,发现删除返回的值一直为0,并没有删除成功。

int delete = getContentResolver().delete(uri," tag = ? AND number = ? ",new String[] { "jason", "1800121990" });

通过查看Iccprovider具体定义的delete的地方并没有用到String[] whereArgs这个参数,而是通过where中对”AND“和“=”进行切割来实现的,具体代码如下

    @Override    public int delete(Uri url, String where, String[] whereArgs) {        int efType;        int subId;        int match = URL_MATCHER.match(url);        switch (match) {            case ADN:                efType = IccConstants.EF_ADN;                subId = SubscriptionManager.getDefaultSubId();                break;            case ADN_SUB:                efType = IccConstants.EF_ADN;                subId = getRequestSubId(url);                break;            case FDN:                efType = IccConstants.EF_FDN;                subId = SubscriptionManager.getDefaultSubId();                break;            case FDN_SUB:                efType = IccConstants.EF_FDN;                subId = getRequestSubId(url);                break;            default:                throw new UnsupportedOperationException(                        "Cannot insert into URL: " + url);        }        if (DBG) log("delete");        // parse where clause        String tag = null;        String number = null;        String[] emails = null;        String pin2 = null;        String[] tokens = where.split("AND");        int n = tokens.length;        while (--n >= 0) {            String param = tokens[n];            if (DBG) log("parsing '" + param + "'");            String[] pair = param.split("=");            if (pair.length != 2) {                Rlog.e(TAG, "resolve: bad whereClause parameter: " + param);                continue;            }            String key = pair[0].trim();            String val = pair[1].trim();            if (STR_TAG.equals(key)) {                tag = normalizeValue(val);            } else if (STR_NUMBER.equals(key)) {                number = normalizeValue(val);            } else if (STR_EMAILS.equals(key)) {                //TODO(): Email is null.                emails = null;            } else if (STR_PIN2.equals(key)) {                pin2 = normalizeValue(val);            }        }        if (efType == FDN && TextUtils.isEmpty(pin2)) {            return 0;        }        boolean success = deleteIccRecordFromEf(efType, tag, number, emails, pin2, subId);        if (!success) {            return 0;        }        getContext().getContentResolver().notifyChange(url, null);        return 1;    }


5.通过内容观察者监听sim里联系人的改变

注册内容观察者

getContentResolver().registerContentObserver(uri, true,myContentObserver);
定义自己的内容观察者继承ContentObserver

private class myContentObserve extends ContentObserver {public myContentObserve(Handler handler) {super(handler);}@Overridepublic void onChange(boolean selfChange) {super.onChange(selfChange);Log.d(TAG, "数据库发生了改变。。。");}}

当不需要监听时,取消注册

if (myContentObserver != null) {getContentResolver().unregisterContentObserver(myContentObserver);}


当ContentProvider数据源发生改变后,如果想通知其监听对象, 例如ContentObserver时,必须在其对应方法 update / insert / delete时,显示的调用this.getContentReslover().notifychange(uri , null)方法,回调监听处理逻辑。否则,我们 的ContentObserver是不会监听到数据发生改变的,即onChange方法不会调用


另外,对sim卡联系人操作需要在清单文件中配置下面的权限

    <uses-permission android:name="android.permission.READ_CONTACTS"/>    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>

如果有需要的,可以 下载源码自己看看。





更多相关文章

  1. Android主题和样式系统篇(上)
  2. Android(安卓)2.1学习笔记(一)
  3. 秒懂Android注解处理器(Android(安卓)Annotation Processor)
  4. Android.自定义控件的实现
  5. Android学习笔记--Binder
  6. 自定义Seekbar拖动条式样
  7. android开发――获取手机联系人
  8. Binder框架 -- android AIDL 的使用
  9. [置顶] Android学习之lowmemorykiller driver

随机推荐

  1. android litepal(还是手写db的好用)
  2. Android画图demo
  3. android飞翔的小鸟……
  4. Android(安卓)studio自动下载第三方jar包
  5. android editText动态改变事件
  6. Android(安卓)各种音量的获取和设置
  7. Android 自定义AlertDialog 并且4个角为
  8. Android 自定义带百分比的进度条
  9. TextView实现中间文字两侧图片的样式 和
  10. android中的BaseAdapter使用