ios5实现访问通话记录(需越狱)

ios5的通话记录都保存在一个sqlite db文件中:

可以用下面代码测试,能否访问到对应的db:

-(IBAction)checkDBClick:(id)sender{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDirectoryEnumerator *dirnum = [[NSFileManager defaultManager] enumeratorAtPath: @"/private/"];
NSString *nextItem = [NSString string];
NSUInteger pos = 0;
uTextView.text = @"checkDBClick";
while( (nextItem = [dirnum nextObject])) {
if ([[nextItem pathExtension] isEqualToString: @"db"] ||
[[nextItem pathExtension] isEqualToString: @"sqlitedb"]) {
if ([fileManager isReadableFileAtPath:nextItem]) {
NSLog(@"%@", nextItem);
pos++;
NSString * tmp = [[NSString alloc] initWithFormat:@"%@ next(%d):%@",uTextView.text,pos,nextItem];
uTextView.text = tmp;

[tmp release];
}
}
}
}

 

ios5中,位于目录: /private/var/wireless/Library/CallHistory/call_history.db 下。由于ios5以后,所有程序运行在沙盒下,仅能访问程序自己的目录,以及有限的几个目录,故,在不越狱的情况下,是访问不到对应的数据的。程序中用到的telocation.db,来电归属地数据库,请直接google得到。
PS:有谁能在不越狱的基础上,利用私有API或者其他方式获取到手机号的话,麻烦email我一下方法,多谢~~~
假定已经获得了手机号码,可通过下述代码获取,并得到对应的归属地:


-(NSString *)getPhoneNumberLocation: (NSString * )phoneNum{
//call area

NSString *teLocationDatabasePath = [[NSString alloc] initWithFormat:@"%@/%@",[[NSBundle mainBundle] resourcePath], @"telocation.db"];
BOOL dbFileExist = FALSE;
NSMutableString * area = [[[NSMutableString alloc] autorelease] initWithString:@""];

NSFileManager *fileManager = [NSFileManager defaultManager];
dbFileExist = [fileManager fileExistsAtPath:teLocationDatabasePath];
[fileManager release];

NSLog(@"teLocationDatabasePath:%@",teLocationDatabasePath);

if(dbFileExist) {
if ([fileManager isReadableFileAtPath:teLocationDatabasePath]) {
sqlite3 *database;
if(sqlite3_open([teLocationDatabasePath UTF8String], &database) == SQLITE_OK) {
sqlite3_stmt *compiledStatement;
NSString *sqlStatement = [NSString stringWithFormat:@"SELECT * FROM mob_location WHERE _id='%@';",[phoneNum substringToIndex:7]];
NSLog(@"sql:%@",sqlStatement);


int errorCode = sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1,
&compiledStatement, NULL);
if( errorCode == SQLITE_OK) {
int count = 1;

while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
int numberOfColumns = sqlite3_column_count(compiledStatement);
NSString *data;
NSString *columnName;

for (int i = 0; i < numberOfColumns; i++) {
columnName = [[NSString alloc] initWithUTF8String:
(char *)sqlite3_column_name(compiledStatement, i)];
data = [[NSString alloc] initWithUTF8String:
(char *)sqlite3_column_text(compiledStatement, i)];



if ([columnName isEqualToString:@"location"]) {
[area appendString:data];

NSLog(@"%d:%@=>%@",count,columnName,data);
}
[columnName release];
[data release];
}
count++;
}

}
else {
NSLog(@"Failed to retrieve table");
NSLog(@"Error Code: %d", errorCode);
}
sqlite3_finalize(compiledStatement);
}
}

}
[teLocationDatabasePath release];
NSLog(@"area:%@",area);
return area;
}

-(IBAction)getInfoClick:(id)sender{

#define DB_FILE [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"call_history.db"]

NSLog(@"getInfoClick:%@",DB_FILE);
uTextView.text = @"getInfoClick:";

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *callHisoryDatabasePath = DB_FILE;//@"/private/var/wireless/Library/CallHistory/call_history.db";
BOOL callHistoryFileExist = FALSE;
callHistoryFileExist = [fileManager fileExistsAtPath:callHisoryDatabasePath];
// [fileManager release];
NSMutableArray *callHistory = [[NSMutableArray alloc] init];


if(callHistoryFileExist) {
NSLog(@"path is exists...");
if ([fileManager isReadableFileAtPath:callHisoryDatabasePath]) {
NSLog(@"path can read...");
sqlite3 *database;
if(sqlite3_open([callHisoryDatabasePath UTF8String], &database) == SQLITE_OK) {
sqlite3_stmt *compiledStatement;
NSString *sqlStatement = [NSString stringWithString:@"SELECT * FROM call;"];

int errorCode = sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1,
&compiledStatement, NULL);
if( errorCode == SQLITE_OK) {
int count = 1;

while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSMutableDictionary *callHistoryItem = [[NSMutableDictionary alloc] init];
int numberOfColumns = sqlite3_column_count(compiledStatement);
NSString *data;
NSString *columnName;

for (int i = 0; i < numberOfColumns; i++) {
columnName = [[NSString alloc] initWithUTF8String:
(char *)sqlite3_column_name(compiledStatement, i)];
data = [[NSString alloc] initWithUTF8String:
(char *)sqlite3_column_text(compiledStatement, i)];


if (![columnName isEqualToString:@"date"]) {
[callHistoryItem setObject:data forKey:columnName];
}
else {

NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"H"]];
NSDate *currentDate = [NSDate dateWithTimeIntervalSince1970:[data intValue]];

[callHistoryItem setObject: [dateFormatter stringFromDate:currentDate] forKey:columnName];

}


if ([columnName isEqualToString:@"address"]) {
[callHistoryItem setObject:[self getPhoneNumberLocation:data] forKey:@"area" ];

}

//[callHistoryItem setObject:data forKey:columnName];

[columnName release];
[data release];
}
[callHistory addObject:callHistoryItem];
[callHistoryItem release];
count++;
}//end while
NSMutableString * tmp = [[NSMutableString alloc] initWithString:uTextView.text];
for (NSUInteger i=0; i //NSLog(@"%d:%@",i,[callHistory objectAtIndex:i]);
NSMutableDictionary * data = [callHistory objectAtIndex:i];
[tmp appendFormat:@"%d:%@=>%@ ",i,[data objectForKey:@"address"],[data objectForKey:@"area"]];
}

uTextView.text = tmp;
[tmp release];

}
else {
NSLog(@"Failed to retrieve table");
NSLog(@"Error Code: %d", errorCode);
}
sqlite3_finalize(compiledStatement);
}
}

}



}

已有1条评论

  1. richardhc 2012-06-29 15:44 回复
    测试下 IntenseDebate 评论系统,感觉不错~
| 1个评论