bugku 管理员系统 后台代码_不会吧,这也行?iOS后台锁屏监听摇一摇

[toc]

背景介绍

一般情况下,出于省电、权限、合理性等因素考虑,给人的感觉是很多奇怪的需求安卓可以实现,但是iOS就无法实现!今天要介绍的需求也有这种感觉,就是“当 APP 处于后台或锁屏状态时,依旧可以监听到摇一摇,进而触发某些功能,比如:语音播报”。

在产品经理提出此需求的一瞬间,仿佛周边的空气都凝固了,我也犹如五雷轰顶,愣在原地无法动弹。不由心想:“苹果爸爸怎么可能允许开发者实现这种功能!这得多费电啊!要是所有 APP 都这么做了,那还了得!” 与此同时,之前网上疯传、远近闻名的的需求--“做一个会根据手机壳颜色而改变主题颜色的APP”,清晰地浮现在脑海中,顿时一万只xx 从心中奔腾而过。此时,产品经理解释到,这是咱们好多视力障碍用户提的需求,他们经常锁屏或把 APP 退到后台,且因为视力不佳原因,导致重新找到 APP 并切到前台的操作很是麻烦,所以十分希望我们能实现这个功能。

在短暂的心理活动后,秉着“客户第一,产品 ”的原则,于是回复说:“这功能太少见了,我先在网上看看吧,要是有其他 APP 有类似的功能,麻烦跟我说我参考一下。”然后,就祭出了程序员利器--Google,输入“iOS 后台 摇一摇”,只搜索出来的一个思路:利用 CoreMotion 框架,监听加速计原始数据,然后在 APP 退到后台后,可以实现监听摇一摇的效果。然而,并没有完整的代码或 demo 。顿时,Talk is cheap, show me the code!这句经典台词突然地出现在脑海中!也看到有人评论说 CoreMotion 的确可以实现跟系统摇一摇类似的效果,但是退到后台或锁屏后,没办法监听到摇一摇事件。

看到这条评论时,我不禁开始怀疑此功能是否真的可以被实现。

玩归玩,闹归闹,开始 code,不开玩笑。

接下来,开始自己的探索之旅。

本文 demo 链接为 OCDailyTests/BackgroundShakeTest,可自行下载,方便运行和验证。

探索过程

其他 APP 有没有类似功能

经过一番 Google,终于找到一款 APP 有类似功能::酷狗音乐 APP,对,就是那个在 PC 端一打开就会大喊 Hello KuGou!的音乐软件对应的 APP,万万没想到,手机 APP 也是这样,一句Hello KuGou!把我吓一跳。按如下步骤,在设置里打开此功能后,后台或锁屏时,摇一摇手机,可实现切歌的效果。

7868483c934c1151e222f053edca69a6.png

703eb1250ebc84336f2b60a500818425.png

f83c8d99675f5c34dc08a3a016177414.png

既然的确有 APP 实现了此功能,那就踏踏实实地探索它可能是怎么实现的吧。

系统提供的摇一摇回调能否满足

系统摇一摇回调方法:

  - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{NSLog(@"%s", __FUNCTION__);}

经测试,此方法只有在 APP 处于前台时,才会被回调。APP 处于后台或锁屏时,此方法不会回调。故初步判定此方法不能满足需求。

##其他方法能否实现

此时,还是先根据网上各路大神提供的思路进行尝试,即利用 CoreMotion 框架,监听加速计原始数据,然后在 APP 退到后台后,实现监听摇一摇的效果。

好,我们先利用 CoreMotion 框架,监听加速计原始数据,实现类似系统摇一摇回调的效果。

利用 CoreMotion 框架,监听加速计原始数据

通过加速计监听摇一摇

