这里的原理是获得到呼叫系统通知,然后根据本地呼叫电话号码,相应的电话联系.

一世。   来电显示是不是在地址簿中的联系人, 这是当第一个加入一个临时的联系人在您的电话簿(它是创建一个新的接触,并保存相应的RecordID)

情况二  已在通讯录的联系人

然后 把相应本次通话的电话标签改动成归属地字符

原文地址    http://blog.csdn.net/leewolf130/article/details/38921921

好了 ,先看看怎么获取系统电话通知

须要的类

//创建电话对象

代码一:

#import <Foundation/Foundation.h>

@import CoreTelephony;

// private API

typedef NS_ENUM(short, CTCallStatus) {

kCTCallStatusConnected = ,
//已接通

kCTCallStatusCallOut = ,
//拨出去

kCTCallStatusCallIn = ,
//打进来

kCTCallStatusHungUp =
//挂断

};

@interface WCCall :
NSObject

@property (nonatomic,assign)
CTCallStatus callStatus;

@property (nonatomic,copy)
NSString *phoneNumber;

@property (nonatomic,retain)
CTCall *internalCall;

@end




代码二: 

#import "WCCall.h"

@implementation WCCall

@end

//监听电话通知

代码三:

#import <Foundation/Foundation.h>

#import "WCCall.h"

@interface WCCallCenter :
NSObject

// 监听来电事件

@property (nonatomic,strong)
void (^callEventHandler)(WCCall *call);

// 挂断电话

- (void)disconnectCall:(WCCall *)call;

@end

代码四:

#import "WCCallCenter.h"

#import "WCUtil.h"

// encrypted string's

#define ENCSTR_kCTCallStatusChangeNotification  [@"n0AHD2SfoSA0LKE1p0AbLJ5aMH5iqTyznJAuqTyiot==" wcDecryptString]

#define ENCSTR_kCTCall                          [@"n0AHD2SfoN==" wcDecryptString]

#define ENCSTR_kCTCallStatus                    [@"n0AHD2SfoSA0LKE1pj==" wcDecryptString]

#define ENCSTR_CTTelephonyCenterGetDefault      [@"D1EHMJkypTuioayQMJ50MKWUMKERMJMuqJk0" wcDecryptString]

#define ENCSTR_CTTelephonyCenterAddObserver     [@"D1EHMJkypTuioayQMJ50MKWOMTECLaAypaMypt==" wcDecryptString]

#define ENCSTR_CTTelephonyCenterRemoveObserver  [@"D1EHMJkypTuioayQMJ50MKWFMJ1iqzICLaAypaMypt==" wcDecryptString]

#define ENCSTR_CTCallCopyAddress                [@"D1EQLJkfD29jrHSxMUWyp3Z=" wcDecryptString]

#define ENCSTR_CTCallDisconnect                 [@"D1EQLJkfETymL29hozIwqN==" wcDecryptString]

//这里须要对字符串 NSString 进行拓展方法

//#import <dlfcn.h> 引用 这个框架


/**

- (NSString *)wcRot13

{

const char *source = [selfcStringUsingEncoding:NSASCIIStringEncoding];

)
* sizeof(char));

if (!dest) {

return nil;

}

;

for ( ; i < self.length; i++) {

char c = source[i];

if (c >= 'A' && c <='Z') {

c = (c - ) % +
'A';

}

else if (c >='a' && c <=
'z') {

c = (c - ) % +
'a';

}

dest[i] = c;

}

dest[i] = '\0';

NSString *result = [[NSStringalloc]
initWithCString:destencoding:NSASCIIStringEncoding];

free(dest);

return result;

}

- (NSString *)wcDecryptString

{

NSString *rot13 = [selfwcRot13];

NSData *data;

if ([NSDatainstancesRespondToSelector:@selector(initWithBase64EncodedString:options:)]) {

data = [[NSDataalloc]
initWithBase64EncodedString]; // iOS 7+

} else {

data = [[NSData
alloc] initWithBase64Encoding:rot13];                          // pre iOS7

}

return [[NSStringalloc]
initWithData:dataencoding:NSUTF8StringEncoding];

}

**/

// private API

//extern NSString *CTCallCopyAddress(void*, CTCall *);

typedef NSString *(*PF_CTCallCopyAddress)(void*,CTCall *);

//extern void CTCallDisconnect(CTCall *);

typedef void (*PF_CTCallDisconnect)(CTCall *);

//extern CFNotificationCenterRef CTTelephonyCenterGetDefault();

typedef CFNotificationCenterRef (*PF_CTTelephonyCenterGetDefault)();

typedef void (*PF_CTTelephonyCenterAddObserver)(CFNotificationCenterRef center,

constvoid *observer,

CFNotificationCallback callBack,

CFStringRef name,

constvoid *object,

CFNotificationSuspensionBehavior suspensionBehavior);

