如何检测手机何时被放下

Posted

技术标签:

【中文标题】如何检测手机何时被放下【英文标题】:How to detect when the phone has been put down 【发布时间】:2013-05-29 11:13:03 【问题描述】:

我想在手机静止 2 秒后执行一项操作。我已经搜索了谷歌和堆栈溢出的年龄。我发现“Accelerometer DidAccelerate”已经贬值,CoreMotion 是替代品。我所看到的一切都与“摇晃”运动有关。我试过阅读苹果的文档,但这让我很困惑!

基本上,我希望应用程序检测到手机上的重力在一定时间内保持在一个很小的范围内(表明手机已经放在桌子或其他东西上),并让它调用并实例化或让应用执行某些操作。

任何帮助将不胜感激。

【问题讨论】:

apple docs中有示例代码 【参考方案1】:

类似于Simple iPhone motion detect 中描述的问题。 CMMotionManager 的基本设置在 Apple 文档中进行了描述,例如 Mike Pollard 在他的评论中所述。我特别推荐Handling Processed Device Motion Data 部分。

然后你需要的是CMDeviceMotion.userAcceleration,它包含没有重力的纯加速度。

CMMotionManager *motionManager = [[CMMotionManager alloc] init];
// UPDATE: set interval to 0.02 sec
motionManager.deviceMotionUpdateInterval = 1.0 / 50.0;
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] 
        withHandler:^(CMDeviceMotion *deviceMotion, NSError *error) 
    CMAcceleration userAcceleration = deviceMotion.userAcceleration;
    double totalAcceleration = sqrt(userAcceleration.x * userAcceleration.x + 
        userAcceleration.y * userAcceleration.y + userAcceleration.z * userAcceleration.z);
    // UPDATE: print debug information
    NSLog (@"total=%f x=%f y=%f z=%f", totalAcceleration, userAcceleration.x, userAcceleration.y, userAcceleration.z);
    // if(totalAcceleration < SOME_LIMIT) ...

然后像 codeplasma 描述的那样继续in his answer above。

另外请注意,如果在地下、公共汽车等中使用,由于外部加速度,该解决方案可能不精确。

【讨论】:

感谢您的帮助,但我遇到了问题(一如既往)。我没有收到任何错误,但它根本不起作用。我告诉它执行的操作,没有执行。我尝试将 SOME_LIMIT 设为 100,但无济于事。你会建议我做什么?我可能忘记或做错了什么? 确保处理程序被调用:一些 NSLog 语句,只是为了安全起见。 totalAcceleration 的平均值应为 1(以 g 为单位)。所以打印出accelerometerData.accelerationtotalAcceleration 来查看值。告诉我,但现在是欧洲的夜晚,所以我们明天可能会看到 :-) 早上好 :) 我该怎么做?我只熟悉简单的NSLog(@"test") 之类的东西(我试过NSLog(@"%f", totalAcceleration),但我认为它不正确,它抱怨“使用未声明的标识符”)。无论如何,我尝试将NSLog(@"test") 放入//do something(在codeplasma 的代码中)位(在codeplasma 的代码中),但控制台中没有任何显示,但是当我将它放在ViewDidLoad 之类的地方时它确实出现了。 s。更新答案:间隔和NSLog,我用// UPDATE: ...标记了更改 我尝试了代码但仍然没有。我在[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *deviceMotion, NSError *error) 之后放置的任何 NSLog 都不会出现。我已经添加了 CoreMotion 框架,除此之外我还需要做什么吗?【参考方案2】:

你可以这样做:

CMMotionManager *mManager = [[CMMotionManager alloc] init];

if ([mManager isAccelerometerAvailable] == YES) 
    __block float lastActivityBefore = 0.0;
    [mManager setAccelerometerUpdateInterval:0.1];
    [mManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) 

        double totalAcceleration = sqrt(accelerometerData.acceleration.x * accelerometerData.acceleration.x + accelerometerData.acceleration.y * accelerometerData.acceleration.y + accelerometerData.acceleration.z * accelerometerData.acceleration.z);
        if(totalAcceleration < SOME_LIMIT)
            lastActivityBefore = lastActivityBefore + 0.1;
        else
            lastActivityBefore = 0.0;

        if(lastActivityBefore >= 2.0)
        
            //do something
        
    ];

即使您的设备稳定,加速度计也会显示一些最小加速度,因此您应该进行测试以确定 SOME_LIMIT 值。

另外请注意,您的应用中应该只有一个实例 CMMotionManager 类,因此您最好将它放在您的 AppDelegate 中并只初始化一次。

【讨论】:

这行不通,因为accelerometerData.acceleration 包含重力 感谢 codeplasma 的帮助。通过一些调整,它工作得非常出色。另一个赞成票 谁能告诉我 SOME_LIMIT 的值?

以上是关于如何检测手机何时被放下的主要内容,如果未能解决你的问题,请参考以下文章

检测 Android 手机中的 GPS 开/关开关

让孩子放下iPad放下手机的秘密武器!| 象妈分享会

手机浏览器如何防止被检测到设备信息

北斗卫星是如何实现手机定位的?

检测应用程序何时最小化(iOS)

检测安卓手机是不是连接到局域网