因加速计回调比较频繁,因此比较占用资源,故把此功能设计为单例。

  • 快速实现单例效果

      //具体实现详见 demo 中文件#import "HMSingleton.h"@interface MYAccelerometerTool : NSObject
    HMSingleton_h(MYAccelerometerTool);
    @end@implementation MYAccelerometerTool
    HMSingleton_m(MYAccelerometerTool);
    @end
  • 声明和懒加载运动管理员属性

    @property(nonatomic, strong) CMMotionManager *gMotionMnger;- (CMMotionManager *)gMotionMnger{if (nil == _gMotionMnger) {CMMotionManager *lMnger = [[CMMotionManager alloc] init];lMnger.accelerometerUpdateInterval = 0.1;[lMnger startAccelerometerUpdates];_gMotionMnger = lMnger;}return _gMotionMnger;
    }
  • 声明和实现时间戳属性,用于实现节流效果(为防止频繁回调,每次检测成功后,停止摇动 1s 后才继续响应下次摇一摇。)

    @property(nonatomic, strong) NSDate *gDateLastShakeSuc;
    - (NSDate *)gDateLastShakeSuc{if (nil == _gDateLastShakeSuc) {_gDateLastShakeSuc = [NSDate distantPast];}return _gDateLastShakeSuc;
    }
  • 开始监听摇一摇动作

    - (BOOL)startMonitorShake{if (NO == self.gMotionMnger.isAccelerometerAvailable) {return NO;}//监听中,直接返回YESif (self.gMotionMnger.isAccelerometerActive) {return YES;}[self.gMotionMnger startAccelerometerUpdatesToQueue:[NSOperationQueue new] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {CMAcceleration acceleration = accelerometerData.acceleration;//综合x、y两个方向的加速度(z方向速度无意义,用的话,走路上下抖手机时会误触发,系统摇一摇也不会被z轴加速度触发)//当综合加速度大于2.3时,就激活效果(数据越小,用户摇动的动作就越小,越容易激活)double accelerameter = sqrt( pow( acceleration.x , 2 ) + pow( acceleration.y , 2 ));if (accelerameter > 2.3) {//节流效果:距离上次摇一摇成功事件,间隔时间小于1s时,认为无效NSDate *lCrtDate = [NSDate date];if ([lCrtDate timeIntervalSinceDate:self.gDateLastShakeSuc] < 1) {self.gDateLastShakeSuc = lCrtDate;return ;}self.gDateLastShakeSuc = lCrtDate;[[NSNotificationCenter defaultCenter] postNotificationName:KNTFY_SHAKE_SUCCESS object:nil];}}];return YES;
    }
  • 为了代码的对称美和可能的相关业务,实现停止监听摇一摇方法

    - (void)stopMonitorShake{[self.gMotionMnger stopAccelerometerUpdates];self.gMotionMnger = nil;self.gDateLastShakeSuc = nil;
    }

控制器相关逻辑和代码

  • 开始监听摇一摇

     BOOL lRes = [[MYAccelerometerTool sharedMYAccelerometerTool] startMonitorShake];NSLog(@"lRes:%d", lRes);NSAssert(lRes, @"开始监听摇一摇失败");
  • 监听摇一摇成功的通知

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nmShakeSuccess:) name:KNTFY_SHAKE_SUCCESS object:nil];//在摇一摇的同时,通过观察此方法是否有log,可以判断是否有监听到。
    - (void)nmShakeSuccess:(NSNotification *)ntfy{NSLog(@"%s", __FUNCTION__);
    }
  • dealloc方法中取消监听

    - (void)dealloc{[[NSNotificationCenter defaultCenter] removeObserver:self];
    }

    运行 demo 工程,测试可知,通过上述方法,的确可以在 APP 处于前台时,实现监听摇一摇动作的效果。可是,当把 APP 退到后台或锁屏时,nmShakeSuccess 方法不再有 log,即:APP 处于后台时,通过监听加速计的方法,默认也无法在 APP 处于后台或锁屏时实现监听效果。这也印证了上文提到的那个评论者的疑问。

    可是 Hello KuGou! 明明实现了后台或锁屏时摇一摇的效果啊!难道是需要额外的配置?联想 iOS 处于后台时,默认会把 APP 的服务给挂起(suspended),只有当 APP 通过某种方式(后台定位/播放音乐/蓝牙扫描等)具有后台运行权限时,才可以一直保活。可猜想,也许赋予 APP 具有后台运行的权限后,就可以实现想要的功能了。于是,开始进行验证如下。

APP 申请后台运行权限后,能否监听到摇一摇

