5

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

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

任何帮助将不胜感激。

4

2 回答 2

4

你可以这样做:

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 并仅初始化一次。

于 2013-05-29T12:31:15.727 回答
4

它类似于Simple iPhone motion detection中描述的问题。基本设置CMMotionManager在 Apple 文档中进行了描述,例如 Mike Pollard 在他的评论中所述。我特别推荐处理已处理的设备运动数据部分。

然后你需要的是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在他上面的回答中描述的那样继续。

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

于 2013-05-29T14:27:34.390 回答