今天下了个软件,可以记录手机解锁的次数和使用时间,当然啦,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,有下面三个函数获得不同的通知中心:

  1. CFNotificationCenterGetLocalCenter(void);

  2. CFNotificationCenterGetDistributedCenter(void);

  3. 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的更多相关文章

  1. 使用私有api统计ios app运行时间及次数

    利用<iphone SprintBoard部分私有API总结>中提到的私有API,可以做很多越狱以前实现不了的事情. 比如,利用一个后台运行的app,监控该iphone上所有app的运行次 ...

  2. iOS设备的尺寸

    iOS设备的尺寸有两种统计单位:像素和点,对于程序员来说,只需要记住点即可. 常见的iOS设备的尺寸(点) 分辨率(点) 设备 分辨率(像素) 320*480 4.4s 320*480(4) 640* ...

  3. 【转】iOS设备的UDID是什么?苹果为什么拒绝获取iOS设备UDID的应用?如何替代UDID?

    本文讲诉的主要是为什么苹果2011年8月发布iOS 5后就开始拒绝App获取设备的UDID以及UDID替补方案,特别提醒开发者苹果App Store禁止访问UDID的应用上架(相关推荐:APP被苹果A ...

  4. iOS不越狱装收费App——注册iOS设备为开发者工具

    额,这篇教程主要是我写下来用于总结注册iOS设备和用iResign安装App的过程,想要不越狱安装App当然有办法,但是有几个前提--你是一个Apple开发者,或者你有个朋友是App的开发者.如果没有 ...

  5. MSSQL 查询统计某状态出现的次数及累计时间

    1.问题来源 最近客户需要统计某个设备,某状态,在某一个时间段内出现的次数,并计算累计出现的时间. 数据源如下: 现在如果要统计UPSCTSTA状态为D出现的次数(同一状态,连续出现的认为是一次),并 ...

  6. [转]iOS设备唯一标识探讨

    转自:http://www.jianshu.com/p/b83b0240bd0e iOS设备唯一标识探讨 为了统计和检测应用的使用数据,几乎每家公司都有获取唯一标识的业务需求,在iOS5以前获取唯一标 ...

  7. PLSQL_统计信息系列04_统计信息的锁定和删除

    20150506 Created By BaoXinjian

  8. iOS亮屏解锁命令【iOS自动化测试】--使用ssh

    前提:iOS越狱手机一个 越狱方法:使用pp助手, 爱思助手等 1.从Cydia安装以下软件: AppSync for iOSx(可安装破解软件).afc2add补丁(可访问整个iOS设备的系统文件) ...

  9. 对IOS设备中UDID的一些思考

    本文转载至 http://blog.csdn.net/happyrabbit456/article/details/11565209 http://blog.csdn.net/xiaoguan2008 ...

随机推荐

  1. Android界面刷新

    Android的invalidate与postInvalidate都是用来刷新界面的,用法区别在于: 1)invalidate():实例化一个Handler对象,并重写handleMessage方法调 ...

  2. Intent的介绍

    一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作 的动作.动作涉及数据.附加数据进行描 ...

  3. 使用webView制作浏览器

    xml文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...

  4. Java并发编程专题

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4852149. ...

  5. PHP之ThinkPHP模板标签操作

    Action    : $User=M("user");     $list=$User->select();     $this->assign("list ...

  6. 关于JFace中的对话框MessageDialog类等其它类型对话框

    对话框是软件系统中最常用到的界面,对话框无处不在,从界面结构来说,对话框主要是由主体的界面组件和底部窗体按钮组成. 之前的例子中已经频繁的使用到了MessageDialog.openInformati ...

  7. 关于常用的git命令列表

    我博客园中所写的git内容几乎都是看的蒋鑫老师的<git权威指南>这本书实在太好了. 常用的Git命令. git add  添加到暂存区 git add interactive  交互式添 ...

  8. EL表达式简单应用

    <%@page import="java.util.HashMap"%> <%@page import="java.util.List"%&g ...

  9. PHP之文件的锁定、上传与下载

    小结文件的锁定机制.上传和下载 1.文件锁定 现在都在讲究什么分布式.并发等,实际上文件的操作也是并发的,在网络环境下,多个用户在同一时刻访问页面,对同一服务器上的同一文件进行着读取,如果,这个用户刚 ...

  10. sparkSQL1.1入门

    http://blog.csdn.net/book_mmicky/article/details/39288715 2014年9月11日,Spark1.1.0忽然之间发布.笔者立即下载.编译.部署了S ...