IOS获取来电去电来电归属系统通知达到效果(一)

2023-10-19 08:30

本文主要是介绍IOS获取来电去电来电归属系统通知达到效果(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

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



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


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

须要的类



//创建电话对象

代码一: 

#import <Foundation/Foundation.h>

@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 <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];

    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] = '\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: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 <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获取来电去电来电归属系统通知达到效果(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/238598

相关文章

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

linux系统中java的cacerts的优先级详解

《linux系统中java的cacerts的优先级详解》文章讲解了Java信任库(cacerts)的优先级与管理方式,指出JDK自带的cacerts默认优先级更高,系统级cacerts需手动同步或显式... 目录Java 默认使用哪个?如何检查当前使用的信任库?简要了解Java的信任库总结了解 Java 信

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

C#使用iText获取PDF的trailer数据的代码示例

《C#使用iText获取PDF的trailer数据的代码示例》开发程序debug的时候,看到了PDF有个trailer数据,挺有意思,于是考虑用代码把它读出来,那么就用到我们常用的iText框架了,所... 目录引言iText 核心概念C# 代码示例步骤 1: 确保已安装 iText步骤 2: C# 代码程

Oracle数据库在windows系统上重启步骤

《Oracle数据库在windows系统上重启步骤》有时候在服务中重启了oracle之后,数据库并不能正常访问,下面:本文主要介绍Oracle数据库在windows系统上重启的相关资料,文中通过代... oracle数据库在Windows上重启的方法我这里是使用oracle自带的sqlplus工具实现的方

Spring Boot中获取IOC容器的多种方式

《SpringBoot中获取IOC容器的多种方式》本文主要介绍了SpringBoot中获取IOC容器的多种方式,包括直接注入、实现ApplicationContextAware接口、通过Spring... 目录1. 直接注入ApplicationContext2. 实现ApplicationContextA

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下