使用CoreTelephony框架.
使用框架中的CTCallCenter和CTCall两个类可以得到目前iPhone是否在通话中.
通过调用方法
- (NSString *)currentCallState
{
callCenter = [[CTCallCenter alloc] init];
for (CTCall *call in callCenter.currentCalls) {
return call.callState;
}
return nil;
}
{
callCenter = [[CTCallCenter alloc] init];
for (CTCall *call in callCenter.currentCalls) {
return call.callState;
}
return nil;
}
可以获取当前的手机的通话状态,CTCall可以监测到四种状态.分别是
CTCallStateDialing // 拨出电话
CTCallStateIncoming // 电话打入
CTCallStateConnected // 通话开始
CTCallStateDisconnected // 通话结束
获取当前手机的网络类型,使用CTTelephonyNetworkInfo类的currentRadioAccessTechnology 属性
/*
* currentRadioAccessTechnology
*
* Discussion:
* The current radio access technology the device is registered with. May be NULL
* if device is not registered on any network.
*/
@property (nonatomic, readonly, retain) NSString* currentRadioAccessTechnology __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
* currentRadioAccessTechnology
*
* Discussion:
* The current radio access technology the device is registered with. May be NULL
* if device is not registered on any network.
*/
@property (nonatomic, readonly, retain) NSString* currentRadioAccessTechnology __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
值包括
CTTelephonyNetworkInfo.currentRadioAccessTechnology
Added CTRadioAccessTechnologyCDMA1x
Added CTRadioAccessTechnologyCDMAEVDORev0
Added CTRadioAccessTechnologyCDMAEVDORevA
Added CTRadioAccessTechnologyCDMAEVDORevB
Added CTRadioAccessTechnologyEdge
Added CTRadioAccessTechnologyGPRS
Added CTRadioAccessTechnologyHSDPA
Added CTRadioAccessTechnologyHSUPA
Added CTRadioAccessTechnologyLTE
Added CTRadioAccessTechnologyWCDMA
Added CTRadioAccessTechnologyeHRPD
监测蜂窝网络类型的变化,不用项目中写的那么复杂,只需要注册这个通知即可收到网络类型的变化
CTRadioAccessTechnologyDidChangeNotification (ios7才有的)
重新写了一个Demo
发现,注册这个通知,首先需要导入
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
@interface ViewController ()
@property (nonatomic, retain)CTTelephonyNetworkInfo *info;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
@property (nonatomic, retain)CTTelephonyNetworkInfo *info;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CTTelephonyNetworkInfo *info
= [[CTTelephonyNetworkInfo alloc]init];
[[NSNotificationCenter defaultCenter] addObserverForName:CTRadioAccessTechnologyDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note)
{
NSLog(@"---%s----,-----%d------,%@",__FUNCTION__,__LINE__,note.object);
NSLog(@"---%s----,-----%d------,%@",__FUNCTION__,__LINE__,note.object);
}
}
如果使用了局部变量,像上面那样用带block的通知,block里面的方法是不会执行的. 因为局部变量在某个地方被release了,这个错误和定位功能使用局部变量定义CLLocationManager如出一辙,代理方法不执行.这种错误容易出现在ARC环境下.因为ARC是Xcode根据情况隐式添加release方法,block语句和代理方法都不是立即执行的,等到执行的时候,info对象可能已经被release了.Xcode编译时,看到后面没有用到info对象,以为不需要了,所以就把它release掉了,MRC应该不会出现类似情况.
当然如果用了局部变量,在block里面这样用就不会有问题了
NSLog(@"---%s----,-----%d------,%@",__FUNCTION__,__LINE__,info.currentRadioAccessTechnology);
因为后面还用到了info对象,所以Xcode还不敢release.
如果使用通知的这个方法就必须要用实例变量了,所以用note.object是可以收到通知的
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveChange:) name:CTRadioAccessTechnologyDidChangeNotification object:nil];
- (void)receiveChange:(NSNotification *)note
{
{
NSLog(@"---%s----,-----%d------,%@",__FUNCTION__,__LINE__,note.object);
}
}
CTRadioAccessTechnologyDidChangeNotification是CTTelephonyNetworkInfo的一个外部变量,但是必须要有CTTelephonyNetworkInfo 对象才可以.具体为什么,还不太清楚.