这俩天学习了一下Android中如何查询通话记录及短信记录。在Android中这些信息都是通过Content Provider来进行存储和读取的。
1 Cursor cursor = this.parent.managedQuery(CallLog.Calls.CONTENT_URI, 2 new String["name","number","duration"], CallLog.Calls.DATE + " > " + l, null, null);
上述代码中"l"表示一个时间点,查询在"l"时间点之后的所有通话记录及通话时间。在通话记录中CallLog.Calls.DATE的数据类型是long,存放的是milliseconds since the epoch。
这里查询使用的Acitivity.managedQuery(),这个方法的好处是不用自己去管理Cursor,但是根据最新的API,在3.0以上的版本已经不建议采用该方法,有新的方法代替。另外查询还可以使用ContentResolver.query(),这个方法需要自己去手动调用close()方法,也可以再调用后使用Activity.startManagingCursor()交给
activity
管理。
managedQuery方法的第一个参数是Uri;
第二个参数 projection变量,返回的结果是该传入变量里所列举的字段名。如果该参数null则返回所有字段数据;
第三个参数 where 后的参数(不包括where和数值),返回符合这些参数的值的数据,要跟第四个参数结合使用;
第四个参数 where 后参数的值;
第五个参数 排序(不包括order by)
1 if (cursor.moveToNext()) { 2 do { 3 String strName = cursor 4 .getString(cursor.getColumnIndex("name")); 5 String strNumber = cursor.getString(cursor 6 .getColumnIndex("number")); 7 long lDuration = cursor.getLong(cursor 8 .getColumnIndex("duration")); 9 if (strName == null) { 10 strNumber = PhoneNumberUtils.formatNumber(strNumber); 11 } else { 12 strNumber = strName; 13 } 14 if ((strNumber == null) || (strNumber.equalsIgnoreCase("-1"))) { 15 strNumber = "Unknown"; 16 } 17 18 if (!hashMap.containsKey(strNumber)) { 19 hashMap.put(strNumber, Double.valueOf(lDuration)); 20 } else { 21 hashMap.put( 22 strNumber, 23 Double.valueOf(lDuration 24 + ((Double) hashMap.get(strNumber)) 25 .doubleValue())); 26 } 27 } while (cursor.moveToNext()); 28 }
查询到通话记录后,逐条取出通话记录,如果不存在"name"这个字段则用"number"来代替。累计查询到的记录中每个人的通话时长总和。如果需要区分拨出或者接入的,则查询一下type字段,并根据字段的值等于CallLog.Calls.OUTGOING_TYPE(拨出)、CallLog.Calls.INCOMING_TYPE(接入)来区分。
下面是一个统计当月与每个人收发短信的条数(收件箱及发件箱中存在的用户):
1 Uri inboxUri = Uri.parse("content://sms/inbox"); //收件箱Uri 2 Uri sentUri = Uri.parse("content://sms/sent"); //发件箱Uri 3 Cursor[] cursor = new Cursor[2]; 4 cursor[0] = this.parent.managedQuery(inboxUri, null, "date > " + l, // l表示这个月的1号的0点,查询这个月的收件箱的短信信息 5 null, null); 6 cursor[1] = this.parent.managedQuery((Uri) sentUri, null, 7 "date > " + l, null, null); 8 for (int i = 0; i < cursor.length; i++) { 9 if (!cursor[i].moveToNext()) 10 continue; 11 do { 12 String strAddress = cursor[i].getString(cursor[i] 13 .getColumnIndex("address")); 14 String str; 15 if (!hashMapTemp.containsKey(strAddress)) {//如果这个用户在不存在则先查询下是否可以关联到姓名 16 str = lookupNumber(strAddress); //根据号码查询到联系人中查询用户姓名 17 hashMapTemp.put(strAddress, str); 18 } else {//已经存在的用户 19 str = (String) (hashMapTemp).get(strAddress); 20 } 21 if (!hashMap.containsKey(str)) {//不存在用户加入,并且数量为一 22 Double d1 = Double.valueOf(1.0D); 23 hashMap.put(str, d1); 24 } else {//已存在的用户在之前的数量基础上+1 25 Double d2 = Double.valueOf(1.0D + ((Double) hashMap 26 .get(str)).doubleValue()); 27 hashMap.put(str, d2); 28 } 29 } while (cursor[i].moveToNext()); 30 }
根据号码查询联系人姓名,根据测试下述方法是可以查询到手机及SIM卡中的联系人信息的(2.2的系统中):
1 private String lookupNumber(String address) { 2 String[] arrayOfString = new String[2]; 3 arrayOfString[0] = "_id"; 4 arrayOfString[1] = "person"; 5 // Cursor cursor = contentResolver.query(phoneUri, arrayOfString, null, 6 // null, null); 7 // 根据号码获取ID 8 Cursor cursor = this.parent.managedQuery( //根据号码查询ID 9 ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 10 ContactsContract.CommonDataKinds.Phone.NUMBER + " = ?", 11 new String[] { address }, null); 12 if (cursor.moveToFirst()) { 13 String strId = cursor 14 .getString(cursor 15 .getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)); 16 // 根据ID获取用户名称 17 Cursor cursorDisplayName = this.parent.managedQuery( // 如果存在该号码,则根据ID在联系人表中查询姓名 18 ContactsContract.Contacts.CONTENT_URI, null, 19 ContactsContract.Contacts._ID + " = ? ", 20 new String[] { strId }, null); 21 if (cursorDisplayName.moveToFirst()) { 22 // 返回用户名称 23 return cursorDisplayName 24 .getString(cursorDisplayName 25 .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 26 } 27 } else if (address.startsWith("+86")) { // 获取的号码为+86开头的,在联系人中有些号码没有存+86的前缀,则需要过滤+86后重新查找 28 String temp = address.substring(3); 29 Cursor cursor1 = this.parent.managedQuery( 30 ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 31 ContactsContract.CommonDataKinds.Phone.NUMBER + " = ?", 32 new String[] { temp }, null); 33 if (cursor1.moveToFirst()) { 34 String strId = cursor1 35 .getString(cursor1 36 .getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)); 37 // 根据ID获取用户名称 38 Cursor cursorDisplayName1 = this.parent.managedQuery( 39 ContactsContract.Contacts.CONTENT_URI, null, 40 ContactsContract.Contacts._ID + " = ? ", 41 new String[] { strId }, null); 42 if (cursorDisplayName1.moveToFirst()) { 43 // 返回用户名称 44 return cursorDisplayName1 45 .getString(cursorDisplayName1 46 .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 47 } 48 } 49 } 50 return address; 51 }
与联系人相关的方法会在后续学习中继续更新!!