這倆天學習了一下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 }
與聯系人相關的方法會在后續學習中繼續更新!!