typedef void (*PF_CTTelephonyCenterRemoveObserver)(CFNotificationCenterRef center,

constvoid *observer,

CFStringRef name,

constvoid *object);

@interface
WCCallCenter ()

- (void)handleCall:(CTCall *)call withStatus:(CTCallStatus)status;

@end

@implementation WCCallCenter

- (id)init

{

self = [superinit];

if (self) {

[selfregisterCallHandler];

}

return
self;

}

- (void)dealloc

{

[selfderegisterCallHandler];

}

- (void)registerCallHandler

{

staticPF_CTTelephonyCenterAddObserver AddObserver;

staticPF_CTTelephonyCenterGetDefault GetCenter;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

AddObserver = [WCDLloadSymbol:ENCSTR_CTTelephonyCenterAddObserver];

GetCenter = [WCDLloadSymbol:ENCSTR_CTTelephonyCenterGetDefault];

});

AddObserver(GetCenter(),

(__bridge
void *)self,

&callHandler,

(__bridgeCFStringRef)(ENCSTR_kCTCallStatusChangeNotification),

NULL,

CFNotificationSuspensionBehaviorHold);

}

- (void)deregisterCallHandler

{

staticPF_CTTelephonyCenterRemoveObserver RemoveObserver;

staticPF_CTTelephonyCenterGetDefault GetCenter;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

RemoveObserver = [WCDLloadSymbol:ENCSTR_CTTelephonyCenterRemoveObserver];

GetCenter = [WCDLloadSymbol:ENCSTR_CTTelephonyCenterGetDefault];

});

RemoveObserver(GetCenter(),

(__bridge
void *)self,

(__bridgeCFStringRef)(ENCSTR_kCTCallStatusChangeNotification),

NULL);

}

- (void)handleCall:(CTCall *)call withStatus:(CTCallStatus)status

{

staticPF_CTCallCopyAddress CopyAddress;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

CopyAddress = [WCDL
loadSymbol:ENCSTR_CTCallCopyAddress];

});

if (!self.callEventHandler || !call) {

return;

}

WCCall *wcCall = [[WCCallalloc]
init];

wcCall.phoneNumber = CopyAddress(NULL, call);

wcCall.phoneNumber = wcCall.phoneNumber;

wcCall.callStatus = status;

wcCall.internalCall = call;

self.callEventHandler(wcCall);

}

static void callHandler(CFNotificationCenterRef center,

void *observer,

CFStringRef name,

const
void *object,

CFDictionaryRef userInfo)

{

if (!observer) {

return;

}

NSDictionary *info = (__bridgeNSDictionary *)(userInfo);

CTCall *call = (CTCall *)info[ENCSTR_kCTCall];

CTCallStatus status = (CTCallStatus)[info[ENCSTR_kCTCallStatus]shortValue];

if ([[calldescription]
rangeOfString:@"status = 196608"].location==NSNotFound)
{

//这里之后就是你对归属地信息的操作了

WCCallCenter *wcCenter = (__bridgeWCCallCenter*)observer;

[wcCenter handleCall:call
withStatus:status];

}

}

- (void)disconnectCall:(WCCall *)call

{

staticPF_CTCallDisconnect Disconnect;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

Disconnect = [WCDL
loadSymbol:ENCSTR_CTCallDisconnect];

});

CTCall *ctCall = call.internalCall;

if (!ctCall) {

return;

}

Disconnect(ctCall);

}

@end

//处理本地通话的一些操作

代码五:

#import <Foundation/Foundation.h>

@interface WCCallInspector :
NSObject

+ (instancetype)sharedInspector;

- (void)startInspect;//启动 O(∩_∩)O~~

@end

代码六:

#import "WCCallInspector.h"

#import "WCCallCenter.h"

#import <AudioToolbox/AudioToolbox.h>

@interface
WCCallInspector ()

@property (nonatomic,strong)
WCCallCenter *callCenter;

@end

@implementation WCCallInspector

+ (instancetype)sharedInspector

{

static WCCallInspector *instance;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

instance = [[WCCallInspector
alloc] init];

});

return instance;

}

- (id)init

{

self = [superinit];

if (self) {

}

return
self;

}

#pragma mark - Call Inspection

- (void)startInspect

{

if (self.callCenter) {

return;

}

self.callCenter = [[WCCallCenteralloc]
init];

__weak WCCallInspector *weakSelf =self;

self.callCenter.callEventHandler = ^(WCCall
*call) {

[weakSelf handleCallEvent:call];

};

}

#pragma mark 呼出,呼入,接通,挂断

- (void)handleCallEvent:(WCCall *)call{

//这里 想怎么操作 依据自己情况而定啊......

//能够打印call的属性看看结果

//    kCTCallStatusConnected = 1, //已接通

//    kCTCallStatusCallOut = 3, //拨出去

//    kCTCallStatusCallIn = 4, //打进来

//    kCTCallStatusHungUp = 5 //挂断

}


//startInspect//这种方法须要在程序启动时候注冊

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

