app运行状态代码 ios获取
2018-11-14 09:31:00 weixin_34279184 阅读数 22

在开发中,有时候我们需要让某些特定的页面为横屏展示,而从这个页面离开或者进入其他页面时为竖屏,起初我仅仅依赖了UIViewController的屏幕旋转方法简单的处理,但是当需求慢慢在变化时,我发觉这并不能满足我的需求:

比如导航页需要横屏展示,但是从导航页上面某个按钮跳转的页面需要竖屏展示,而再从这个页面返回到导航页时,如果屏幕为竖屏且用户关闭了屏幕旋转锁定,则导航页应继续展示横屏。

下面笔记写的比较乱,可直接查看Demo in Github

屏幕旋转的方案

我现在使用的解决方案是CMMotionManager,启动设备的运动更新,通过给定的队列向给定的处理程序提供数据,对屏幕旋转的监测。

CMMotionManager可以理解为是CoreMotion Framework的中央管理器,也可以理解为运动服务。这些服务提供了获取加速机数据、旋转数据和磁力数据等。

首先我在info.plist中把设备的方向只勾选了竖屏。

AppDelegate 中需要实现的方法

- (UIInterfaceOrientationMask)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window {// iPhone doesn't support upside down by default, while the iPad does.  Override to allow all orientations always, and let the root view controller decide what's allowed (the supported orientations mask gets intersected).UIViewController* presentdeVC = [self.class topViewControllerWithPresentedViewController];if([presentdeVC isKindOfClass:NSClassFromString(@"NaviController")])returnUIInterfaceOrientationMaskAllButUpsideDown;returnUIInterfaceOrientationMaskPortrait;}

监听设备运动

/// 开启屏幕旋转的检测- (void)startListeningDirectionOfDevice {if(self.motionManager ==nil) {self.motionManager = [[CMMotionManageralloc] init];    }// 提供设备运动数据到指定的时间间隔 刷新数据的评率self.motionManager.deviceMotionUpdateInterval =0.3;// 判断设备传感器是否可用if(self.motionManager.deviceMotionAvailable) {// 启动设备的运动更新,通过给定的队列向给定的处理程序提供数据。[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueuemainQueue] withHandler:^(CMDeviceMotion*motion,NSError*error) {                        [selfperformSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];        }];    }else{        [selfsetMotionManager:nil];    }}

停止监听设备运动

- (void)stopListeningDirectionOfDevice {if(_motionManager) {        [_motionManager stopDeviceMotionUpdates];        _motionManager =nil;    }}

根据设备运动,更新设备屏幕方向

- (void)handleDeviceMotion:(CMDeviceMotion*)deviceMotion {if([UIDevicebb_canRotate] ==false) {return;    }doublex = deviceMotion.gravity.x;doubley = deviceMotion.gravity.y;if(fabs(y) >= fabs(x)) {// 竖屏if(y <0) {if(self.previousInterfaceOrientation ==UIInterfaceOrientationPortrait) {return;            }            [selfapplyInterfaceOrientation:UIInterfaceOrientationPortrait];        }else{if(self.previousInterfaceOrientation ==UIInterfaceOrientationPortraitUpsideDown) {return;            }            [selfapplyInterfaceOrientation:UIInterfaceOrientationPortraitUpsideDown];        }    }else{// 横屏if(x <0) {if(self.previousInterfaceOrientation ==UIInterfaceOrientationLandscapeRight) {return;            }            [selfapplyInterfaceOrientation:UIInterfaceOrientationLandscapeRight];        }else{if(self.previousInterfaceOrientation ==UIInterfaceOrientationLandscapeLeft) {return;            }            [selfapplyInterfaceOrientation:UIInterfaceOrientationLandscapeLeft];        }    }}

强制修改屏幕方向

- (void)applyInterfaceOrientation:(UIInterfaceOrientation)orientation {    [[UIDevicecurrentDevice] beginGeneratingDeviceOrientationNotifications];UIDevice*currentDevice = [UIDevicecurrentDevice];UIDeviceOrientationcurrentDeviceOrientation = currentDevice.orientation;/// mark:强制旋转有时无效的解决方案: 强制前先设置为UIDeviceOrientationUnknown[currentDevice setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"];        SEL selector =NSSelectorFromString(@"setOrientation:");if(![currentDevice respondsToSelector:selector]) {return;    }NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];    [invocation setSelector:selector];    [invocation setTarget:currentDevice];// 从2开始是因为0 1 两个参数已经被selector和target占用[invocation setArgument:&orientation atIndex:2];    [invocation invoke];    [currentDevice endGeneratingDeviceOrientationNotifications];    [UIDevicesetForceOrientation:currentDeviceOrientation];}

获取屏幕锁定状态

现在存在的问题是,屏幕旋转开关被锁定时,横屏状态下不应该可以旋转页面,而Apple提供的api中,并没有获取控制中心中屏幕旋转锁定的开关

通过监听UIDeviceOrientationDidChangeNotification通知测试:

当app在前台时,如果屏幕旋转开关锁定了,怎么旋转设备都不会触发此通知,只有在app启动、从后台进入前台或者被激活时,才会触发此通知

当屏幕旋转开关被关闭时,设备旋转时都会触发此通知的

解决方法:

注册UIDeviceOrientationDidChangeNotification通知

[[UIDevicecurrentDevice] beginGeneratingDeviceOrientationNotifications];    [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(deviceOrientaionDidChange:) name:UIDeviceOrientationDidChangeNotificationobject:[UIDevicecurrentDevice]];}

当触发监听的方法时,根据设备的方向确定屏幕是否可以旋转

/// 当用户锁定了屏幕旋转开关时,且app在前台时,设备旋转不会触发此通知,当app启动、从后台进入前台或者被激活时,都会触发此通知+ (void)deviceOrientaionDidChange:(NSNotification*)noty {self.forceOrientation = [UIDevicecurrentDevice].orientation;    [InterfaceOrientationUtil sharedInsatnce].previousInterfaceOrientation = [UIApplicationsharedApplication].statusBarOrientation;UIDevice*device = [UIDevicecurrentDevice] ;/**

    *  取得当前Device的方向,Device的方向类型为Integer

    *

    *  必须调用beginGeneratingDeviceOrientationNotifications方法后,此orientation属性才有效,否则一直是0。orientation用于判断设备的朝向,与应用UI方向无关

    *

    *  @param device.orientation

    *

    */NSLog(@"%@", noty.userInfo);switch(device.orientation) {caseUIDeviceOrientationLandscapeLeft:caseUIDeviceOrientationLandscapeRight:            [selfsetBb_canRotate:YES];//只有当用户把手机旋转到横屏的时候来去触发判断是否支持横屏break;default:            [selfsetBb_canRotate:NO];break;    }}

在监听设备的运动更新的方法中,根据canRotate判断是否可以旋转屏幕

作者:swift_kim

链接:https://www.jianshu.com/p/2eeac9a10814

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

2018-08-23 11:09:00 weixin_34268169 阅读数 40
  1. 程序在前台,这种比较简单。直接使用Darwin层的通知就可以了:(但是这种方法,只能针对不上线的项目来使用,有可能被拒。在17年的时间这个API变成私有的了)
#import <notify.h>

#define NotificationLock CFSTR("com.apple.springboard.lockcomplete")

#define NotificationChange CFSTR("com.apple.springboard.lockstate")

#define NotificationPwdUI CFSTR("com.apple.springboard.hasBlankedScreen")

static void screenLockStateChanged(CFNotificationCenterRef center,void* observer,CFStringRef name,const void*object,CFDictionaryRef userInfo)

{

 NSString* lockstate = (__bridge NSString*)name;

 if ([lockstate isEqualToString:(__bridgeNSString*)NotificationLock]) {

//如果想做在这里面做一些操作的话,可以用通知来和OC语言来做交互

 NSLog(@"locked.");

 } else {

     // 此处监听到屏幕解锁事件(锁屏也会掉用此处一次,锁屏事件要在上面实现)

 NSLog(@"lock state changed.");

 }

}

添加通知

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

   CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, screenLockStateChanged, NotificationLock, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);

   CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, screenLockStateChanged, NotificationChange, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);

   return YES;

}

2: 还有一种黑客的做法是调节屏幕的亮度,直接上代码

-(void)applicationDidEnterBackground:(NSNotification*)notification  {

    if ([self didUserPressLockButton]) {

        //User pressed lock button

        NSLog(@"Lock screen.");

    }else{

        NSLog(@"Home.");

        //user pressed home button

    }

}

-(BOOL)didUserPressLockButton{

    //获取屏幕亮度

    CGFloat oldBrightness = [UIScreen mainScreen].brightness;

    //以较小的数量改变屏幕亮度

    [UIScreenmainScreen].brightness= oldBrightness + (oldBrightness <=0.01? (0.01) : (-0.01));

    CGFloatnewBrightness  = [UIScreen mainScreen].brightness;

    //恢复屏幕亮度

    [UIScreen mainScreen].brightness = oldBrightness;

    //判断屏幕亮度是否能够被改变

    returnoldBrightness != newBrightness;

}

当用户离开通过锁定按钮而不是主页按钮时,苹果只允许你从applicationDidEnterBackground更改屏幕亮度。这种方法是当APP进入后台时, 以较小的数量改变屏幕亮度,并检查是否能够更改。如果能够更改便是锁定按钮,不能则是主页按钮。经过检测这种方法是可行的,这里讲的是监听锁屏,这个方法同样也可以监听解锁,小编开发的功能是有定时器的,每隔一秒就会执行下didUserPressLockButton这个方法,解锁的时候会同样执行锁屏的语句。

另外网上还有一种方法是通过检测屏幕亮度来判断是锁屏还是按了home键,这种方法是不可以的,因为锁屏之后屏幕的亮度并不为0。

2016-04-17 12:37:00 u014744233 阅读数 328
  1. #import <CoreTelephony/CTCallCenter.h>    
  2. #import <CoreTelephony/CTCall.h>    
  3.   
  4. [plain] view plaincopy  
  5. -(void)detectCall    
  6. {    
  7.      CTCallCenter *callCenter = [[CTCallCenter alloc] init];    
  8.     callCenter.callEventHandler=^(CTCall* call)    
  9.     {    
  10.         if (call.callState == CTCallStateDisconnected)    
  11.         {    
  12.             NSLog(@"Call has been disconnected");    
  13.             self.viewController.signalStatus=YES;    
  14.         }    
  15.         else if (call.callState == CTCallStateConnected)    
  16.         {    
  17.             NSLog(@"Call has just been connected");    
  18.         }    
  19.             
  20.         else if(call.callState == CTCallStateIncoming)    
  21.         {    
  22.             NSLog(@"Call is incoming");    
  23.             //self.viewController.signalStatus=NO;    
  24.         }    
  25.             
  26.         else if (call.callState ==CTCallStateDialing)    
  27.         {    
  28.             NSLog(@"call is dialing");    
  29.         }    
  30.         else    
  31.         {    
  32.             NSLog(@"Nothing is done");    
  33.         }    
  34.     };    
  35. }    
2013-05-22 17:37:26 waterforest_pang 阅读数 3402
UIDeviceBatteryState deviceBatteryState = [UIDevice currentDevice].batteryState;
if (deviceBatteryState == UIDeviceBatteryStateCharging || deviceBatteryState == UIDeviceBatteryStateFull) {
    // It is charging
}

typedef enum {
   UIDeviceBatteryStateUnknown,
   UIDeviceBatteryStateUnplugged,
   UIDeviceBatteryStateCharging,
   UIDeviceBatteryStateFull,
} UIDeviceBatteryState;


2013-01-17 15:31:16 slinloss 阅读数 3230

1.首先引入CoreTelephony.framework
2.加入头文件

1
#import <CoreTelephony/CTCallCenter.h>

3.功能实现

1
2
3
4
CTCallCenter *center = [[CTCallCenter alloc] init];
center.callEventHandler = ^(CTCall *call){
        NSLog(@"Call State : %@",[call description]);
    };

当电话打进来时,程序就会执行我们的block.
CTCall (0x1ab590) {
callState: [CTCallStateIncoming]
Call ID: [2B9E84A9-0F12-4539-AC8D-AF2A7ED7069E]
}
CTCall (0x183a00) {
callState: [CTCallStateDisconnected]
Call ID: [2B9E84A9-0F12-4539-AC8D-AF2A7ED7069E]
}
注:__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0)

ios获取app版本号

阅读数 809

IOS 获取安装的app

阅读数 613

获取iOS app资源

阅读数 447

iOS获取APP的IP地址

阅读数 841

没有更多推荐了,返回首页