问题描述
我的 iOS 应用是否可以在用户每次访问主屏幕时自动重启?这是针对已越狱设备的 - 该应用程序并非用于 App Store.
一般来说,如果在应用外执行特定的用户操作,我如何让我的应用重新启动?
推荐答案
加速度计
如果您只想在遇到某些加速度计条件时让您的应用程序运行,您可以使用 Activator 来实现.Activator 是一个很棒的应用程序,由 Ryan Petrich 开发,可在 Cydia 上免费使用.它使您可以将设备配置为在执行特定用户操作时运行任何应用程序(或切换).这可能是按下主页按钮、按下电源/锁定按钮或加速度计抖动.
如果基本的 shake 不是您想要的,或者您正在构建一个应用程序来提供给许多用户,并且不希望他们必须自己设置 Activator,那么您可能需要自己写一些代码.
例如,您可以编写一个 启动守护程序,除了您的主 UI 应用程序之外, 并具有启动守护程序 监控加速度计.
当您检测到您感兴趣的特定运动类型时,您可以使用 open 命令启动您的 UI 应用程序.如果这只是供您自己使用,只需从 Cydia 下载 open 包.如果这是为了发布给其他人,请确保您的应用依赖于 open 以确保它已安装.例如,如果打包在 Debian .deb 包中,则 DEBIAN/control 文件可能包含以下内容:
Depends: open
确保安装您的应用的用户也将自动获得您的应用所需的 open.
解锁
您的另一个问题是在用户解锁手机时启动应用.同样,我会使用您的 Launch Daemon 来监听这种情况.在 iOS 5 上,我在解锁手机时看到此通知:
<块引用>截获通知:com.apple.springboard.lockstate
(我通过从命令行运行 notificationWatcher 实用程序检测到这一点,而 SSH 连接到我的手机.NotificationWatcher 也可从 Cydia 获得,作为 Erica Sadun 的 Erica Utilities 软件包的一部分)
所以,我想要你的启动守护进程 为 "com.apple.springboard.lockstate" 注册 Darwin 通知.像这样的:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center self, // observer: can be NULL if callback doesn't need self onLockStateChanged, // callback CFSTR("com.apple.springboard.lockstate"), // name NULL, // object CFNotificationSuspensionBehaviorDeliverImmediately);
回调函数在哪里:
static void onLockStateChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { // if you need access to member data (ivars): MyLaunchDaemon* this = (MyLaunchDaemon*)observer; //if (userInfo != nil) { // CFShow(userInfo); //} NSDictionary* info = (NSDictionary*)userInfo; // I'm not sure if the userInfo object has any useful // description for the lock state event if (/* unlocked */) { // force app to open, or resume from the background system("/usr/bin/open com.mycompany.MyAppName"); } }
当屏幕被锁定或解锁时,我会看到同样的通知,因此您可能需要让启动守护程序跟踪锁定/解锁状态,或者检查 userInfo 对象以查看是否告诉您这是锁定或解锁事件.我敢肯定还有其他方法.
更新:如果你想帮助解决屏幕锁定或解锁时是否出现通知,可以查看我的更新2 在另一个 SO 答案中.notify_get_state() 可用于确定事件是打开还是关闭事件.