/**

* Your Code

**/

[[WCCallInspectorsharedInspector]
startInspect];

return
YES;

}

//引用这个类库

#import <AudioToolbox/AudioToolbox.h>

转载请标明 原文地址    http://blog.csdn.net/leewolf130/article/details/38921921

当程序启动    来电/传出/接通/挂断    能够获得的,  这样就完成了文章, 敬请关注  添加联系人归属, 联系方式变更的操作博客.....

IOS获取来电去电来电归属系统通知达到效果(一)的更多相关文章

  1. android135 360 来电去电归属地显示,自定义toast,

    点击会开启服务. sivAddress.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) ...

  2. ANDROID 通过监听来电去电,并弹出悬浮窗

    要监听android打电话和接电话,有一种的是通过新建一个Receiver继承自BroadcastReceiver. 还有一种也可通过PhoneStateListener来实现.今天就说说后面一种,废 ...

  3. Android MTK平台 客制化系统来电界面(屏蔽 InCallUI 提供接口给客户自行展示来电去电页面)

    OS: Android 8.1 需求分析 1.禁止系统来电铃声,提供接口给客户自己播放铃声 2.禁止系统拉起来去电页面(InCallActivity),消息通知客户拉起自己的来去电页面 3.禁止来电消 ...

  4. iOS获取设备唯一标识的8种方法

    8种iOS获取设备唯一标识的方法,希望对大家有用. UDID UDID(Unique Device Identifier),iOS 设备的唯一识别码,是一个40位十六进制序列(越狱的设备通过某些工具可 ...

  5. iOS 获取文件的目录路径的几种方法 [转]

    iOS 获取文件的目录路径的几种方法 2 years ago davidzhang iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么. d ...

  6. iOS获取设备型号、装置类型等信息

    iOS获取设备型号.设备类型等信息 设备标识 关于设备标识,历史上盛行过很多英雄,比如UDID.Mac地址.OpenUDID等,然而他们都陆陆续续倒在了苹果的门下.苹果目前提供了2个方法供App获取设 ...

  7. Swift3.0 iOS获取当前时间 - 年月日时分秒星期

    Swift3.0 iOS获取当前时间 - 年月日时分秒星期func getTimes() -> [Int] { var timers: [Int] = [] // 返回的数组 let calen ...

  8. IOS 获取最新设备型号方法

    1.IOS 获取最新设备型号方法列表最新对照表:http://theiphonewiki.com/wiki/Models方法: #import "sys/utsname.h” struct ...

  9. ios 获取通讯录的所有信息

    iOS获取通讯录全部信息 ABAddressBookRef addressBook = ABAddressBookCreate(); CFArrayRef results = ABAddressBoo ...

随机推荐

  1. HDU 4544 湫湫系列故事――消灭兔子

    HDU 4544 Tags: 数据结构,贪心 Analysis: 将兔子的血量从大到小排序,将箭的杀伤力从大到小排序,对于每一个兔子血量, 将比他大的杀伤力大的剑压入优先队列,优先队列自己重写,让它每 ...

  2. UML建模技术(资料汇总)

    其实,我是非常不喜欢,<深入浅出XXX>.<初级入门XXX>,<21天学会XXX>. ... .and so on , 之类的东西的. 好吧,只是得承认,有些还是不 ...

  3. 解决java mail发送TXT附件被直接显示在正文中的问题

    这两天遇到一个问题,关于使用java mail发送邮件的问题. 详细是这样子的:我使用java mail发送异常报告邮件,邮件中有一个包含异常日志的附件,和关于设备信息的邮件正文.假设日志为log后缀 ...

  4. 用spring-data-redis实现类似twitter的网站(转)

    1. spring-data-redis简介 封装了一下redis的客户端,使得使用起来更方便. 优点是把客户端连接放到一个连接池里,从而提高性能.还有就是可以不同的客户端之间实现切换,而不用改一行代 ...

  5. 基于visual Studio2013解决C语言竞赛题之1060寻找回文数

       题目 解决代码及点评 /* 60. 回文数指左右数字对称的数,如121,2112都是回文数.回文数猜想:取一任意十进制数,将其倒过来,并将这两个数相加, 然后把这个相加的和倒过来再与 ...

  6. hdu1298 T9(手机输入法,每按一个数字,找出出现频率最高的字串,字典树+DFS)

    Problem Description A while ago it was quite cumbersome to create a message for the Short Message Se ...

  7. 原始的js代码和jquery对比

    Even a task as simple as this can be complicated without jQuery at our disposal. In plain JavaScript ...

  8. Metasploit学习之msf连接数据库

    kali使用metasploit开启数据服务: 首先,初次使用系统要初始化建立数据库msf3, 否则的话 /opt/metasploit/apps/pro/ui/config/databse.yml不 ...

  9. 基于visual Studio2013解决面试题之0207单词翻转

     题目

  10. HDU 5045(Contest-费用流)[template:费用流]

    Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submi ...