android中对sim卡联系人的增删改查以及监听sim卡联系数据的改变

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

具体对sim卡联系人的增删改查都是通过AIDL IIccPhoneBook调用完成对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 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);
		}

		@Override
		public 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值