因为工作中很多 APP 具有后台定位权限和相关功能,所以本文通过为 APP 申请后台定位权限来验证。

APP 申请后台定位权限

  • plist 文件中增加”定位请求描述信息“

    <key>NSLocationAlwaysUsageDescription</key><string>我们需要根据您的定位提供周边搜索和导航服务</string><key>NSLocationWhenInUseUsageDescription</key><string>我们需要根据您的定位提供周边搜索和导航服务</string>

    增加”后台定位权限“

    <key>UIBackgroundModes</key><array><string>location</string></array>
  • 声明定位管理员属性

    @property(nonatomic, strong) CLLocationManager *gMnger;
  • 懒加载定位管理员,请求定位权限、允许后台位置更新

    - (CLLocationManager *)gMnger{if (nil == _gMnger) {_gMnger = [[CLLocationManager alloc] init];_gMnger.delegate = self;_gMnger.allowsBackgroundLocationUpdates = YES;[_gMnger requestWhenInUseAuthorization];}return _gMnger;
    }
  • 代理 3 步走(用于验证后台定位是否生效)

    • 遵守代理协议

      @interface ViewController ()<CLLocationManagerDelegate>

    • 指定代理对象

      _gMnger.delegate = self;

    • 实现代理方法

      #pragma mark -  delegate
      - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{NSLog(@"%s", __FUNCTION__);
      }- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{NSLog(@"%s", __FUNCTION__);
      }
  • APP 后台或锁屏后,测试能否成功监听摇一摇

    运行 demo 工程,经测试,把 APP 退到后台或锁屏,或即退到后台又锁屏,都能够检测到摇一摇事件。

多 APP 都实现此功能时,摇一摇是何效果

这里用 demo APP 和酷狗音乐 APP 进行测试。

  • 同时打开这两个 APP,其中酷狗音乐 APP 打开后台摇一摇切歌的功能。
  • 酷狗音乐 APP 开始放歌,退到后台。
  • demo APP 打开后,退到后台。
  • 摇一摇,查看效果:
    • 当摇动的力度不是很大时,demo APP 回调方法会被触发;
    • 当摇动的力度很大时,demo APP 回调方法和酷狗 APP 切歌会同时被触发;
  • 由此可见,如果多个 APP 同时实现了此功能时,那么后台或锁屏摇一摇时,只要满足了某个 APP 实现的加速计相关判定条件,就可以同时触发多个 APP 对应的效果。

后台定位权限 + 系统摇一摇,是否可行?

经测试,还是不行。果然,系统摇一摇还是比较受限的,只能在前台回调。

文章小结

想要实现”iOS后台锁屏监听摇一摇“功能,

首次,必须满足一个硬性条件:APP 具有某种后台运行的权限。

其次,技术实现上必须使用CoreMotion框架,通过监听加速计回调自己实现对摇一摇事件的监听判定

最后,可通过增加时间属性,实现对摇一摇事件监听时的节流效果,防止持续摇动时,太过频繁的事件回调。

此外,多 APP 都实现此功能时,摇一摇的效果是:只要摇动力度很大,加速计数据满足 APP 实现的摇一摇判定条件,就可以同时触发多个 APP 各自对应的效果

因此,如果不是 APP 特别需要此功能,尽量不要这样实现,毕竟,比较占用系统资源,而且太多 APP 同时实现时,可能会出现效果上的相互干扰。不过,如果合理利用此功能,却可以为特殊用户群体提供极大的便利

通过探索,满足了视力障碍用户的迫切需求,还是蛮有成就感的!

偷偷的告诉大家,写到这里时,产品经理还没告诉我他所知道的哪个 APP 实现了这个功能,可能他太忙,给忘记了吧......

参考文章

iOS应用退出到后台后怎样监听摇晃事件

Demo 链接

OCDailyTests/BackgroundShakeTest

最后,感谢“技术创作101训练营”!通过参加训练营,让我对写作有了更深入的认识和更高的心里觉悟。

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows php5.3升级,Windows10系统将PHPNOW升级PHP版本为5.3.5

