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

來源:互聯網
上載者:User

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

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

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

情況二 已在通訊錄的連絡人

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

 

 

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

需要的類

 

//建立電話對象

代碼一:

 

#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

 

程式啟動的情況下 來電/去電/接通/掛斷 都可以獲到了, 文章到此結束了, 敬請期待 對連絡人添加歸屬地, 修改連絡人操作部落格.....

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.