今天下了个软件,可以记录手机解锁的次数和使用时间,当然啦,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. volley框架详解

    Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Uni ...

  2. Spring中BeanPostProcessor

    Spring中BeanPostProcessor 前言: 本文旨在介绍Spring动态配置数据源的方式,即对一个DataSource的配置诸如jdbcUrl,user,password,driverC ...

  3. 计算机程序和C++语言简介

    C++程序设计 第一章 计算机程序和C++语言简介 1.计算机是一台能够存储并处理数据的电子设备,包含硬件和软件两部分. 2.计算机硬件由: 1)中央处理单元(Central Processing U ...

  4. c语言面试题之sizeof

    c语言面试题之sizeof */--> c语言面试题之sizeof Table of Contents 1. sizeof 1 sizeof sizeof是c语言中判断数据类型或者表达式的长度符 ...

  5. 我的第一篇——nginx+naxsi总结篇1

    今天是我正式在Linux下安装nginx的第一天吧,搜索,查看,安装,这之间肯定是或多或少的遇到了很多的问题,不管是大的还是小的,都应该记录下来,或许以后还会用到,或许会帮到其他人. 首先,先说一下, ...

  6. JavaScript高级程序设计(第三版)学习笔记13、14章

    第13章,事件 事件冒泡 IE的事件叫做事件冒泡:由具体到不具体 <!DOCTYPE html> <html> <head>      <title>E ...

  7. OAuth2集成——《跟我学Shiro》

    http://jinnianshilongnian.iteye.com/blog/2038646 目前很多开放平台如新浪微博开放平台都在使用提供开放API接口供开发者使用,随之带来了第三方应用要到开放 ...

  8. VMware下LINUX的虚拟机增加磁盘空间

    先关闭虚拟机电源,做如下设置:“ 虚拟机”--“虚拟机设置”--“磁盘”--“扩展” 可以随意添加你需要增到到的磁盘大小(如15Gb,表示磁盘总量,包含原来的磁盘容量); 再重启电源进入系统做如下步骤 ...

  9. Oracle连接配置以及实例的备份和恢复

    背景:一个团队项目开发,不可能每个人都架设自己本地的数据库,大多数情况下是统一用服务器上的数据库,这时候就需要进行远程数据库的连接.而且有时候还需要进行数据库搬迁 ,这时候就需要进行数据库的备份和恢复 ...

  10. 电脑中java环境的搭建