Windows 10发布很久了&#xff0c;现在大多数人都在使用&#xff0c;在WIN10中使用PHPNOW&#xff0c;觉得自带的PHP版本有点低&#xff0c;所以就想升级下&#xff0c;在网上搜索了一些方法&#xff0c;然后结合自己的实际操作&#xff0c;在这里分享下。1、首先要下载PHP5.3.…

在Microsoft Word中,Node是如何替代宏的

最近的30年来&#xff0c;宏&#xff08;macros&#xff09;成为了Microsoft Word的关键卖点。WordBASIC最初是在1989年引入的&#xff0c;它能够让受过极少培训的打字员都能进行计算机编程&#xff0c;从而简化他们的日常工作。\\在那个时代&#xff0c;竞争非常激烈。除了Wor…

igs无法分配驱动器映射表_硬盘无法使用,用DiskPart进行分区和格式化,非常简单...

如果计算机硬盘出现问题&#xff0c;有时不是硬件上出现了错误&#xff0c;很可能只是逻辑上出现了问题&#xff0c;这时就可以使用DiskPart来快速解决。在Windows 10上&#xff0c;当外部存储(例如U盘、可移动硬盘或SD卡)由于数据损坏或其他问题而停止工作时&#xff0c;可以使…

java随机生成1到33数组,JAVA 生成随机数数组

一、JAVA获取随机数的方法//使用java.lang.Math类的random()方法double a Math.random();System.out.println("0.0-1.0的随机数&#xff1a;" a);double b Math.random()*100;System.out.println("0.0-100.0的随机数&#xff1a;" b);int c (int)(Mat…

线性筛法求素数

求素数是比较基本的内容&#xff0c;有时候我们会需要打一个素数表。一般如果n比较小我们会使用&#xff08;%2~sqrtn&#xff09;这种算法&#xff0c;简单但是时间耗费很多&#xff0c;复杂度是O(n^2)。这里介绍一种筛选求素数法&#xff0c;基本要点是&#xff0c;如果找到一…

硬件nat关闭还是开启_超能课堂(173):AfterBurner不止超频,还是绝佳的游戏伴侣...

微星AfterBurner软件可以说是一个相当好用的显卡工具&#xff0c;它好用的超频功能估计都不用我多说了吧&#xff1f;微星并没有把这款软件限制在自己品牌的显卡能用&#xff0c;各个品牌的显卡都能用&#xff0c;无论A卡还是N卡都可以用AfterBurner来超频&#xff0c;软件在超…

java dataset redis,利用Spring-Data-Redis和Jedis操作Redis缓存

概述 Jedis是redis官方推荐的用于访问Java客户端&#xff0c;在https://github.com/xetorthio/jedis下载最新的jedis。 访问redis 1、访问简单的key——value&#xff0c; pu只需简单几步&#xff0c;就可以利用Spring-Data-Redis和Jedis操作Redis缓存。步骤如下&…

javascript Array学习与使用

一&#xff0e;Javascript数组是无类型的&#xff1b;数组元素可以任意类型&#xff0c;并且同一个数组中的不同元素也可能有不同的类型&#xff0c;javascript数组是动态的&#xff0c;会根据需要增长或者缩减&#xff0c;每一个数组都有一个length属性。它不是只读的&#xf…

mx350显卡天梯图_CPU天梯图与显卡天梯图2020年最新版

最新CPU天梯图较之以往没有太大的变化&#xff0c;前十位置还是那几款。但是继阿里之后&#xff0c;腾讯也开始准备自己制作芯片了&#xff0c;毕竟自研AI芯片的诱惑还是很大的&#xff0c;2020年有不少的厂商都推出了新鲜美味的显卡&#xff0c;有些是老卡翻新做性价比。有的则…

matlab写字,Matlab实现鼠标写字代码

类型&#xff1a;编程工具大小&#xff1a;1.5M语言&#xff1a;中文 评分&#xff1a;1.2标签&#xff1a;立即下载最早的程序&#xff0c;实在忘了从哪里下载的了。能够实现鼠标的手写输入&#xff0c;但是一些不连续的点。tmouse.mfunction tmouse(action)% TMOUSE 本例展示…

[Linux]变量加减赋值以及将String转int

