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“和“=”进行切割来实现的,具体代码如下

    @Overridepublic 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 clauseString 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"/>

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

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

  1. Android中数据库的一些操作(增删改查)

    提起Android的开发,就不得不提数据库,几乎每个App中都会用到Sqlit数据库存储一些数据,小编闲暇时期,写了一个小demo关于数据库的增删改查,之前也介绍过数据库的一个开源框架ORMLite, ...

  2. android sim卡联系人存储格式,Android SIM卡联系人的增删改查操作

    手机在存储联系人时支持存储到手机或者sim卡,本文主要讲述Android的sim卡中联系人是如何操作的. 1.权限 由于操作联系人的信息,所以联系人的读取和写入是必不可少的. 2.URI URI的创建 ...

  3. WEB阶段7:综合练习-联系人管理系统-增删改查查询分页

    综合练习-联系人管理系统-增删改查&查询分页 回顾 能够说出过滤器的作用 解决全局乱码问题 用户权限访问控制 用户输入文本内容进行过滤 能够编写过滤器 创建一个类实现javax.servlet ...

  4. 对联系人进行增删改查

    我已经将联系人操作的方法进行了封装,暴露了几个重要的方法,方便以后调用. 1. public void printContactsList() // 获取到的联系人列表(用于测试用) 2. publi ...

  5. Android整合SQLite数据库进行基本的增删改查

    简言 使用Android整合SQLite数据库进行数据存储,大致可以划分为三步: ①继承 SQLiteOpenHelper,创建数据库 ②继承 ContentProvider 类,重写方法 ③在清单文 ...

  6. Android本地文件管理器思路解析一一增删改查具体实现

    花了一天的时间撸完了Android本地文件管理器~!!GitHub下载地址为:PumpkinFileManager 南瓜文件管理器1.0. 功能列表: 1: 实现了在ListView中浏览本地所有文件 ...

  7. Mybatis中使用Dao实现类实现增删改查【实际开发中使用代理dao】

    在Mybatis开发中,使用到的是代理Dao的方式实现增删改查,这样就不需要在写Dao的实现类 但是Mybatis也支持写Dao实现类!即DaoImpl 直接上DaoImpl,之前的代码可以参考前面几 ...

  8. mongodb windows的安装方法和添加到任务管理器中、检测是否成功、增删改查命令...

    转: mongodb安装方法: https://blog.csdn.net/heshushun/article/details/77776706        mongodb检测安装成功 .以及增删改 ...

  9. 华山论剑之iOS中(数组,字典,SQLite,CoreData)的“增删改查“

    我们的生活态度就应该是 "不抱怨" ! 其实我想写这篇文章很久了,因为自己做的iOS开发 ,对数据这一块有这极高的要求.所以一些必须的存储数据的使用,我们都有必要熟悉用法.在以前我 ...

最新文章

  1. 炸裂!MySQL 82 张图带你飞!
  2. Oracle-No.04 Oracle视图加主键解决hibernate复合主键问题
  3. python新手教程 从零开始-让你从零开始学会写爬虫的5个教程(Python)
  4. linux使用遇到的一些小问题
  5. SQL Server 学习笔记
  6. 20210928 A列满秩,那么A转置A一定可逆
  7. 【技术干货】TC基础与自动化
  8. n1进入recovery模式_oppo n1怎么进recovery
  9. Atitit 提升稳定性 错误处理 全局错误捕获 1.2. 可以uncaughtException来全局捕获未捕获的Error, 使用uncaughtException 2 1.2.1. 使用 t
  10. 406.根据身高重建队列
  11. STKX组件技术在星地链路中的仿真模式研究
  12. 双路服务器装mac系统,华硕Z10 C612,双路E5继续折腾调试改机型Macpro终于成功。...
  13. 框架 day32 Hibernate,一级缓存,关联关系映射(一对多,多对多)
  14. python个数计算公式_使用python中的公式计算第n个斐波纳契数
  15. java mongodb开发_Java 操作 MongoDB
  16. Win10升级后C盘莫名其妙满了怎么办
  17. 一生的读书计划——影响中国历史进程的中国名人2
  18. 响应式网页教程_如何响应式思考:响应式网页设计教程
  19. SAS中的informat和input
  20. 【黑帽SEO大神揭秘】快速排名的黑帽技术有哪些?

热门文章

  1. 2022年武汉建设厅七大员(建筑八大员)报名考试介绍,甘建二
  2. 在Unity中通过ScrollView实现背包物品展示后如何与指定背包物品的数据进行交互
  3. .net 鼠标移入弹出页面_jq: 事件-鼠标
  4. Vue build打包之后,刷新页面出现404解决方案
  5. 名字真好听的五子棋——15周进度
  6. 【黑科技】钉钉自动打卡
  7. 家庭自建流媒体服务器,如何创建自己的“家庭媒体流服务器”使用Plex与FreeNAS - 第3部分...
  8. Python编程基础(老男孩)——第三章 数据类型
  9. 西电A测|基于Arduino uno的温度检测控制仿真系统
  10. 如何对付团队中的“害群之马”