IOS 获取设备相关特性
来源:互联网 发布:js内置对象有哪些 编辑:程序博客网 时间:2024/06/15 16:04
IOS 获取设备相关特性
一、 判断手机是否插入了SIM卡
解答:
A. 私有 API 检测
[CTSIMSupportGetSIMStatus()isEqualToString:kCTSIMSupportSIMStatusNotInserted]可以判断是否插入了 sim卡。
前提是把下面的代码随便复制到一个头文件里面,然后引入CoreTelephony.framework即可。
1 extern NSString* c*****tkCTSMSMessageReceivedNotification;
2
3 extern NSString* c*****tkCTSMSMessageReplaceReceivedNotification;
4
5 extern NSString* c*****tkCTSIMSupportSIMStatusNotInserted;
6
7 extern NSString* c*****t kCTSIMSupportSIMStatusReady;
8
9
10 id CTTelephonyCenterGetDefault(void);
11
12 void CTTelephonyCenterAddObserver(id,id,CFNotificationCallback,NSString*,void*,int);
13
14 voidCTTelephonyCenterRemoveObserver(id,id,NSString*,void*);
15
16 int CTSMSMessageGetUnreadCount(void);
17
18 int CTSMSMessageGetRecordIdentifier(void * msg);
19
20 NSString * CTSIMSupportGetSIMStatus();
21
22 NSString * CTSIMSupportCopyMobileSubscriberIdentity();
23
24 id CTSMSMessageCreate(void* unknow,NSString*number,NSString* text);
25
26 void * CTSMSMessageCreateReply(void* unknow,void *forwardTo,NSString* text);
27
28 void* CTSMSMessageSend(id server,id msg);
29
30 NSString *CTSMSMessageCopyAddress(void *, void *);
31
32 NSString *CTSMSMessageCopyText(void *, void *);
B. 开放 API 检测(有待改进,飞行模式下检测不到)
1 -(BOOL)simExist {
2
3 CTTelephonyNetworkInfo *info =[[CTTelephonyNetworkInfo alloc] init];
4
5 CTCarrier *carrier = [info subscriberCellularProvider];
6
7 //NSString *code = [carriermobileNetworkCode];
8
9 NSString *isoCountryCode =[carrier isoCountryCode];
10
11 if (isoCountryCode == nil ||isoCountryCode.length == 0) {
12
13 NSLog(@"no sim");
14
15 return NO;
16 } else {
17
18 NSLog(@"sim exist");
19
20 return YES;
21 }
22 }
二、 获取更换 SIM卡后的通知(只有更换前后的 SIM 运营商不同才能收到)
解答:
1 //初始化
2 CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
3
4 //当sim卡更换时弹出此窗口
5 networkInfo.subscriberCellularProviderDidUpdateNotifier = ^(CTCarrier *carrier) {
6
7 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Sim card changed" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
8
9 [alert show];
10 };
三、 获取 SIM卡信息
解答:
1 //初始化
2 CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
3
4 //获取sim卡信息
5 CTCarrier *carrier = networkInfo.subscriberCellularProvider;
6
7 //供应商名称(中国联通 中国移动)
8 carrier.carrierName;
9
10 //所在国家编号
11 carrier.mobileCountryCode;
12
13 //供应商网络编号
14 carrier.mobileNetworkCode;
15
16 // iso国家编号
17 carrier.isoCountryCode;
18
19 //是否允许voip
20 carrier.allowsVOIP;
四、 判断锁屏状态
解答:
A. 私有 API 检测
1 #import <SpringBoard/SBAwayController.h>
2
3 //一句话搞定
4 if ([[objc_getClass("SBAwayController")sharedAwayController] isLocked]) {
5
6 PrintLog(@"doublecheck Home ,now YES Lock");
7 } else {
8
9 PrintLog(@"double check Home ,now NOLock");
10 }
B. 程序在前台,这种比较简单。直接使用Darwin层的通知就可以了
1 #import <notify.h>
2
3 #define NotificationLockCFSTR("com.apple.springboard.lockcomplete")
4 #define NotificationChangeCFSTR("com.apple.springboard.lockstate")
5 #define NotificationPwdUICFSTR("com.apple.springboard.hasBlankedScreen")
6
7
8 static voidscreenLockStateChanged(CFNotificationCenterRef center,void*observer,CFStringRef name,const void* object,CFDictionaryRef userInfo) {
9
10 NSString*lockstate = (__bridge NSString*)name;
11
12 if ([lockstateisEqualToString:(__bridge NSString*)NotificationLock]) {
13
14 NSLog(@"locked.");
15 } else {
16
17 NSLog(@"lock state changed.");
18 }
19 }
20
21
22 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
23
24 // Overridepoint for customization after application launch.
25 CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),NULL, screenLockStateChanged, NotificationLock, NULL,CFNotificationSuspensionBehaviorDeliverImmediately);
26
27 CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),NULL, screenLockStateChanged, NotificationChange, NULL,CFNotificationSuspensionBehaviorDeliverImmediately);
28
29 //setScreenStateCb();
30 return YES;
31 }
C. 程序退后台后,这时再锁屏就收不到上面的那个通知了,需要另外一种方式, 以循环的方式一直来检测是否是锁屏状态,会消耗性能并可能被苹果挂起
1 static voidsetScreenStateCb() {
2
3 uint64_tlocked;
4
5 __block inttoken = 0;
6
7 notify_register_dispatch("com.apple.springboard.lockstate",&token,dispatch_get_main_queue(),^(intt) {
8 });
9
10 notify_get_state(token, &locked);
11
12 NSLog(@"%d",(int)locked);
13 }
14
15
16 -(void)applicationDidEnterBackground:(UIApplication *)application {
17
18 while (YES) {
19
20 setScreenStateCb();
21
22 sleep(1);
23 }
24 }
关于 notify.h 请移步到:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/notify_register_check.3.html
五、 获取电池状态(是否正在充电)
解答:
通过 UIDeviceBatteryStateDidChangeNotification 通知可以获取手机是否处于充电状态。
1 (void)batteryMoniter {
2
3 UIDevice *device = [UIDevice currentDevice];
4
5 device.batteryMonitoringEnabled = YES;
6
7 if (device.batteryState == UIDeviceBatteryStateUnknown) {
8
9 NSLog(@"UnKnow");
10 }else if (device.batteryState == UIDeviceBatteryStateUnplugged){
11
12 NSLog(@"Unplugged");
13 }else if (device.batteryState == UIDeviceBatteryStateCharging){
14
15 NSLog(@"Charging");
16 }else if (device.batteryState == UIDeviceBatteryStateFull){
17
18 NSLog(@"Full");
19 }
20
21 NSLog(@"%f",device.batteryLevel);
22 }
六、 获取电池电量
解答:
1 UIDevice *device = [UIDevice currentDevice];
2
3 device.batteryMonitoringEnabled = YES;
4
5 NSLog(@"%f",device.batteryLevel);//简单的这句就是了。
6
7 ################################################
8
9 Having said that, I would not use a timer event for this, it is pretty inefficient. You want to use KVO instead:
10
11 - (void) viewWillAppear:(BOOL)animated {
12
13 UIDevice *device = [UIDevice currentDevice];
14
15 device.batteryMonitoringEnabled = YES;
16
17 currentCharge.text = [NSString stringWithFormat:@"%.2f", device.batteryLevel];
18
19 [device addObserver:self forKeyPath:@"batteryLevel" options:0x0 context:nil];
20
21 [super viewWillAppear:animated];
22 }
23
24
25 - (void) viewDidDisappear:(BOOL)animated {
26
27 UIDevice *device = [UIDevice currentDevice];
28
29 device.batteryMonitoringEnabled = NO;
30
31 [device removeObserver:self forKeyPath:@"batteryLevel"];
32
33 [super viewDidDisappear:animated];
34 }
35
36
37 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
38
39 UIDevice *device = [UIDevice currentDevice];
40
41 if ([object isEqual:device] && [keyPath isEqual:@"batteryLevel"]) {
42
43 currentCharge.text = [NSString stringWithFormat:@"%.2f", device.batteryLevel];
44
45 }
46 }
http://stackoverflow.com/questions/6161318/how-to-determine-whether-ios-device-is-connected-to-desktop-computer-and-itunes
EAAccessory相关方法需要Iphone的外设配件支持,只有在配件通过30pin、蓝牙、USB的方式连接iOS设备时,才能够通过该方法来检测是否连接(外设配件)的状态。外设的相关设置,需要在info.plist中添加UISupportedExternalAccessoryProtocols键,需要把pc端设置成iPhone的外设备才行,这一步不知道怎么做了。
七、 获取 SIM 卡信号强度
解答:
私有 API获取
1 intgetSignalStrength() {
2
3 void *libHandle =dlopen("/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony",RTLD_LAZY);
4
5 int (*CTGetSignalStrength)();
6
7 CTGetSignalStrength = dlsym(libHandle,"CTGetSignalStrength");
8
9 if( CTGetSignalStrength == NULL) {
10
11 NSLog(@"Couldnot find CTGetSignalStrength");
12 }
13
14 int result = CTGetSignalStrength();
15
16 dlclose(libHandle);
17 return result;
18 }
以上代码获取 RSSI的值为正,函数拿到的是 rssi,转换成 dbm需要剪掉 113
可以用class-dump这个工具来导出库里的头文件结构(包含了私有API)
八、 获取 WIFI 的信息(WIFI列表和强度)
解答:
1 - (id)fetchSSIDInfo {
2
3 NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
4
5 NSLog(@"Supported interfaces: %@", ifs);
6
7 id info = nil;
8
9 for (NSString *ifnam in ifs) {
10
11 info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
12
13 NSLog(@"%@ => %@", ifnam, info);
14
15 if (info && [info count]) { break; }
16 }
17
18 return info;
19 }
九、 判断当前应用的定位服务是否可用
解答:
用到地图定位的时候,会判断定位是否可用来初始化定位服务。但是以前的方法是判断所有应用的定位服务,无法指定到当前的应用是否开启服务。下面的就可以直接搞定这个问题。
1 //[CLLocationManager locationServicesEnabled]判断全局的定位功能是否可用
2 if ([CLLocationManager locationServicesEnabled] && ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined)) {
3
4 //定位功能可用,开始定位
5 _locationManger = [[CLLocationManager alloc] init];
6
7 locationManger.delegate = self;
8
9 [locationManger startUpdatingLocation];
10 } else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
11
12 NSlog("定位功能不可用,提示用户或忽略");
13 }
十、 监测网络状态的改变
解答:
1 -(void)startNetCheck {
2
3 NSLog(@"探测网络开始,startNetCheck");
4
5 [AFNetworkReachabilityManagermanagerForDomain:@"www.baidu.com"];
6
7 [[AFNetworkReachabilityManagersharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatusstatus) {
8
9 NSLog(@"探测网络结果[%d]",status);
10
11 //发送通知
12 [[NSNotificationCenterdefaultCenter]postNotificationName:RcSGlobalNoticeNetworkChangeobject:@(status)];
13 }];
14
15 [[AFNetworkReachabilityManagersharedManager] startMonitoring];
16 }
十一、 监测蓝牙开启状态
解答:
添加类库:
CoreBluetooth.framework
导入:
#import<CoreBluetooth/CoreBluetooth.h>
初始化并设置代理:
CBCentralManager*centralManager = [[CBCentralManager alloc] initWithDelegate:selfqueue:nil];
实现代码方法:
1 -(void)peripheralManagerDidUpdateState:(CBPeripheralManager*)peripheral {
2
3 switch (peripheral.state) {
4
5 //蓝牙开启且可用
6 caseCBPeripheralManagerStatePoweredOn: {
7
8 NSLog(@"Bluetoothis currently powered on and available to use.");
9 }
10 break;
11 default:
12
13 NSLog(@"PeripheralManager did change state");
14
15 break;
16 }
17 }
十二、 红外感应(距离感应器)
解答:
1 - (void)handleNotification:(BOOL)state{
2
3 [[UIDevicecurrentDevice]setProximityMonitoringEnabled:state];//设置红外感应是否可用
4
5 if(state) {//添加监听
6
7 [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(sensorStateChange:) name:@"UIDeviceProximityStateDidChangeNotification"object:nil];
8 }else {//移除监听
9
10 [[NSNotificationCenterdefaultCenter]removeObserver:self name:@"UIDeviceProximityStateDidChangeNotification"object:nil];
11 }
12
13 //处理监听触发事件
14 -(void)sensorStateChange:(NSNotificationCenter*)notification {
15
16 //如果此时手机靠近面部放在耳朵旁,那么声音将通过听筒输出,并将屏幕变暗(省电啊)
17 if([[UIDevicecurrentDevice]proximityState]== YES) {
18
19 NSLog(@"Deviceis close to user");
20
21 [[AVAudioSessionsharedInstance]setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
22 }else{
23
24 NSLog(@"Deviceis not close to user");
25
26 [[AVAudioSessionsharedInstance]setCategory:AVAudioSessionCategoryPlayback error:nil];
27 }
28 }
十三、 监听程序失去active(比如 按下home键)和成为active
解答:
第一步:
创建2个NSNotificationCenter监听
1. [[NSNotificationCenterdefaultCenter] addObserver:self selector:@selector(applicationWillResignActive:)name:UIApplicationWillResignActiveNotificationobject:nil];//监听是否触发home键挂起程序
2.
3. [[NSNotificationCenterdefaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:)name:UIApplicationDidBecomeActiveNotificationobject:nil];//监听是否重新进入程序程序
第二步:
实现2个NSNotificationCenter所触发的事件方法
1. (void)applicationWillResignActive:(NSNotification*)notification{
2.
3. printf("按理说是触发home按下\n");
4. }
5.
6. -(void)applicationDidBecomeActive:(NSNotification*)notification{
7.
8. printf("按理说是重新进来后响应\n");
9. }
十四、 监听输出设备变化(耳机插拔、蓝牙设备断与连)
解答:
在ios6以前,我们有如下的方法:
1. #import<AVFoundation/AVFoundation.h>
2.
3. [[AVAudioSession sharedInstance] setDelegate:self];
4.
5. AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange,audioRouteChangeListenerCallback, self);
然后实现该回调:
1. //音频监控回调函数
2. static void audioRouteChangeListenerCallback(void *inUserData, AudioSessionPropertyID inPropertyID, UInt32inPropertyValueSize, const void *inPropertyValue) {
3.
4. if (inPropertyID != kAudioSessionProperty_AudioRouteChange){
5.
6. return;
7. }
8. // Determines the reason for the routechange, to ensure that it is not
9. // because of a category change.
10.
11. CFDictionaryRef routeChangeDictionary =inPropertyValue;
12.
13. CFNumberRef routeChangeReasonRef =CFDictionaryGetValue (routeChangeDictionary, CFSTR (kAudioSession_AudioRouteChangeKey_Reason));
14.
15. SInt32 routeChangeReason;
16.
17. CFNumberGetValue (routeChangeReasonRef,kCFNumberSInt32Type,&routeChangeReason);
18. // do your handling here
19. }
请注意[[AVAudioSession sharedInstance] setDelegate:self]一定不要遗漏,否则该回调应该无法触发。
--------------分割线--------------
上面的方法是ios6以前的实现方式,我们可以看出这个api是比较低级的实现,其回调还是c的实现方式,而不是我们平常习惯的oc实现。
因此在ios6及以后,上面的api被deprecated了(当然,你要是还这么用,也还是能够实现功能),我们有更好更高级的实现来解决问题:
1. [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(outputDeviceChanged:)name:AVAudioSessionRouteChangeNotificationobject:[AVAudioSessionsharedInstance]];
2.
3. -(void)outputDeviceChanged:(NSNotification *)aNotification {
4.
5. // do your jobs here
6. }
请注意,addobserver的参数填写:其中的object必须是[AVAudioSession sharedInstance],而不是我们通常很多情况下填写的nil,此处若为nil,通知也不会触发。
- IOS 获取设备相关特性
- iOS设备相关信息获取
- iOS 获取设备相关信息
- iOS获取设备相关信息
- iOS 设备获取设备相关信息
- 获取iOS设备的相关信息
- iOS获得设备相关信息,获取app相关信息
- iOS开发小技巧 获取当前设备/应用程序相关信息
- iOS 获取本地设备相关信息,如:IP地址
- ios 获取手机设备型号等相关信息
- 获取设备相关信息
- ios相关设备降级
- 获取IOS设备字体
- 获取iOS设备类型
- iOS - 获取设备语言:
- ios设备获取存储空间
- 获取ios设备电量
- 获取ios设备电量
- 怎么xxx.app一直都是红色的? 编译了很多次 显示成功,但就是红色
- 《C算法》笔记7:词法解析树
- Sdoi2015约数个数和题解莫比乌斯反演
- 小结-sprintf()
- (题解)(Splay)NOI2004郁闷的出纳员
- IOS 获取设备相关特性
- TCP与UDP的区别
- 动态数组封装实现向量类
- exchange2013的搜索邮件跟踪日志功能
- 同一服务器上启动多个数据库的方法及常见问题
- C++ Primer : 第十二章 : 动态内存之unique_ptr和weak_ptr
- CodeForces-447C DZY Loves Sequences
- Pixhawk---烧写FMU/IO bootloader
- object-c语言的nonatomic,assign,copy,retain的区别