teddytoshiba~$ a"76"teddytoshiba~$ echo $((a3))79teddytoshiba~$ echo $((a-12))64teddytoshiba~$取文件名以及文件路径的脚本&#xff1a;#!/bin/shtmp$1filenameecho $1 | awk -F/ {print $(NF)}echo "filename":$filenamefilenamelengthecho | awk …

matlab在绘图时分数,第三章_Matlab图形绘制试卷.ppt

2、griddata函数&#xff0c;用来产生经插值后均匀间隔数据作图。常用的调用方法是&#xff1a;[XI,YI,ZI] griddata(x,y,z,XI,YI,’method’)&#xff0c;其中x,y,z来自关系式zf(x,y)&#xff0c;也可以是离散的数据点&#xff0c;ZI是有XI和YI插值后得到的对应点。其中metho…

from rfc 2068 hypertext怎么解决_你好,打工人!用英语怎么表达“打工人”?可别直接说 worker...

打工人&#xff0c;打工魂&#xff0c;打工人是人上人&#xff01;最近&#xff0c;「打工人」这个词火了&#xff01;几乎一夜之间&#xff0c;很多人在和朋友打招呼时&#xff0c;都自称“打工人”。那“打工人”是什么意思&#xff1f;这里的“打工人”&#xff0c;其实是对…

fbset

fbset用于读取和设置framebuffer的参数。# fbset mode "800x480-112"# D: 64.998 MHz, H: 58.034 kHz, V: 112.035 Hzgeometry 800 480 800 480 16timings 15385 220 40 21 7 60 10accel falsergba 5/11,6/5,5/0,0/0 endmode

mysql中更新的命令是,mysql命令总结(陆续更新中)

批量mysql 数据导入 load data local infile xx into table xx;连接数据库&#xff1a;mysql -h hostname -P port -u username -p -D databasename查看提供什么存储引擎&#xff1a;show engines;查看当前引擎&#xff1a;show variables like %storage_engine%;查看表使用了…

STM32连续采样_STM32 - 利用双缓冲实现实时曲线显示(续)

前言大概半个月之前捣鼓了下利用STM32实现实时曲线显示&#xff0c;中间又做了一点小改进和扩充&#xff0c;在这里更新一下&#xff1a;利用DMA进行缓冲区到LCD GRAM的像素数据搬运效果更好的曲线绘制策略代码可以在这里找到&#xff1a;<写得比较乱&#xff0c;望谅解( &a…

Vmware虚拟机三种网络模式详解

原文来自http://note.youdao.com/share/web/file.html?id236896997b6ffbaa8e0d92eacd13abbf&typenote 我怕链接会失效&#xff0c;故转载此篇文章。通过这篇文章&#xff0c;我对之前疑惑的地方有了直观的理解&#xff0c;很多地方并没有自己动手实践&#xff0c;所以这篇…

ros 双wan配置_基于ROS搭建简易软件框架实现ROV水下目标跟踪(九)--程序解析之PWM波下发...

模块对应cabin_controllers/serial_to_mcu。模块实现的功能为监听网络中PWM矩阵信息&#xff0c;将其转换成十六进制数据通过串口下发至MCU&#xff0c;实现对推进器电机的控制。模块数据的串口通信借助了ros的serial工具包&#xff08;sudo apt-get install ros-melodic-seria…

2018php项目实战视频教程,2018PHP实战技术VIP在线学习视频课程

课程目录&#xff1a;1-1 疯狂讲义之web简介2-1 从搭建PHP开发环境开始2-2 第一个PHP程序2-3 PHP变量相关知识2-4 PHP数据类型2-5 PHP数据类型之进制转换2-6 PHP数据类型之浮点型2-7 PHP数据类型系统函数简介3-1 PHP数据类型字符串的声明与定义3-2 数据类型之数组、资源、null类…

Struts1.x在MyEclipse中的环境搭建和配置

2019独角兽企业重金招聘Python工程师标准>>> &#xff08;一&#xff09; 先解压Struts-1.3.10-all.zip的文件夹Struts-1.3.10-all备用 -> 打开MyEclipse -> 新建一个 web project -> 在工程名上按右键鼠标选 Properties -> 弹出 Properties 面板 …