你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> IOS獲取來電去電系統通知達到來電歸屬地效果(一)

IOS獲取來電去電系統通知達到來電歸屬地效果(一)

編輯:IOS開發綜合

這裡的實現原理是獲取到來電系統通知,然後根據本地通話的電話號碼,把對應電話的聯系人.

情況一 來電號碼未在通訊錄聯系人中, 這時候要先在通訊錄添加一個臨時的聯系人(就是新建一個聯系人,並保存對應的RecordID)

情況二 已在通訊錄的聯系人

然後 把對應本次通話的電話標簽修改成歸屬地字符

 

 

好了 ,先看看怎麼獲取系統電話通知

需要的類

height=110

 

//創建電話對象

代碼一:

 

#import

@import CoreTelephony;

 

// private API

typedef NS_ENUM(short, CTCallStatus) {

kCTCallStatusConnected = 1, //已接通

kCTCallStatusCallOut = 3, //撥出去

kCTCallStatusCallIn = 4, //打進來

kCTCallStatusHungUp = 5 //掛斷

};

 

@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

#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 引用 這個框架


 

/**

 

- (NSString *)wcRot13

{

const char *source = [selfcStringUsingEncoding:NSASCIIStringEncoding];

char *dest = (char *)malloc((self.length +1) * sizeof(char));

if (!dest) {

return nil;

}

 

NSUInteger i = 0;

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

char c = source[i];

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

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

}

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

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

}

dest[i] = c;

}

dest[i] = '';

 

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:rot13options:0]; // 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

@interface WCCallInspector : NSObject

 

+ (instancetype)sharedInspector;

- (void)startInspect;//啟動 O(∩_∩)O~~

 

@end


代碼六:

#import WCCallInspector.h

#import WCCallCenter.h

#import

 

@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

 

程序啟動的情況下 來電/去電/接通/掛斷 都可以獲到了, 文章到此結束了, 敬請期待 對聯系人添加歸屬地, 修改聯系人操作博客.....

 

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved