统计 iOS 设备锁定、解锁次数-b
今天下了个软件,可以记录手机解锁的次数和使用时间,当然啦,App 必须在后台运行着。当时比较纳闷的是有什么 API 可以接收设备解锁事件或通知的,Google 了下,还真有哎——我是链接:http://stackoverflow.com/questions/14229955/is-there-a-way-to-check-if-the-ios-device-is-locked-unlocked?noredirect=1&lq=1。
设备锁定的状态
由上面的回答可以知道,设备在锁定、解锁的时候,SpringBoard 都会发出通知,iPhoneDevWiki 这里:http://iphonedevwiki.net/index.php/SpringBoard.app/Notifications 能找到更多有趣的通知(注意:黄色标注的通知是有状态变量与之关联的,后面会用到)。贴订阅通知的代码:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), // 获取通知中心 NULL, // 设置观察者 deviceLockStatusChanged, // 接收到通知时的回调函数 CFSTR("com.apple.springboard.lockstate"), // 通知名 NULL, // 要观察的对象 CFNotificationSuspensionBehaviorDeliverImmediately // 决定应用在后台如何处理通知的标记 );
这里所用的通知中心并不是我们常用的 [NSNotificationCenter defalutCenter]
,而是 CFNotificationCenterRef
对象。提一下,即便前者的底层确实是由 CFNotificationCenter
实现的,但它们两者不是 Toll-Free Bridged。回到 CFNotificationCenterRef
,有下面三个函数获得不同的通知中心:
CFNotificationCenterGetLocalCenter(void);
CFNotificationCenterGetDistributedCenter(void);
CFNotificationCenterGetDarwinNotifyCenter(void);
第一个是我们熟悉的 Local Center,可以理解为通知的行为完全由本进程维护,作用域也仅在本进程;
第二个是 Distributed Center,如果有看到这个函数声明上的编译条件,你就会发现仅在桌面系统上才有 Distributed Center 可用。它可以实现两个进程之间的通信,感兴趣可以看看 Communicating With the Target Application:https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/PreferencePanes/Tasks/Communication.html ,似乎是通过 BundleID 实现对特定应用发送通知;
第三个是本文的重点,Darwin Center 的服务由系统的一个守护进程维护,相比 Local Center,通知的作用域扩大到了所有进程。这就为什么我们的应用能够接收到 SpringBoard.app 发送的通知。本文用的是用 CoreFoundation 的函数实现接收通知,除此之外,文档里还提到了利用 Mach Port, File Descriptors, Signal 等方法。查看 Darwin Notification Concepts:https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/MacOSXNotifcationOv/DarwinNotificationConcepts/DarwinNotificationConcepts.html#//apple_ref/doc/uid/TP40005947-CH5-SW1 了解更多。
接下来要讲讲回调函数了:
static void deviceLockStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){NSString *nameString = (__bridge NSString*)name;int token;
uint64_t state;
notify_register_check(nameString.UTF8String, &token);
notify_get_state(token, &state);
NSLog(@"%@: token: %d, state: %llu", nameString, token, state);if (state == 0) {
counter++;
}
notify_cancel(token);
}
函数的原型是直接抄文档的,notify_register_check()
可以生成一个 token 值用来关联某一个通知,接着用 notify_get_state()
就可以获得响应状态值。最后是 notify_cancel()
,它用来取消跟 token 相关联的通知和释放相应的资源,按 manual pages 的描述好像只针对利用 Mach Port 和 File Descriptors 接收消息时创建的资源。具体到这个回调函数,不太清楚底层做了什么,但我们能看到的是 token 被清零了。
后台运行
获得设备锁定、解锁的方法有了,接着是要让应用保存生命力,不能让它被挂起,否则就统计不了次数了。比较常见的方法就是循环播放一段空白的声音,然后在 Info.plist 里面添加相应的字段(KEY: UIBackgroundModes, VALUE: audio),或者直接在 Capabilities 里面的 Background Modes 中 Audio 的复选框中打个勾。
统计 iOS 设备锁定、解锁次数-b的更多相关文章
- 使用私有api统计ios app运行时间及次数
利用<iphone SprintBoard部分私有API总结>中提到的私有API,可以做很多越狱以前实现不了的事情. 比如,利用一个后台运行的app,监控该iphone上所有app的运行次 ...
- iOS设备的尺寸
iOS设备的尺寸有两种统计单位:像素和点,对于程序员来说,只需要记住点即可. 常见的iOS设备的尺寸(点) 分辨率(点) 设备 分辨率(像素) 320*480 4.4s 320*480(4) 640* ...
- 【转】iOS设备的UDID是什么?苹果为什么拒绝获取iOS设备UDID的应用?如何替代UDID?
本文讲诉的主要是为什么苹果2011年8月发布iOS 5后就开始拒绝App获取设备的UDID以及UDID替补方案,特别提醒开发者苹果App Store禁止访问UDID的应用上架(相关推荐:APP被苹果A ...
- iOS不越狱装收费App——注册iOS设备为开发者工具
额,这篇教程主要是我写下来用于总结注册iOS设备和用iResign安装App的过程,想要不越狱安装App当然有办法,但是有几个前提--你是一个Apple开发者,或者你有个朋友是App的开发者.如果没有 ...
- MSSQL 查询统计某状态出现的次数及累计时间
1.问题来源 最近客户需要统计某个设备,某状态,在某一个时间段内出现的次数,并计算累计出现的时间. 数据源如下: 现在如果要统计UPSCTSTA状态为D出现的次数(同一状态,连续出现的认为是一次),并 ...
- [转]iOS设备唯一标识探讨
转自:http://www.jianshu.com/p/b83b0240bd0e iOS设备唯一标识探讨 为了统计和检测应用的使用数据,几乎每家公司都有获取唯一标识的业务需求,在iOS5以前获取唯一标 ...
- PLSQL_统计信息系列04_统计信息的锁定和删除
20150506 Created By BaoXinjian
- iOS亮屏解锁命令【iOS自动化测试】--使用ssh
前提:iOS越狱手机一个 越狱方法:使用pp助手, 爱思助手等 1.从Cydia安装以下软件: AppSync for iOSx(可安装破解软件).afc2add补丁(可访问整个iOS设备的系统文件) ...
- 对IOS设备中UDID的一些思考
本文转载至 http://blog.csdn.net/happyrabbit456/article/details/11565209 http://blog.csdn.net/xiaoguan2008 ...
随机推荐
- c++中io流的使用
#include <strstream> #include <iostream.h> #include <string> using namespace std; ...
- svn管理代码在cornerstone上无法添加.a 静态库文件
有时候.a静态库不能上传到svn的服务器 导致别人拉代码运行不了 这是因为cornerstone设置里面默认不会提交.a文件, 在上图选项栏里是cornerstone默认忽略上传的文件名后缀,在这里 ...
- 关于Eclipse中的egit的常规使用和模板
修改bug的模板 要提交的comment信息.TDI-31426 fix bug: if get studio license use : Import License :after get lice ...
- SICP的一些练习题
1.3 较大两个数之和 (define (MaxSum x y z) (+ (cond ((or (> x y) (> x z)) x) ()) (cond ((or (> y x) ...
- fiddlercore 抓包获取cookie的方法
public partial class form1 : Form { public form1() { string cookies = ""; InitializeCompon ...
- C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)
介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...
- XML DOM操作,适用目前流行的浏览器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- ORM中去除反射,添加Expression
之前接触了别人的ORM框架,感觉牛掰到不行,然后试着自己来写自己的ORM. 最初从园子里找到其他人写的反射的例子: List<PropertyInfo> pis = typeof(T).G ...
- 从V$SQL_PLAN中FORMAT执行计划
10G版本 select sql_id from v$sqlarea where sql_text like'%xxx%'; select * from v$sql_plan where sql_i ...
- Css颜色定义的方法汇总color属性设置方式
颜色的定义方式用rgb()里面带上十进制的数字来定义. color:rgb(211,123,135); 用预定义的颜色名称. color:red; rgba()最后一个参数是不透明度. color:r ...