应用进入后台监测摇一摇事件<转>

原文地址:iOS使用CoreMotion实现摇一摇功能

现在网上介绍的iOS摇一摇功能,基本是以借助系统的ShakeToEdit功能来实现,什么是ShakeToEdit?看下图应该就能懂:

  怎么实现?请看以下代码:

[objc] view plain copy

  1. //ViewController 加入以下两方法
  2. -(BOOL)canBecomeFirstResponder
  3. {
  4. //让当前controller可以成为firstResponder,这很重要
  5. return YES;
  6. }
  7. -(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
  8. {
  9. if (event.subtype==UIEventSubtypeMotionShake) {
  10. //做你想做的事
  11. }
  12. }
  13. //在viewDidView中调用以下消息,主动让当前controller成为firstResponder
  14. [self becomeFirstResponder];
  15. //已经不需要其它多余代码了

  这个方法最简单,但这个功能有时候会失效。它失效的时候,系统所有摇一摇撤销重做都会不起作用,从而导致包括所有关联的Shake事件也不起作用。失效原因或在什么情况下失效,目前还没有相关资料。据这两天个人观察,大多发生在手机放在裤袋中走10多分钟路之后(iPhone5S iOS 7.05).是否因为摇得太久了,系统为了省电就关闭此功能呢?希望大家也拿自己手机来试一试,我们一起来看看这到底是什么问题。

  要恢复,最直接的是连接iTunes,否则,就要让手机平放一段时间,但时候平放一天都没有恢复。所以说此方式不太稳定,微信及其它有摇一摇功能的应用,他们的摇一摇并不受此影响,而且微信的摇一摇动作比ShakeToEdit要轻,可以讲手动动一下就激活了。于是我认为,这些应用都放弃了ShakeToEdit,使用了加速仪,自己重新实现。

  使用加速仪与使用相机,声音之类不同,不需要经过用户允许,也没有访问限制,当然也没什么危害,是个基本配备。那要怎么做?下面费话不多说,直接开始吧:

  第一步,为项目TARGET添加CoreMotion.framework

  第二步,引入头文件

[objc] view plain copy

  1. #import <CoreMotion/CoreMotion.h>

  第三步,使用CMMotionManager

[objc] view plain copy

  1. @property (strong,nonatomic) CMMotionManager *motionManager;

  注意,当前应用只能有一个CMMotionManager实例,多个实例会影响接收速率

  第四步,实例并初始化加速仪

[objc] view plain copy

  1. self.motionManager = [[CMMotionManager alloc] init];//一般在viewDidLoad中进行
  2. self.motionManager.accelerometerUpdateInterval = .1;//加速仪更新频率,以秒为单位

  第五步,开始接收加速仪数据(startAccelerometerUpdatesToQueue:withHandler:

[objc] view plain copy

  1. -(void)viewDidAppear:(BOOL)animated
  2. {
  3. [self startAccelerometer];
  4. }
  5. -(void)startAccelerometer
  6. {
  7. //以push的方式更新并在block中接收加速度
  8. [self.motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc]init]
  9. withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
  10. [self outputAccelertionData:accelerometerData.acceleration];
  11. if (error) {
  12. NSLog(@"motion error:%@",error);
  13. }
  14. }];
  15. }
  16. -(void)outputAccelertionData:(CMAcceleration)acceleration
  17. {
  18. //综合3个方向的加速度
  19. double accelerameter =sqrt( pow( acceleration.x , 2 ) + pow( acceleration.y , 2 )
  20. + pow( acceleration.z , 2) );
  21. //当综合加速度大于2.3时,就激活效果(此数值根据需求可以调整,数据越小,用户摇动的动作就越小,越容易激活,反之加大难度,但不容易误触发)
  22. if (accelerameter>2.3f) {
  23. //立即停止更新加速仪(很重要!)
  24. [self.motionManager stopAccelerometerUpdates];
  25. dispatch_async(dispatch_get_main_queue(), ^{
  26. //UI线程必须在此block内执行,例如摇一摇动画、UIAlertView之类
  27. });
  28. }
  29. }
  30. -(void)viewDidDisappear:(BOOL)animated
  31. {
  32. //停止加速仪更新(很重要!)
  33. [self.motionManager stopAccelerometerUpdates];
  34. }

  最后一步

  至此,摇一摇核心已经实现,但还差最后一步:当App退到后台时必须停止加速仪更新,回到当前时重新执行。否则应用在退到后台依然会接收加速度更新,可能会与其它当前应用冲突,产生不好的体验。所以,分别在viewDidAppear和viewDidDisappear中加入如下监听:

[objc] view plain copy

  1. //viewDidAppear中加入
  2. [[NSNotificationCenter defaultCenter] addObserver:self
  3. selector:@selector(receiveNotification:)
  4. name:UIApplicationDidEnterBackgroundNotification object:nil];
  5. [[NSNotificationCenter defaultCenter] addObserver:self
  6. selector:@selector(receiveNotification:)
  7. name:UIApplicationWillEnterForegroundNotification object:nil];

[objc] view plain copy

  1. //viewDidDisappear中取消监听
  2. [[NSNotificationCenter defaultCenter] removeObserver:self
  3. name:UIApplicationDidEnterBackgroundNotification object:nil];
  4. [[NSNotificationCenter defaultCenter] removeObserver:self
  5. name:UIApplicationWillEnterForegroundNotification object:nil];

[objc] view plain copy

  1. //对应上面的通知中心回调的消息接收
  2. -(void)receiveNotification:(NSNotification *)notification
  3. {
  4. if ([notification.name
  5. isEqualToString:UIApplicationDidEnterBackgroundNotification])
  6. {
  7. [self.motionManager stopAccelerometerUpdates];
  8. }else{
  9. [self startAccelerometer];
  10. }}

  至此,所有使用加速仪实现摇一摇功能的实现方式已介绍完毕。

  一些可改进的地方:

  1) 摇一摇动作捕捉——如果仅是以加速度大小来判定,有可能用户突然快速移动手机时就激活了摇动,但用户比较稍稍慢一些来回晃动手机却不会激活,可能与用户期望的稍微有出入。系统的ShakeToEdit就能做得比较到位。
   我们可以结合定时器与加速度的正反方向来更精确判定用户的摇一摇动作,例如:综合加速度改为带方向的向量,然后当1.5秒内有相反两个方向大于某个数值的加速度,才算为一个摇动行为。这个1.5秒时间需要通过实际测试来取值,当某次取得的加速度值大于某个值开始统计下一个加速度向量,此值也需要实测来取值,可能1.5左右就够了。

  2) App状态更改——如果激活的摇一摇是个长时间等待行为,例如弹出ActionSheet让用户选择操作。在用户进行下一步操作前,ActionSheet没消失前,不应该启动下一次监听,包括应用从后台回到当前状态后,也要判断用户是否有过下一步行为。

原文地址:https://www.cnblogs.com/deng37s/p/8492317.html

时间: 2024-08-28 10:26:55

应用进入后台监测摇一摇事件<转>的相关文章

利用HTML5的devicemotion事件实现手机摇一摇抽奖,年会抽奖

摇一摇JS脚本逻辑:接下来是移动端JS脚本逻辑的实现,摇一摇的实现需借助html5新增的devicemotion事件,获取设备在位置和方向上的改变速度的相关信息,该事件的基本使用如下: if (window.DeviceMotionEvent) { window.addEventListener('devicemotion', handler, !1); lastTime = new Date(); } else { alert('你的浏览器不支持摇一摇功能.'); } devicemotion

摇一摇事件

html5新增了一个devicemotion的事件,可以使用手机的重力感应.如下代码所示: window.ondevicemotion = function(event){ var gravity = event.accelerationIncludingGravity; console.log(gravity.x, gravity.y, gravity.z); } x,y,z表示三个方向的重力加速度,如下图所示: x是手机短边,y是长边,z是和手机屏幕垂直的方向,当把手机平着放的时候,由于x.

iOS 摇一摇事件

我知道的摇一摇有以下2种方案: 一.直接用系统自带的motionBegan方法 -(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event 假如程序不响应此方法,试着加入下面方法: -(BOOL)canBecomeFirstResponder { return YES; } 如果还不行,建议用第二种方法. 二.motionBegan+通知的方法 1.在Appdelegate里写motionBegan方法 -(void)

微信摇一摇红包

 功能介绍  2015年9月份左右微信摇一摇周边开放了"摇一摇红包组件接口",具备开发能力的用户,可以调用该接口进行功能开发.摇一摇红包功能通过简便的操作方式减少用户的操作层级.优化了用户的互动体验,并且趣味性地留存了用户和促进了品牌推广,参与活动的用户仅需在ibeacon设备蓝牙广播范围内打开手机蓝牙,进入微信摇一摇,等待出现"周边"入口,即可摇到现金红包,用户点击拆开红包,直接转入微信零钱包并且默认用户关注了公众号.  用户领取红包流程  现在,跟着一起,来体验

Android摇一摇振动效果Demo

前言 在微信刚流行的时候,在摇一摇还能用来那啥的时候,我也曾深更半夜的拿着手机晃一晃.当时想的最多的就是.我靠,为神马摇一下须要用这么大的力度,当时我想可能腾讯认为那是个人性的设计.后来才发觉尼马重力加速度设得太高了吧.扯多了.近期项目里须要解决一个振动的问题,因此在学习振动实现的过程中,写了个demo实现了摇一摇振动的效果,这里记录一下. 原理 摇一摇功能的基本原理就是:利用手机的加速度传感器,当加速度到达某个值时.触发某个事件,比如手机振动.UI改变等.这里要实现该功能,首先须要了解一下An

Android摇一摇震动效果Demo

前言 在微信刚流行的时候,在摇一摇还能用来那啥的时候,我也曾深更半夜的拿着手机晃一晃.当时想的最多的就是,我靠,为神马摇一下需要用这么大的力度,当时我想可能腾讯觉得那是个人性的设计,后来才发觉尼马重力加速度设得太高了吧.扯多了,最近项目里需要解决一个震动的问题,因此在学习震动实现的过程中,写了个demo实现了摇一摇震动的效果,这里记录一下. 原理 摇一摇功能的基本原理就是:利用手机的加速度传感器,当加速度到达某个值时,触发某个事件,例如手机震动.UI改变等.这里要实现该功能,首先需要了解一下An

利用html5实现类似微信的手机摇一摇功能,并播放音乐,并且解决中文乱码的问题。

转载了@三井学长:http://blog.csdn.net/david1030/article/details/8229008 转载了@Hello Csn楠!:http://www.cnblogs.com/csn0721/ 1.  deviceOrientation:封装了方向传感器数据的事件,可以获取手机静止状态下的方向数据,例如手机所处角度.方位.朝向等. 2.  deviceMotion:封装了运动传感器数据的事件,可以获取手机运动状态下的运动加速度等数据. 不多说直接上代码, Javas

Android仿iPhone晃动撤销输入功能(微信摇一摇功能)

重力传感器微信摇一摇SensorMannager自定义alertdialogSensorEventListener 很多程序中我们可能会输入长文本内容,比如短信,写便笺等,如果想一次性撤销所有的键入内容,很多手机需要一直按住退格键逐字逐句的删除,稍稍麻烦,不过 在iPhone上,有个人性化的功能,当我们想要去撤销刚刚输入的所有内容的时候,可以轻轻晃动手机,会弹出提示框,点击确定就可以清空内容,如下图: 在 android中,一般手机貌似没有定制这个功能,不过我们可以自己去实现这样的功能,放置在我

利用传感器(sensor)实现微信摇一摇动画

所需要的权限: <uses-permission android:name="android.permission.VIBRATE"></uses-permission> xml文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/and